我读文件在各种不同的格式和语言和我目前正在使用一个小小的编码的图书馆采取的尝试,以检测正确的编码(http://www.codeproject.com/KB/recipes/DetectEncoding.aspx).

这是很好的,但它仍然错过偶尔。(多种语言的文件)

我大部分的潜在用户有很少了解的编码(最好的,我可以希望是"它有什么用的字符"),是非常不太可能有能力选择正确的编码清单,因此我想让他们的周期通过不同的编码,直至正确的是发现只需按一个按钮。

显示器的问题?按这里尝试一种不同的编码!(那么这一概念无论如何)

什么是最好的方式来实施类似的东西吗?


编辑:看起来像我没有表达自己显然不够。通过"骑自行车穿过编码",我的意思不是"如何通过环编码?"

我的意思是"如何让用户的尝试不同的编码列无需重新加载的文件?"

这个想法是更多这样的:让我们说该文件载有错误的编码。一些奇怪的字显示。用户将按一下按钮"下编码"或"前编码",并串将被转换成在一个不同的编码。用户只需要保持点击,直到正确的编码。(无论编码看起来不错对用户将做优良)。只要的用户可以点击"下一步",他有一个合理的机会解决他的问题。

我们发现迄今为止涉及到转换串字节使用的前编码,然后转换字节的下一个编码、转换的那些字节到的字符,然后将char成一串...可行的,但是我想知道如果没有一个更简单的方式做到这一点。

例如,如果有一个方法,将宣读一个字符串并返回其使用不同的编码,就像"渲染(string,编码)".


谢谢你的答案!

有帮助吗?

解决方案

读取文件作为字节,然后使用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));

所以,你必须只加载一次文件。您可以使用基于文件的原始字节每个编码。用户可以选择正确的一个UND可以使用Encoding.GetEncoding(...)的结果。GetString的(数据)以供进一步处理。

其他提示

(以下问题更新除去原来的答案)

  

举例来说,如果有一个方法   会读一个字符串,并将其返回   使用不同的编码,东西   像 “呈现(字符串,编码)”。

我不认为你可以重新使用的字符串数据。事实是:如果编码是错误的,这个字符串可以被视为腐败。它可以很容易地包含可能寻找字符中乱码。特别是,许多编码可以原谅的存在/不存在一个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(和其他地方)的挑战。

您必须保留原来的数据作为字节数组或MemoryStream的你就可以转化为新的编码,一旦您已经转换您的数据为字符串,你不能可靠地恢复到原来的表示。

如何是这样的:

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

使用的LoadFile第一次尝试;然后使用TryEncoding随后

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top