我正在编写一些测试应用程序,使用StreamWriter将一些文本写入文本文件。执行WriteLine方法时系统突然关闭。重新启动后,机器发现文件末尾有许多NUL字符。
搜索了很多网站,包括MSDN,我没有找到解决此问题的方法。
任何人都可以帮我解决这个问题。
如果我们执行以下步骤,这很容易重现:
在按钮单击事件处理程序中,编写以下代码:
private void button1_Click(object sender,EventArgs e)
{
string str = "Welcome to the C Sharp programming world with a test application using IO operations.";
StreamWriter sw = new StreamWriter(fileName, true, Encoding.Unicode, str.Length);
sw.WriteLine(str);
sw.Close();
}
运行应用程序并连续单击按钮(不要直到机器关闭)并按下PC的电源按钮。
重新启动电脑并检查包含以下文字的文件:
欢迎使用使用IO操作的测试应用程序来访问C Sharp编程世界。
欢迎使用使用IO操作的测试应用程序来访问C Sharp编程世界。
欢迎使用使用IO操作的测试应用程序来访问C Sharp编程世界。
欢迎使用使用IO操作的测试应用程序来访问C Sharp编程世界。
欢迎使用使用IO操作的测试应用程序来访问C Sharp编程世界。
欢迎使用使用IO操作的测试应用程序来访问C Sharp编程世界。
NULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNUL
NUL字符将出现在NotePad ++中,我们无法在Normal NotePad中看到这些字符。
先谢谢
答案 0 :(得分:2)
发生这种情况。首先附加文件时,在目录中更正其大小(并且在NTFS中是事务性的),然后写入实际的新数据。很有可能如果你关闭系统,你最终会得到一个附加大量空字节的文件,因为数据写入不是事务性的,不像元数据(文件大小)写入。
这个问题没有绝对的解决办法。
答案 1 :(得分:2)
我在Linux(在树莓派上)上的 netcore 遇到了同样的问题。看起来它们是某种未及时刷新的缓冲区。 (StreamWriter.Flush()
方法无济于事。)
解决方法是将缓冲区大小设置为数据大小array.Length
,并使用FileOptions.WriteThrough
禁用所有缓存(来自msdn:)
指示系统应该通过任何中间高速缓存写入 并直接转到磁盘。
string str = "Welcome to the C Sharp programming world with a test application using IO operations.";
byte[] data = new UTF8Encoding(true).GetBytes(str);
using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write,
FileShare.Read, data.Length, FileOptions.WriteThrough))
{
fs.Write(data , 0, data.Length);
}
对于来自C / C ++的用户,请设置posix标志:
O_DIRECT尝试最大程度减少往返于此的I / O的缓存影响 文件。通常,这会降低性能,但在 特殊情况,例如应用程序自行缓存时。 文件I / O直接在用户空间缓冲区中进行,也可以从用户空间缓冲区中进行。
更多信息:SO question
答案 2 :(得分:0)
我知道它看起来很糟糕,但这是我必须要解决的问题。将字符串写入文件后,只需输入以下代码即可。
var lines = System.IO.File.ReadAllLines(workingFile.FullName);
//Strip the "null line" from file
if (lines[lines.Length - 1].StartsWith("\0\0\0\0\0"))
{
System.IO.File.WriteAllLines(workingFile.FullName, lines.Take(lines.Length - 1).ToArray());
}
这样做是将文件中的所有行读入一个数组,如果最后一行是那个讨厌的NUL行,代码将写入数组的所有元素减去最后一个元素(NUL行)