2016-05-14 180 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操作只會減慢速度:) –

相關問題