2016-05-14 185 views
1

我以前使用下面的函数为什么这些NUL的出现

using (FileStream fs = new FileStream(Settings.PsLog, FileMode.Truncate, System.Security.AccessControl.FileSystemRights.Write, FileShare.ReadWrite, 1024, FileOptions.None, null)) 
{ 
    foreach (string line in checkList) 
    { 
     byte[] encodedText = Encoding.Unicode.GetBytes(line + Environment.NewLine); 
     await fs.WriteAsync(encodedText, 0, line.Length); 
    } 
} 

写了很多不同的文件,因为这些代码被复制粘贴一回事,我决定把它解压到一个更广泛的功能。

private static async Task WriteTextAsync(string filePath, string text) 
{ 
    byte[] encodedText = Encoding.Unicode.GetBytes(text + Environment.NewLine); 
    using (FileStream sourceStream = new FileStream(filePath, 
      FileMode.Append, FileAccess.Write, FileShare.Write, 
      bufferSize: 1024, useAsync: true)) 
    { 
     await sourceStream.WriteAsync(encodedText, 0, encodedText.Length); 
    }; 
} 

使用提取的版本随机NUL的追加到文本

enter image description here

在哪里这些零点从哪里来但是经过?我试着复制filestream()设置1,但即使这样NUL也发生了。

+2

'Encoding.Unicode'是一种UTF-16编码。检查'byte'数组,它应该包含多个'0'字节。改用'Encoding.UTF8'。 –

+1

@JeanHominal似乎是这样。但是,函数A怎么来没有这个问题,而函数B呢。即使给出了相同的输入,并采取了相同的步骤? –

+0

这应该总是添加了NUL(实际上你明确地添加它们)。也许它在截断文件之前看起来很正确,因为编码是自动检测的(您可以通过在十六进制编辑器中打开它来测试),但另一种方式是将其附加到文件上,该文件可能具有UTF8 BOM(再次检查一个十六进制编辑器),无论如何开始一堆简单的ascii,这将愚弄读者的格式 – harold

回答

4

您的原始代码已损坏。当使用Encoding.Unicode时,line.LengthencodedText.Length不同。当你尝试写入数据时,你只写了大约一半的数据(平均而言)。

由于在您的示例中实际上没有发生这种情况,最可能的原因是您实际上没有使用Encoding.Unicode,而是Encoding.UTF8或单字节ANSI/ASCII编码之一。

在这两种情况下,请确保写入的字节数与要写入的字节数相同。字符的数量是不相关的。并确保你使用正确的编码 - 只能有一个。

作为一个侧面说明,您的代码将比原始代码慢得多。这很可能是一个糟糕的交易。相反,您可能想要捕获整个foreach,并通过IEnumerable<string>而不是仅仅string。如果在某些情况下您确实只需要写一个字符串,那么您可以提供一个params string超负荷或任何最适合您的服务。确保所有案例实际上都是相同的 - 这肯定不是,因为原始文件在原始代码中被丢弃,而它只被附加到代码中。

+0

'line.Length'确实是罪魁祸首。写了utf8格式的unicode编码的字符串,而不会丢失任何字符(除了nul的) –

0

也许你正在编写UTF-16输出?

阐述:

在你的问题的代码第一和秒块你正在使用Encoding.Unicode,编码字符串little endian UTF-16 byte representations。 ASCII字符(如0G)的Little Endian字节顺序UTF-16表示包含通常的ASCII字节作为第一个字节,然后0NUL)作为字符的第二个字节。这是输出中NUL字节的可能来源。

至于为什么NUL未出现在第一代码块的输出中,我不确定。请输入一个输入字符串,该输入字符串不会为第一个代码块输出NUL字节,但会为第二个代码块输出NUL输出字节,以便可以确认该问题的原因。

+1

考虑到我将它转换为unicode编码。写入中只包含数字和字母,并且只有其中一个功能添加了nul的我有点怀疑 –

+0

嗯......我会更深一层。稍后再看。谢谢。 –

+2

'Encoding.Unicode'是UTF-16。 – yaakov

0

您是否尝试过增加bufferSize。您应该看看改变后nul开始插入的位置是否有所不同。

还不确定在通过所有行运行的for循环与生成结果的单个方法之间发生了什么。你没有多个线程同时运行到这个文件吗?

+0

通过增加第一个函数的缓冲区大小,会出现同样的问题。所有从单线程运行,多线程IO操作只会减慢速度:) –

相关问题