4

这是将字符串写入文件的代码

System.IO.File.WriteAllText("test.txt", "P                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ");

它基本上是字符“P”,后跟总共 513 个空格字符。

当我在 Notepad++ 中打开文件时,它似乎很好。但是,当我在 Windows 记事本中打开时,我看到的只是乱码。

如果我添加 514 或 512 而不是 513 空格字符,它会在记事本中正常打开。

我错过了什么?

4

2 回答 2

5

您缺少的是记事本在猜测,这并不是因为您的长度特别是 513 个空格……而是因为它是偶数字节并且文件大小> = 100 总字节。尝试 511 或 515 个空格 ... 或 99 ... 您会看到对文件内容的相同误解。对于奇数字节,记事本可以假设您的文件不是任何双字节编码,因为这些都会导致每个字符 2 个字节 = 文件中总字节数的偶数。如果您在文件开头添加更多低位 ASCII 字符(例如,“PICKLE”+ 空格),记事本会更好地理解它应该将内容视为单字节字符。

建议的包含方法Encoding.UTF8是最简单的修复方法......它将在文件的开头写入一个 BOM,告诉记事本(和记事本++)数据的格式是什么,因此它不必求助于这种猜测行为(您可以通过在 Notepad++ 中打开两者来查看原始方法和 BOM 方法之间的区别,然后查看应用程序的右下角。使用 BOM,它会告诉您编码是UTF-8-BOM......没有它,它只会说UTF-8)。

我还应该说,您文件的内容本身并没有“错误”……奇怪的格式纯粹是由于记事本的“猜测”算法。因此,除非要求人们使用记事本读取带有 1 个字母和大量奇数空格的文件......也许只是不要出汗。如果您确实更改为使用 写入文件Encoding.UTF8,那么您确实需要确保读取您文件的任何其他系统都知道如何遵守 BOM,因为这对文件内容的真正更改。如果您无法验证文件的所有使用者都可以/将处理 BOM,那么只需了解记事本恰好对您的特定用例做出错误的猜测,并将原始内容完全按照您想要的方式保留,可能会更安全。

您可以通过执行二进制读取然后将它们转换为字符串来验证文件与 BOM 的物理差异(您无法“看到”更改ReadAllText,因为它尊重并剥离 BOM):

byte[] contents = System.IO.File.ReadAllBytes("test.txt");
Console.WriteLine(Encoding.ASCII.GetString(contents));
于 2018-08-15T20:36:28.790 回答
3

尝试传入不同的编码:

i. System.IO.File.WriteAllText(filename , stringVariable, Encoding.UTF8);
ii. System.IO.File.WriteAllText(filename , stringVariable, Encoding.UTF32);
iii. etc.

您也可以尝试使用另一种方式来构建您的字符串,使其更易于阅读、更改和计数,而不是点击空格键 513 次;

一世。使用字符串构造函数(如@Tigran 建议的)

var result = "P" + new String(' ', 513);

ii. 使用 stringBuilder

var stringBuilder = new StringBuilder();
stringBuilder.Append("P");

for (var i = 1; i <= 513; i++) { stringBuilder.Append(" "); }

iii. 或两者

public string AppendSpacesToString(string stringValue, int numberOfSpaces) 
{
    var stringBuilder = new StringBuilder();
    stringBuilder.Append(stringValue);
    stringBuilder.Append(new String(' ', numberOfSpaces));
    return stringBuilder.ToString();
}
于 2018-08-15T20:14:04.783 回答