为什么这些nul出现了

时间:2016-05-14 22:01:37

标签: c# filestream

我曾经使用以下函数写入许多不同的文件

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复制为1,但即便如此,也发生了NUL。

3 个答案:

答案 0 :(得分:4)

您的原始代码已损坏。

使用Encoding.Unicode时,line.LengthencodedText.Length不同。当您尝试写入数据时,您只会写一半(平均)。

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

在任何一种情况下,请确保编写尽可能多的字节来写入。字符数无关紧要。并确保使用正确的编码 - 只能有一个。

作为旁注,您的代码也会比原始代码慢得多。这很可能是一次糟糕的权衡。相反,您可能希望捕获整个foreach,并传递IEnumerable<string>而不是string。如果你真的只需要在某些情况下写一个字符串,你可以提供params string重载或任何最适合你的方法。并且确保所有情况都是等效的 - 这个肯定不是,因为原始文件在原始代码中被丢弃,而它只会附加到您的代码中。

答案 1 :(得分:0)

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

精化:

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

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

答案 2 :(得分:0)

您是否尝试过增加bufferSize。您应该看看在更改后nul开始插入的位置是否存在差异。

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