c# getting anc 更改文件编码
c# getting anc changing the file encoding
我对文件编码有点困惑。我想改变它。这是我的代码:
public class ChangeFileEncoding
{
private const int BUFFER_SIZE = 15000;
public static void ChangeEncoding(string source, Encoding destinationEncoding)
{
var currentEncoding = GetFileEncoding(source);
string destination = Path.GetDirectoryName(source) +@"\"+ Guid.NewGuid().ToString() + Path.GetExtension(source);
using (var reader = new StreamReader(source, currentEncoding))
{
using (var writer =new StreamWriter(File.OpenWrite(destination),destinationEncoding ))
{
char[] buffer = new char[BUFFER_SIZE];
int charsRead;
while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer, 0, charsRead);
}
}
}
File.Delete(source);
File.Move(destination, source);
}
public static Encoding GetFileEncoding(string srcFile)
{
using (var reader = new StreamReader(srcFile))
{
reader.Peek();
return reader.CurrentEncoding;
}
}
}
在 Program.cs 我有代码:
string file = @"D:\path\test.txt";
Console.WriteLine(ChangeFileEncoding.GetFileEncoding(file).EncodingName);
ChangeFileEncoding.ChangeEncoding(file, new System.Text.ASCIIEncoding());
Console.WriteLine(ChangeFileEncoding.GetFileEncoding(file).EncodingName);
在我的控制台中打印的文本是:
Unicode (UTF-8)
Unicode (UTF-8)
为什么文件的编码没有改变?
我在更改文件编码时出错了?
此致
StreamReader class,当没有在其构造函数中传递编码时,将尝试自动检测文件的编码。当文件以 BOM 开头时,它会很好地执行此操作(并且您应该在更改文件编码时编写序言,以便下次您要读取文件时进行此操作)。
正确检测文本文件的编码是一个难题,尤其是对于非 Unicode 文件或没有 BOM 的 Unicode 文件。 reader(无论是 StreamReader、Notepad++ 还是任何其他 reader)都必须 猜测 文件中使用了哪种编码。
另见 How can I detect the encoding/codepage of a text file,强调我的:
You can't detect the codepage, you need to be told it. You can analyse the bytes and guess it, but that can give some bizarre (sometimes amusing) results.
因为 ASCII(字符 0-127)是 Unicode 的一个子集,所以使用单字节 Unicode 编码(UTF-8)读取 ASCII 文件是安全的。因此 StreamReader 使用该编码。
也就是说,只要它是真正的 ASCII。代码点 127 以上的任何字符都将是 ANSI,然后您就可以享受 检测 猜测正确代码页的乐趣。
所以回答你的问题:你已经改变了文件的编码,根本没有万无一失的方法来"detect"它,你只能猜测。
必读material:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) and Unicode, UTF, ASCII, ANSI format differences.
使用 StreamReader.CurrentEncoding
检测有点棘手,因为它不会说明文件使用什么编码,而是说明 StreamReader
需要什么编码才能读取它。基本上,如果没有 BOM 而没有读取整个文件(并分析你在那里找到的内容,这不是微不足道的),就没有简单的方法来检测编码。
对于带有 BOM 的文件,很简单:
public static Encoding GetFileEncoding(string srcFile)
{
var bom = new byte[4];
using (var f = new FileStream(srcFile, FileMode.Open, FileAccess.Read))
f.Read(bom, 0, 4);
if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) return Encoding.UTF7;
if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) return Encoding.UTF8;
if (bom[0] == 0xff && bom[1] == 0xfe) return Encoding.Unicode;
if (bom[0] == 0xfe && bom[1] == 0xff) return Encoding.BigEndianUnicode;
if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;
// No BOM, so you choose what to return... the usual would be returning UTF8 or ASCII
return Encoding.UTF8;
}
我对文件编码有点困惑。我想改变它。这是我的代码:
public class ChangeFileEncoding
{
private const int BUFFER_SIZE = 15000;
public static void ChangeEncoding(string source, Encoding destinationEncoding)
{
var currentEncoding = GetFileEncoding(source);
string destination = Path.GetDirectoryName(source) +@"\"+ Guid.NewGuid().ToString() + Path.GetExtension(source);
using (var reader = new StreamReader(source, currentEncoding))
{
using (var writer =new StreamWriter(File.OpenWrite(destination),destinationEncoding ))
{
char[] buffer = new char[BUFFER_SIZE];
int charsRead;
while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer, 0, charsRead);
}
}
}
File.Delete(source);
File.Move(destination, source);
}
public static Encoding GetFileEncoding(string srcFile)
{
using (var reader = new StreamReader(srcFile))
{
reader.Peek();
return reader.CurrentEncoding;
}
}
}
在 Program.cs 我有代码:
string file = @"D:\path\test.txt";
Console.WriteLine(ChangeFileEncoding.GetFileEncoding(file).EncodingName);
ChangeFileEncoding.ChangeEncoding(file, new System.Text.ASCIIEncoding());
Console.WriteLine(ChangeFileEncoding.GetFileEncoding(file).EncodingName);
在我的控制台中打印的文本是:
Unicode (UTF-8)
Unicode (UTF-8)
为什么文件的编码没有改变? 我在更改文件编码时出错了?
此致
StreamReader class,当没有在其构造函数中传递编码时,将尝试自动检测文件的编码。当文件以 BOM 开头时,它会很好地执行此操作(并且您应该在更改文件编码时编写序言,以便下次您要读取文件时进行此操作)。
正确检测文本文件的编码是一个难题,尤其是对于非 Unicode 文件或没有 BOM 的 Unicode 文件。 reader(无论是 StreamReader、Notepad++ 还是任何其他 reader)都必须 猜测 文件中使用了哪种编码。
另见 How can I detect the encoding/codepage of a text file,强调我的:
You can't detect the codepage, you need to be told it. You can analyse the bytes and guess it, but that can give some bizarre (sometimes amusing) results.
因为 ASCII(字符 0-127)是 Unicode 的一个子集,所以使用单字节 Unicode 编码(UTF-8)读取 ASCII 文件是安全的。因此 StreamReader 使用该编码。
也就是说,只要它是真正的 ASCII。代码点 127 以上的任何字符都将是 ANSI,然后您就可以享受 检测 猜测正确代码页的乐趣。
所以回答你的问题:你已经改变了文件的编码,根本没有万无一失的方法来"detect"它,你只能猜测。
必读material:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) and Unicode, UTF, ASCII, ANSI format differences.
使用 StreamReader.CurrentEncoding
检测有点棘手,因为它不会说明文件使用什么编码,而是说明 StreamReader
需要什么编码才能读取它。基本上,如果没有 BOM 而没有读取整个文件(并分析你在那里找到的内容,这不是微不足道的),就没有简单的方法来检测编码。
对于带有 BOM 的文件,很简单:
public static Encoding GetFileEncoding(string srcFile)
{
var bom = new byte[4];
using (var f = new FileStream(srcFile, FileMode.Open, FileAccess.Read))
f.Read(bom, 0, 4);
if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) return Encoding.UTF7;
if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) return Encoding.UTF8;
if (bom[0] == 0xff && bom[1] == 0xfe) return Encoding.Unicode;
if (bom[0] == 0xfe && bom[1] == 0xff) return Encoding.BigEndianUnicode;
if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;
// No BOM, so you choose what to return... the usual would be returning UTF8 or ASCII
return Encoding.UTF8;
}