2012-09-08 30 views
6

我想插入我的字符串到文件的開頭。但是沒有功能可以追加在流媒體作家中。那麼我應該怎麼做?如何使用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(); 

但它似乎沒有優化。那麼還有其他方法嗎?

+1

寫該文件的開始將覆蓋那裏的內容。考慮將數據附加到文件的末尾而不是開始。 – Oded

+0

您需要讀取整個文件,將其存儲在一個字符串中,然後使用'String.Insert'將新數據插入到該字符串的開頭,然後用修改的字符串重寫整個文件。 –

+0

@ 0 _______ 0這就像我所做的一樣。 – hamed

回答

8

你幾乎有:

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

+1。同樣簡單的'新StreamWriter(path,true)'修復也可以。 –

+0

代碼編輯:刪除不必要的'.Close()'調用 - '使用'已經照顧它。 –

+3

答案並不考慮文件大小可能超過虛擬內存空間的可用區域。 – SerG

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

爲什麼你需要明確創建支持FileStream? – SerG

+0

SerG,它是前一段時間,但我敢打賭,因爲它提供了一個緩衝區大小的過載。 – aiodintsov

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