как написать в начало файла с помощью Stream Writer?

Я хочу вставить свою строку в начало файла. Но в начале stream writer нет функции для добавления. Так как же мне это сделать ?

мой код :

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();

но он не кажется оптимизированным. Есть ли другой способ ?

3 ответов


вы почти там:

        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);
        }

Если вам не нужно рассматривать другие процессы, записывающие в тот же файл, и ваш процесс имеет разрешения на создание каталога, наиболее эффективным способом борьбы с этим было бы:

  1. создать новый файл с именем temp
  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);
}

и для больших файлов (т. е. > несколько МБ)

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);
}

что-то вроде этого:

    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();
    }