문제

다양한 형식과 언어로 파일을 읽고 있으며 현재 적절한 인코딩을 감지하기 위해 작은 인코딩 라이브러리를 사용하고 있습니다 (http://www.codeproject.com/kb/recipes/detectencoding.aspx).

꽤 좋지만 여전히 가끔 그리워합니다. (다국어 파일)

내 잠재적 인 사용자의 대부분은 인코딩에 대한 이해가 거의 없으며 (내가 기대할 수있는 최선은 "캐릭터와 관련이 있다는 것입니다") 목록에서 올바른 인코딩을 선택할 수는 없으므로 원합니다. 버튼을 클릭하여 오른쪽 인코딩을 찾을 때까지 다른 인코딩을 순환하게하십시오.

표시 문제? 다른 인코딩을 시도하려면 여기를 클릭하십시오! (어쨌든 그게 개념입니다)

그런 것을 구현하는 가장 좋은 방법은 무엇입니까?


편집 : 내가 자신을 충분히 명확하게 표현하지 않은 것 같습니다. "인코딩을 통과하는 사이클링"이라는 말은 "인코딩을 통과하는 방법"을 의미하지 않습니다.

내가 의미하는 바는 "사용자가 파일을 다시로드하지 않고 순서대로 다른 인코딩을 시도하는 방법"이었습니다.

아이디어는 다음과 같습니다. 파일에 잘못된 인코딩이로드되었다고 가정 해 봅시다. 이상한 문자가 표시됩니다. 사용자는 "다음 인코딩"또는 "이전 인코딩"버튼을 클릭하고 문자열은 다른 인코딩에서 변환됩니다. 사용자는 오른쪽 인코딩이 발견 될 때까지 계속 클릭하면됩니다. (인코딩이 무엇이든 사용자에게 잘 보이는 것은 괜찮을 것입니다). 사용자가 "다음"을 클릭 할 수있는 한, 그는 자신의 문제를 해결할 수있는 합리적인 기회가 있습니다.

지금까지 찾은 것은 전류 인코딩을 사용하여 문자열을 바이트로 변환 한 다음 바이트를 다음 인코딩으로 변환하고 해당 바이트를 숯으로 변환 한 다음 숯을 문자열로 변환하는 것과 관련이 있지만 ... '더 쉬운 방법입니다.

예를 들어, 문자열을 읽고 다른 인코딩을 사용하여 문자열을 읽는 메소드가있는 경우 "Render (String, Encoding)"와 같은 것입니다.


답변 해 주셔서 감사합니다!

도움이 되었습니까?

해결책

파일을 바이트로 읽은 다음 encoding.getString 메소드를 사용합니다.

        byte[] data = System.IO.File.ReadAllBytes(path);

        Console.WriteLine(Encoding.UTF8.GetString(data));
        Console.WriteLine(Encoding.UTF7.GetString(data));
        Console.WriteLine(Encoding.ASCII.GetString(data));

따라서 파일을 한 번만로드해야합니다. 파일의 원래 바이트를 기반으로 모든 인코딩을 사용할 수 있습니다. 사용자는 추가 처리를 위해 Encoding.getEncoding (...). GetString (데이터)의 결과를 사용할 수있는 올바른 것을 선택할 수 있습니다.

다른 팁

(질문 업데이트 후 원래 답변 제거)

예를 들어, 문자열을 읽고 다른 인코딩을 사용하여 문자열을 읽는 메소드가있는 경우 "Render (String, Encoding)"와 같은 것입니다.

문자열 데이터를 재사용 할 수 있다고 생각하지 않습니다. 사실 : 인코딩이 잘못되면이 문자열은 손상된 것으로 간주 될 수 있습니다. 가능성이 높은 캐릭터 중에는 횡설수설을 매우 쉽게 포함 할 수 있습니다. 특히, 많은 인코딩이 BOM/서문의 존재 또는 부재를 용서할 수 있지만, 그것으로 다시 인코딩 하시겠습니까? 이것없이?

당신이 그것을 위험에 빠뜨릴 수 있다면 (나는 그렇지 않을 것입니다), 당신은 마지막 인코딩으로 로컬 문자열을 다시 인센트 할 수 있습니다.

// I DON'T RECOMMEND THIS!!!!
byte[] preamble = lastEncoding.GetPreamble(),
    content = lastEncoding.GetBytes(text);
byte[] raw = new byte[preamble.Length + content.Length];
Buffer.BlockCopy(preamble, 0, raw, 0, preamble.Length);
Buffer.BlockCopy(content, 0, raw, preamble.Length, content.Length);
text = nextEncoding.GetString(raw);

실제로, 나는 당신이 할 수있는 최선은 원본을 유지하는 것입니다. byte[] - 다른 인코딩을 통해 다른 렌더링을 좋아할 때까지 다른 렌더링을 계속 제공하십시오. 같은 것 :

using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
class MyForm : Form {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.Run(new MyForm());
    }
    ComboBox encodings;
    TextBox view;
    Button load, next;
    byte[] data = null;

    void ShowData() {
        if (data != null && encodings.SelectedIndex >= 0) {
            try {
                Encoding enc = Encoding.GetEncoding(
                    (string)encodings.SelectedValue);
                view.Text = enc.GetString(data);
            } catch (Exception ex) {
                view.Text = ex.ToString();
            }
        }
    }
    public MyForm() {
        load = new Button();
        load.Text = "Open...";
        load.Dock = DockStyle.Bottom;
        Controls.Add(load);

        next = new Button();
        next.Text = "Next...";
        next.Dock = DockStyle.Bottom;
        Controls.Add(next);

        view = new TextBox();
        view.ReadOnly = true;
        view.Dock = DockStyle.Fill;
        view.Multiline = true;
        Controls.Add(view);

        encodings = new ComboBox();
        encodings.Dock = DockStyle.Bottom;
        encodings.DropDownStyle = ComboBoxStyle.DropDown;
        encodings.DataSource = Encoding.GetEncodings();
        encodings.DisplayMember = "DisplayName";
        encodings.ValueMember = "Name";
        Controls.Add(encodings);

        next.Click += delegate { encodings.SelectedIndex++; };

        encodings.SelectedValueChanged += delegate { ShowData(); };

        load.Click += delegate {
            using (OpenFileDialog dlg = new OpenFileDialog()) {
                if (dlg.ShowDialog(this)==DialogResult.OK) {
                    data = File.ReadAllBytes(dlg.FileName);
                    Text = dlg.FileName;
                    ShowData();
                }
            }
        };
    }
}

