5

を使用してテキスト ファイルにテキストを書き込むテスト アプリケーションを作成していますStreamWriter。メソッドの実行中にWriteLine、システムが突然シャットダウンします。マシンを再起動した後、ファイルの末尾に多くの NUL 文字があることに気付きました。

MSDN を含む多くのサイトを検索しましたが、この問題の解決策は見つかりませんでした。

この問題を解決するのを手伝ってくれる人はいますか?

これは、次の手順を実行すると簡単に再現できます。

  1. WindowsApplication を作成し、ボタン コントロールを配置します。

  2. ボタン クリック イベント ハンドラーで、次のコードを記述します。

    private void button1_Click(オブジェクト送信者, 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();        
     } 
    
  3. アプリケーションを実行し、ボタンを連続してクリックし (マシンがシャットダウンするまで停止しないでください)、PC の電源オフ ボタンを押します。

  4. PCを再起動し、ファイルを確認してください。次のテキストが含まれています。

IO 操作を使用したテスト アプリケーションを使用した C Sharp プログラミングの世界へようこそ。

IO 操作を使用したテスト アプリケーションを使用した C Sharp プログラミングの世界へようこそ。

IO 操作を使用したテスト アプリケーションを使用した C Sharp プログラミングの世界へようこそ。

IO 操作を使用したテスト アプリケーションを使用した C Sharp プログラミングの世界へようこそ。

IO 操作を使用したテスト アプリケーションを使用した C Sharp プログラミングの世界へようこそ。

IO 操作を使用したテスト アプリケーションを使用した C Sharp プログラミングの世界へようこそ。

NULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNUL

NUL 文字は Notepad++ に表示され、通常のメモ帳ではこれらの文字は表示されません。

4

3 に答える 3

3

発生します。最初にファイルを追加すると、そのサイズがディレクトリで修正され (NTFS ではトランザクションになります)、実際の新しいデータが書き込まれます。システムをシャットダウンすると、多くの null バイトが追加されたファイルが作成される可能性が高くなります。これは、メタデータ (ファイル サイズ) の書き込みとは異なり、データの書き込みがトランザクションに対応していないためです。

この問題に絶対的な解決策はありません。

于 2012-06-06T11:53:39.107 に答える
3

Linux(ラズベリー)のネットコアでも同じ問題がありました。時間内にフラッシュされないある種のバッファのようです。(StreamWriter.Flush()メソッドは役に立ちません)。

回避策は、バッファー サイズをデータ サイズに設定し、(msdn から:)array.Lengthですべてのキャッシュを無効にすることです。FileOptions.WriteThrough

システムが中間キャッシュを介して書き込み、ディスクに直接移動する必要があることを示します。

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 の質問

于 2020-08-05T13:33:54.003 に答える
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 行) を引いたものを書き込みます。

于 2014-09-26T19:29:16.600 に答える