在C#中将ANSI(Windows 1252)转换为UTF8

GPX*_*GPX 4 .net c# string character-encoding special-characters

之前我已经在Stack Overflow上以循环方式询问了这个问题,并希望这次能够做到正确.如何将ANSI(代码页1252)转换为UTF-8,同时保留特殊字符?(我知道UTF-8支持比ANSI更大的字符集,但是如果我可以保留ANSI支持的所有UTF-8字符并用其他?东西替换其余的字符集就可以了)

为什么我要转换ANSI→UTF-8

我基本上编写的程序将vCard文件(VCF)拆分为单个文件,每个文件包含一个联系人.我注意到诺基亚和索尼爱立信手机以UTF-8(无BOM)保存备份VCF文件,但Android将其保存为ANSI(1252).上帝知道其他手机以什么格式保存它们!

所以我的问题是

  1. vCard文件的字符编码是否有行业标准?
  2. 哪个更容易解决我的问题?将ANSI转换为UTF8(和/或反过来)或尝试检测输入文件具有哪种编码并通知用户有关它?

tl; dr 需要知道如何将字符编码从(ANSI/UTF8)转换为(UTF8/ANSI),同时保留所有特殊字符.

Guf*_*ffa 13

您不应该从一种编码转换为另一种编码.您必须使用创建的编码来读取每个文件,否则您将丢失信息.

一旦您使用正确的编码读取文件,您将内容作为Unicode字符串,从那里您可以使用您喜欢的任何编码保存它.

如果需要检测编码,可以将文件作为字节读取,然后查找特定于任一编码的字符代码.如果文件不包含特殊字符,则编码将起作用,因为两种编码的字符32..127相同.


Han*_*ant 8

VCF 按照第3.4章中的规范要求以utf-8编码.你需要认真对待这个问题,如果不是一成不变的话格式就完全没用了.如果您看到一些Android应用程序修改重音字符,那么假设这是该应用程序中的错误.或者更可能的是,它从其他地方得到了不好的信息.您尝试更正编码会导致更多问题,因为您的卡版本将永远不会与原始版本匹配.

您可以使用Encoding.GetEncoding(1252).GetString()从1252转换为utf-8,并传入一个byte [].永远不要尝试编写代码读取一个字符串,并将其变成敲敲罢了一个byte [],这样就可以使用转换方法,只是使编码问题很多糟糕.换句话说,您需要使用FileStream而不是StreamReader读取文件.但同样,避免解决其他人的问题.


dju*_*nod 8

这是我在C#中使用的(我一直用它来从Windows-1252转换为UTF8)

    public static String readFileAsUtf8(string fileName)
    {
        Encoding encoding = Encoding.Default;
        String original = String.Empty;

        using (StreamReader sr = new StreamReader(fileName, Encoding.Default))
        {
            original = sr.ReadToEnd();
            encoding = sr.CurrentEncoding;
            sr.Close();
        }

        if (encoding == Encoding.UTF8)
            return original;

        byte[] encBytes = encoding.GetBytes(original);
        byte[] utf8Bytes = Encoding.Convert(encoding, Encoding.UTF8, encBytes);
        return Encoding.UTF8.GetString(utf8Bytes);
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

我是这样做的:

    private static void ConvertAnsiToUTF8(string inputFilePath, string outputFilePath)
    {
        string fileContent = File.ReadAllText(inputFilePath, Encoding.Default);
        File.WriteAllText(outputFilePath, fileContent, Encoding.UTF8);
    }
Run Code Online (Sandbox Code Playgroud)