Question

Je lis des fichiers dans divers formats et langues et j'utilise actuellement une petite bibliothèque de codage pour tenter de détecter le codage approprié ( http://www.codeproject.com/KB/recipes/DetectEncoding.aspx ).

C'est assez bon, mais il manque encore parfois. (Fichiers multilingues)

La plupart de mes utilisateurs potentiels comprennent très peu le codage (le mieux que je puisse espérer est & "; cela a quelque chose à voir avec les caractères &";) et il est très peu probable que vous puissiez choisir le encodage à droite dans une liste, je voudrais donc les laisser parcourir différents encodages jusqu’à trouver celui de droite en cliquant simplement sur un bouton.

Problèmes d'affichage? Cliquez ici pour essayer un autre encodage! (C'est le concept quand même)

Quel serait le meilleur moyen de mettre en œuvre quelque chose comme ça?

Edit: On dirait que je ne me suis pas exprimé assez clairement. En & Quot; parcourant l'encodage & Quot ;, je ne veux pas dire & Quot; comment parcourir les encodages? & Quot;

Ce que je voulais dire était & "comment laisser l'utilisateur essayer différents encodages en séquence sans recharger le fichier? &";

L’idée est plutôt la suivante: supposons que le fichier soit chargé avec le mauvais codage. Certains caractères étranges sont affichés. L'utilisateur cliquerait sur un bouton & Quot; Encodage suivant & Quot; ou " encodage précédent " ;, et la chaîne serait convertie en un encodage différent. Il suffit à l'utilisateur de continuer à cliquer jusqu'à ce que le bon encodage soit trouvé. (quel que soit l'encodage qui semble bon pour l'utilisateur, tout ira bien). Tant que l'utilisateur peut cliquer sur & "Suivant &", Il a une chance raisonnable de résoudre son problème.

Ce que j'ai trouvé jusqu'à présent implique la conversion de la chaîne en octets en utilisant l'encodage actuel, puis la conversion d'octets en encodage suivant, la conversion de ces octets en caractères, puis la conversion du caractère en chaîne ... Doable, mais je me demande bien. s'il n'y a pas de moyen plus facile de le faire.

Par exemple, s'il existait une méthode qui lirait une chaîne et la renverrait en utilisant un encodage différent, quelque chose comme & "; render (chaîne, encodage) &";

. "

Merci beaucoup pour les réponses!

Était-ce utile?

La solution

Lisez le fichier sous forme d'octets et utilisez ensuite la méthode 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));

Vous devez donc charger le fichier une seule fois. Vous pouvez utiliser chaque encodage en fonction des octets d'origine du fichier. L’utilisateur peut sélectionner celui qui convient et utiliser le résultat de Encoding.GetEncoding (...). GetString (data) pour un traitement ultérieur.

Autres conseils

(réponse originale supprimée après la mise à jour de la question)

  

Par exemple, s'il y avait une méthode   qui lirait une chaîne et la renverrait   en utilisant un encodage différent, quelque chose   comme " render (chaîne, encodage) ".

Je ne pense pas que vous puissiez réutiliser les données de chaîne. Le fait est que si l'encodage était incorrect, cette chaîne peut être considérée comme corrompue. Il peut très facilement contenir du charabia parmi les personnages à la recherche probable. En particulier, de nombreux encodages peuvent pardonner la présence / l'absence d'une nomenclature / d'un préambule, mais voudriez-vous ré-encoder avec? sans elle?

Si vous êtes prêt à prendre le risque (je ne le serais pas), vous pouvez simplement ré-encoder votre chaîne locale avec le dernier encodage:

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

En réalité, je pense que le mieux que vous puissiez faire est de conserver l'original byte[]. Continuez à offrir des rendus différents (via des codages différents) jusqu'à ce qu'ils vous plaisent. Quelque chose comme:

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

Pouvez-vous laisser l'utilisateur entrer des mots (avec des caractères & "spéciaux &";) censés figurer dans le fichier?

Vous pouvez rechercher vous-même tous les encodages pour voir si ces mots sont présents.

Faites attention au Bogue du bloc-notes '. Quoi que vous essayiez, cela va vous piquer ... Vous pouvez en trouver bonnes discussions sur les encodages et leurs problèmes sur MSDN (et d’autres endroits).

Vous devez conserver les données d'origine sous forme de tableau d'octets ou de MemoryStream que vous pouvez ensuite convertir en un nouvel encodage. Une fois que vous avez déjà converti vos données en chaîne, vous ne pouvez plus revenir à la représentation d'origine.

Que diriez-vous de quelque chose comme ça:

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

Utilisez Load File lors de votre premier essai. utilisez ensuite Try Encoding par la suite.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top