8

ファイルの先頭に文字列を挿入したい。ただし、ストリームライターの最初に追加する機能はありません。では、どうすればよいでしょうか。

私のコードは:

string path = Directory.GetCurrentDirectory() + "\\test.txt";
StreamReader sreader = new StreamReader(path);
string str = sreader.ReadToEnd();
sreader.Close();

StreamWriter swriter = new StreamWriter(path, false);

swriter.WriteLine("example text");
swriter.WriteLine(str);
swriter.Close();

しかし、それは最適化されていないようです。それで他の方法はありますか?

4

3 に答える 3

10

あなたはほとんどそこにいます:

        string path = Directory.GetCurrentDirectory() + "\\test.txt";
        string str;
        using (StreamReader sreader = new StreamReader(path)) {
            str = sreader.ReadToEnd();
        }

        File.Delete(path);

        using (StreamWriter swriter = new StreamWriter(path, false))
        {
            str = "example text" + Environment.NewLine + str;
            swriter.Write(str);
        }
于 2012-09-08T20:02:42.113 に答える
4

同じファイルに書き込む他のプロセスを考慮する必要がなく、プロセスにディレクトリへの作成権限がある場合、これに対処する最も効率的な方法は次のとおりです。

  1. 一時的な名前で新しいファイルを作成します
  2. 新しいテキストを書く
  3. ファイルから古いテキストを追加します
  4. ファイルを削除する
  5. 一時ファイルの名前を変更します

それほどクールで高速ではありませんが、少なくとも、現在使用しているアプローチのためにメモリに巨大な文字列を割り当てる必要はありません。

ただし、ファイルの長さが数メガバイト未満のように小さいことが確実な場合は、アプローチはそれほど悪くありません。

ただし、コードを少し単純化することは可能です。

public static void InsertText( string path, string newText )
{
    if (File.Exists(path))
    {
        string oldText = File.ReadAllText(path);
        using (var sw = new StreamWriter(path, false))
        {
            sw.WriteLine(newText);
            sw.WriteLine(oldText);
        }
    }
    else File.WriteAllText(path,newText);
}

大きなファイルの場合(つまり、>数MB)

public static void InsertLarge( string path, string newText )
{
    if(!File.Exists(path))
    {
        File.WriteAllText(path,newText);
        return;
    }

    var pathDir = Path.GetDirectoryName(path);
    var tempPath = Path.Combine(pathDir, Guid.NewGuid().ToString("N"));
    using (var stream = new FileStream(tempPath, FileMode.Create, 
        FileAccess.Write, FileShare.None, 4 * 1024 * 1024))
    {
        using (var sw = new StreamWriter(stream))
        {
            sw.WriteLine(newText);
            sw.Flush();
            using (var old = File.OpenRead(path)) old.CopyTo(sw.BaseStream);
        }
    }
    File.Delete(path);
    File.Move(tempPath,path);
}
于 2012-09-08T20:16:43.787 に答える
0

このようなもの:

    private void WriteToFile(FileInfo pFile, string pData)
    {
        var fileCopy = pFile.CopyTo(Path.GetTempFileName(), true);

        using (var tempFile = new StreamReader(fileCopy.OpenRead()))
        using (var originalFile = new  StreamWriter(File.Open(pFile.FullName, FileMode.Create)))
        {
            originalFile.Write(pData);
            originalFile.Write(tempFile.ReadToEnd());
            originalFile.Flush();
        }

        fileCopy.Delete();
    }
于 2012-09-08T20:19:01.243 に答える