C# &引用É&引用;无法正确转换为两个字节
除此之外,我还有一个补充问题 我发现一首歌的标题是“É” 我的代码:C# &引用É&引用;无法正确转换为两个字节,c#,unicode,fonts,C#,Unicode,Fonts,除此之外,我还有一个补充问题 我发现一首歌的标题是“É” 我的代码: var playList = new StreamWriter(playlist, false, Encoding.UTF8); - 将其转换为以下字节: 195 137 输出为Ã后跟一个正方形(这是一个无法以当前字体打印的字符) 我已经将同一个文件导出到Media Monkey中的播放列表中,它将“Ô写为“É”——我假设这是正确的(正如KennyTM指出的) 我的问题是,如何获得“‰”符号输出?我需要选择不同的字体吗
var playList = new StreamWriter(playlist, false, Encoding.UTF8);
-
将其转换为以下字节:
195
137
输出为Ã后跟一个正方形(这是一个无法以当前字体打印的字符)
我已经将同一个文件导出到Media Monkey中的播放列表中,它将“Ô写为“É”——我假设这是正确的(正如KennyTM指出的)
我的问题是,如何获得“‰”符号输出?我需要选择不同的字体吗?如果需要,选择哪种字体
更新
人们似乎没有抓住重点
我可以使用
playList.WriteLine("É");
这不是问题所在
问题是Media Monkey要求文件采用以下格式:
#EXTINFUTF8:140,Yann Tiersen - Comptine D'Un Autre Été: L'Après Midi
#EXTINF:140,Yann Tiersen - Comptine D'Un Autre Été: L'Après Midi
#UTF8:04-Comptine D'Un Autre Été- L'Après Midi.mp3
04-Comptine D'Un Autre Été- L'Après Midi.mp3
其中所有的“高ascii”(因为缺少更好的术语)都被写成一对字符
更新2
我应该将c9
替换为c389
我本来打算把我实际得到的东西放进去,但是在做这个测试的过程中,我设法得到了一个测试程序,以正确的格式“原样”输出文本。因此,我需要做更多的调查。我不做C#但症状告诉我,您确实是以UTF-8的形式编写的,但是您查看写入输出的输出/控制台/应用程序/任何东西都不是使用UTF-8,而是使用ISO-8859-1来显示它们,MediaMonkey使用CP1252来显示它们
如果在IDE控制台中查看它们,则需要将IDE配置为使用UTF-8
作为控制台和文本文件编码
更新您显然希望将UTF-8
数据写入CP-1252
。现在问题更清楚了。同样,我不做C#,但Java等价物是:
Writer writer = new OutputStreamWriter(new FileOutputStream("file.ext"), "CP-1252");
writer.write(someUTF8String); // Will be written as CP-1252. "É" would become "É"
希望这能提供一些见解。我不做C#但症状告诉我,您确实是以UTF-8的形式编写的,但是您查看编写的输出的输出/控制台/应用程序/任何东西都不是使用UTF-8,而是使用ISO-8859-1来显示它们,MediaMonkey使用CP1252来显示它们
如果在IDE控制台中查看它们,则需要将IDE配置为使用UTF-8
作为控制台和文本文件编码
更新您显然希望将UTF-8
数据写入CP-1252
。现在问题更清楚了。同样,我不做C#,但Java等价物是:
Writer writer = new OutputStreamWriter(new FileOutputStream("file.ext"), "CP-1252");
writer.write(someUTF8String); // Will be written as CP-1252. "É" would become "É"
希望这能提供一些见解。像这样使用
Convert.ToChar
几乎肯定是个坏主意。你基本上是在两次编码
您应该自己执行转换,然后直接写入流,或者让StreamWriter
执行转换。如果您试图自己执行转换,为什么要使用StreamWriter
您正在尝试写入二进制文件还是简单的文本文件?如果它是一个简单的文本文件,只需使用StreamWriter
就可以进行转换。如果是二进制文件,请使用流
而不是流编写器
,并在需要时直接执行文本编码,然后将字节直接写入流
编辑:以下是您的原始代码发生的情况:
Encoding.UTF8.GetBytes(text) => byte[] { 0xc3, 0x89 };
Convert.ToChar(0xc3) => char U+00C3
StreamWriter writes U+00C3 as byte[] { 0xc3, 0x83 };
Convert.ToChar(0x89) => char U+0089
StreamWriter writes U+00C3 as byte[] { 0xc2, 0x89 };
这就是为什么要将c3 83 c2 89写入文件。像这样使用
Convert.ToChar
几乎肯定是个坏主意。你基本上是在两次编码
您应该自己执行转换,然后直接写入流,或者让StreamWriter
执行转换。如果您试图自己执行转换,为什么要使用StreamWriter
您正在尝试写入二进制文件还是简单的文本文件?如果它是一个简单的文本文件,只需使用StreamWriter
就可以进行转换。如果是二进制文件,请使用流
而不是流编写器
,并在需要时直接执行文本编码,然后将字节直接写入流
编辑:以下是您的原始代码发生的情况:
Encoding.UTF8.GetBytes(text) => byte[] { 0xc3, 0x89 };
Convert.ToChar(0xc3) => char U+00C3
StreamWriter writes U+00C3 as byte[] { 0xc3, 0x83 };
Convert.ToChar(0x89) => char U+0089
StreamWriter writes U+00C3 as byte[] { 0xc2, 0x89 };
这就是为什么要将c3 83 c2 89写入文件。
StreamWriter
已经将发送的字符转换为UTF-8 — 这就是它的全部目的。扔掉WriteUTF8
;它坏了,没用了
(WriteUTF8
是获取字符,将它们转换为UTF-8字节,将每个单个字节转换为它在当前代码页中映射到的字符,然后用UTF-8编码每个字符。因此,在最好的情况下,您有一个双UTF-8编码字符串;在最坏的情况下,您完全丢失了系统中未映射的字节e页面指令集;对于DBCS代码页尤其糟糕。)
Media Monkey的问题可能只是它根本不支持UTF-8或Unicode文件名。请尝试让它播放(并导出播放列表)不适合系统代码页字符的文件,例如将文件重命名为αβγ.mp3
编辑:
好的,您在同一个文件中得到的是混合编码:难怪文本编辑器在打开它时会遇到问题。未注释和#definef
行位于系统默认代码页中,用于支持无法读取Unicode文件名的媒体播放器。系统中没有任何文件名字符对于不知道#UTF8
(以及#extefutf8
(用于说明)行的任何内容,代码页(如上面的希腊文,在Western Windows安装中)将被损坏且不可打印
因此,如果这是您的目标格式,则需要获取两个编码和u
private static void writePlaylistEntry(Stream playlist, string filename, int length) {
Encoding utf8= new UTF8Encoding(false);
Encoding ansi= Encoding.Default;
playlist.Write(utf8.GetBytes("#EXTINFUTF8:"+length+","+filename+"\n"));
playlist.Write(ansi.GetBytes("#EXTINF:"+length+","+filename+"\n"));
playlist.Write(utf8.GetBytes("#UTF8:"+filename+"\n"));
playlist.Write(ansi.GetBytes(filename+"\n"));
}
private static void WriteUTF8(...)
static void Main(string[] args)
{
string fileName = @"C:\Temp\Test.m3u";
using (StreamWriter writer = new StreamWriter(fileName, false,
Encoding.GetEncoding(1252)))
{
writer.WriteLine("#EXTM3U");
writer.WriteLine("#EXTINF:140,Yann Tiersen " +
"- Comptine D'Un Autre Été: L'Après Midi");
writer.WriteLine("04-Comptine D'Un Autre Été- L'Après Midi.mp3");
}
}
var playList = new StreamWriter(playlist, false, Encoding.Default);
playList.WriteLine("#EXTM3U");
foreach (string track in tracks)
{
// Read ID3 tags from file
var info = new FileProperties(track);
// Write extended info (#EXTINF:<time>,<artist> - <title>
if (Encoding.UTF8.GetBytes(info.Artist).Length != info.Artist.Length ||
Encoding.UTF8.GetBytes(info.Title).Length != info.Title.Length)
{
playList.Close();
playList = new StreamWriter(playlist, true, Encoding.UTF8);
playList.WriteLine(string.Format("#EXTINFUTF8:{0},{1} - {2}",
info.Duration, info.Artist, info.Title));
playList.Close();
playList = new StreamWriter(playlist, true, Encoding.Default);
}
playList.WriteLine(string.Format("#EXTINF:{0},{1} - {2}",
info.Duration, info.Artist, info.Title));
// Write the name of the file (removing the drive letter)
string file = Path.GetFileName(track);
if (Encoding.UTF8.GetBytes(file).Length != file.Length)
{
playList.Close();
playList = new StreamWriter(playlist, true, Encoding.UTF8);
playList.WriteLine(string.Format("#UTF8:{0}", file));
playList.Close();
playList = new StreamWriter(playlist, true, Encoding.Default);
}
playList.WriteLine(file);
}
playList.Close();