为什么会出现这些 nul
Why are these nul's appearing
我曾经使用以下函数写入很多不同的文件
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 会附加到文本中
这些空值来自哪里?我也尝试将 filestream()
设置 1 对 1 复制,但即使这样 NUL 也出现了。
也许您正在编写 UTF-16 输出?
阐述:
在您问题的第一段和第二段代码中,您使用的是 Encoding.Unicode
,它将字符串编码为 little endian UTF-16 byte representations。 ASCII 字符的 Little endian 字节顺序 UTF-16 表示形式,例如 0
或 G
包含通常的 ASCII 字节作为第一个字节,然后 0
(NUL
) 作为第二个字节字符的字节。这可能是输出中 NUL
字节的来源。
至于为什么 NUL
没有出现在第一个代码块的输出中,我不确定。请 post 一个输入字符串,它不会为第一个代码块输出 NUL
个字节,但会为第二个代码块输出 NUL
个输出字节,以便确认问题的原因.
您是否尝试过增加 bufferSize。您应该查看更改后 nul 开始插入的位置是否存在差异。
也不确定 for 循环 运行 通过所有行到只有一个方法产生结果之间发生了什么。你没有多个线程 运行 同时去这个文件吧?
您的原始代码已损坏。
当使用Encoding.Unicode
时,line.Length
和encodedText.Length
不是一回事。当您尝试写入数据时,您只写入了大约一半(平均)。
由于在您的示例中实际上并没有发生这种情况,最可能的原因是您实际上并未使用 Encoding.Unicode
,而是 Encoding.UTF8
或单字节 ANSI/ASCII编码。
无论哪种情况,请确保您写入的字节数与要写入的字节数一样多。字符数无关紧要。并确保使用正确的编码 - 只能有一个。
附带说明一下,您的代码也将比原始代码慢得多。这很可能是一个糟糕的权衡。相反,您可能想要捕获整个 foreach
,并传递 IEnumerable<string>
而不仅仅是 string
。如果在某些情况下你真的只需要写一个字符串,你可以提供一个 params string
重载或任何最适合你的东西。并确保所有情况实际上都是等价的——这个肯定不是,因为原始文件在原始代码中被丢弃,而它只在你的代码中附加过。
我曾经使用以下函数写入很多不同的文件
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 会附加到文本中
这些空值来自哪里?我也尝试将 filestream()
设置 1 对 1 复制,但即使这样 NUL 也出现了。
也许您正在编写 UTF-16 输出?
阐述:
在您问题的第一段和第二段代码中,您使用的是 Encoding.Unicode
,它将字符串编码为 little endian UTF-16 byte representations。 ASCII 字符的 Little endian 字节顺序 UTF-16 表示形式,例如 0
或 G
包含通常的 ASCII 字节作为第一个字节,然后 0
(NUL
) 作为第二个字节字符的字节。这可能是输出中 NUL
字节的来源。
至于为什么 NUL
没有出现在第一个代码块的输出中,我不确定。请 post 一个输入字符串,它不会为第一个代码块输出 NUL
个字节,但会为第二个代码块输出 NUL
个输出字节,以便确认问题的原因.
您是否尝试过增加 bufferSize。您应该查看更改后 nul 开始插入的位置是否存在差异。
也不确定 for 循环 运行 通过所有行到只有一个方法产生结果之间发生了什么。你没有多个线程 运行 同时去这个文件吧?
您的原始代码已损坏。
当使用Encoding.Unicode
时,line.Length
和encodedText.Length
不是一回事。当您尝试写入数据时,您只写入了大约一半(平均)。
由于在您的示例中实际上并没有发生这种情况,最可能的原因是您实际上并未使用 Encoding.Unicode
,而是 Encoding.UTF8
或单字节 ANSI/ASCII编码。
无论哪种情况,请确保您写入的字节数与要写入的字节数一样多。字符数无关紧要。并确保使用正确的编码 - 只能有一个。
附带说明一下,您的代码也将比原始代码慢得多。这很可能是一个糟糕的权衡。相反,您可能想要捕获整个 foreach
,并传递 IEnumerable<string>
而不仅仅是 string
。如果在某些情况下你真的只需要写一个字符串,你可以提供一个 params string
重载或任何最适合你的东西。并确保所有情况实际上都是等价的——这个肯定不是,因为原始文件在原始代码中被丢弃,而它只在你的代码中附加过。