사용자가 파일에서 발생 해야하는 단어 ( "특별한"문자 포함)를 입력 할 수 있습니까?

모든 인코딩을 직접 검색 하여이 단어가 있는지 확인할 수 있습니다.

악명 높은 사람을 조심하십시오 '메모장 버그'. 그래도 당신이 시도하는 모든 것을 물게 될 것입니다 ... 당신은 몇 가지를 찾을 수 있습니다 좋은 토론 MSDN (및 기타 장소)에 대한 인코딩 및 도전에 대해.

원래 데이터를 바이트 배열 또는 메모리 스트림으로 유지해야합니다. 그런 다음 이미 데이터를 문자열로 변환 한 후에는 원래 표현으로 안정적으로 돌아갈 수 없습니다.

이와 같은 것은 어떻습니까 :

public string LoadFile(string path)
{
    stream = GetMemoryStream(path);     
    string output = TryEncoding(Encoding.UTF8);
}

public string TryEncoding(Encoding e)
{
    stream.Seek(0, SeekOrigin.Begin) 
    StreamReader reader = new StreamReader(stream, e);
    return reader.ReadToEnd();
}

private MemoryStream stream = null;

private MemorySteam GetMemoryStream(string path)
{
    byte[] buffer = System.IO.File.ReadAllBytes(path);
    return new MemoryStream(buffer);
}

첫 번째 시도에서로드 파일을 사용하십시오. 그런 다음 TryenCoding을 사용하여 사용하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top