Frage

Ich bin Dateien in verschiedenen Formaten und Sprachen zu lesen und ich bin zur Zeit eine kleine Codierung Bibliothek Versuch, nehmen Sie die richtige Codierung ( http://www.codeproject.com/KB/recipes/DetectEncoding.aspx ).

Es ist ziemlich gut, aber es fehlt immer noch gelegentlich. (Multilingual Dateien)

Die meisten meiner potentiellen Nutzer haben sehr wenig Verständnis für Codierung (das Beste, was ich hoffen kann, ist „es hat etwas mit Zeichen zu tun“) und ist sehr unwahrscheinlich zu können, wählen Sie die richtige Codierung in einer Liste, so dass ich möchte sie durchlaufen verschiedene Kodierungen lassen, bis die richtige durch klicken auf eine Schaltfläche nur zu finden ist.

Anzeigeprobleme? Hier klicken, um eine andere Codierung zu versuchen! (Nun, das ist das Konzept sowieso)

Was wäre der beste Weg, so etwas zu implementieren?


Edit: Sieht aus wie ich nicht ausdrücken habe mich klar genug. Mit „Radtouren durch die Codierung“, meine ich nicht „wie eine Schleife durch Kodierungen?“

Was ich meinte war „wie der Benutzer zu lassen, verschiedene Kodierungen nacheinander versuchen, ohne die Datei neu zu laden?“

Die Idee ist mehr wie folgt aus: Lassen Sie uns sagen, dass die Datei mit der falschen Codierung geladen wird. Einige seltsame Zeichen angezeigt. Der Benutzer auf eine Schaltfläche klicken „Next-Codierung“ oder „vorherige Codierung“ und die Zeichenfolge würde in einer anderen Kodierung umgewandelt werden. Der Benutzer muss nur Klick halten, bis die richtige Codierung zu finden ist. (Was auch immer Codierung sieht gut aus für den Benutzer tun gut). Solange kann der Benutzer auf „Weiter“ klicken, er hat eine gute Chance, sein Problem zu lösen.

Was ich bisher beinhaltet Umwandlung der Zeichenfolge in Bytes, die die aktuelle Codierung verwenden, dann Umwandeln der Bytes auf die nächste Codierung, Konvertieren diese Bytes in Zeichen gefunden, dann die Zeichen in einen String konvertieren ... Doable, aber ich frage mich, wenn es nicht ein einfacherer Weg, das zu tun.

Zum Beispiel, wenn es eine Methode war, die einen String lesen würde und sendet es eine andere Kodierung verwendet wird, so etwas wie „macht (string, Codierung)“.


Vielen Dank für die Antworten!

War es hilfreich?

Lösung

Lesen Sie die Datei als Byte und verwenden dann die Encoding.GetString Methode.

        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));

So können Sie die Datei nur einmal zu laden haben. Sie können jede Codierung auf dem ursprünglichen Bytes der Datei basiert. Der Benutzer kann die richtigen wählen und können Sie das Ergebnis von Encoding.GetEncoding (...) verwenden. GetString (Daten) zur weiteren Verarbeitung.

Andere Tipps

(entfernt ursprüngliche Antwort folgende Frage Update)

  

Zum Beispiel, wenn es eine Methode   das würde einen String lesen und senden Sie es   mit einer anderen Kodierung, etwas   wie "machen (string, Codierung)".

Ich glaube nicht, können Sie die String-Daten wiederverwenden. Die Tatsache ist: Wenn die Codierung falsch ist, kann diese Zeichenfolge korrupt angesehen werden. Es kann sehr leicht Kauderwelsch unter den wahrscheinlich aussehenden Zeichen enthält. viele Codierungen können auf das Vorhandensein / Nichtvorhandensein einer BOM / Präambel, vergib Insbesondere, aber würden Sie neu kodieren mit ihm? ohne es?

Wenn Sie sind glücklich, es zu riskieren (ich würde nicht sein), können Sie einfach neu kodieren Ihre lokale Zeichenfolge mit der letzten Codierung:

// 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);

In Wirklichkeit glaube ich, das Beste, was Sie tun können, ist die ursprüngliche byte[] zu halten - halten unterschiedliche Darstellungen bieten (über verschiedene Kodierungen), bis sie einen mögen. So etwas wie:

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();
                }
            }
        };
    }
}

Könnten Sie den Benutzer lassen einige Worte eingeben (mit „speziellen“ Zeichen), die in der Datei auftreten sollen?

Sie können alle Codierungen suchen, sich zu sehen, ob diese Worte vorhanden sind.

Vorsicht vor dem berüchtigten ' Notepad Bug '. Es wird Sie beißen, was Sie versuchen, aber ... Sie können einige gute Gespräche über Kodierungen und ihre Herausforderungen auf MSDN (und anderen Orten).

Sie haben die Originaldaten als Byte-Array zu halten oder Memory Sie können dann auf die neue Codierung übersetzen, wenn Sie bereits Ihre Daten in eine Zeichenfolge konvertiert man nicht zuverlässig auf die ursprüngliche Darstellung zurückkehren kann.

Wie wäre es etwa so:

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);
}

Mit Loadfile auf Ihrem ersten Versuch; verwenden TryEncoding dann anschließend.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top