2015-12-31 129 views
3

我想將文本從文本框追加到文本文件中的新行並且遇到問題。比方說,目前已經在文本文件中的內容,看起來像這樣追加到新行不會去換行

something 
Something 
Something<---- Cursor ends here 

光標的結束位置的箭頭指向(在過去的「東西」對於g後,如果我嘗試使用

File.AppendAllLines(@"Location", new[]{tb.Text}); 

或者

File.AppendAllText(@"Location", tb.Text + Environment.NewLine); 

就會把光標所在處,而不是在文本文件中的最後一個項目下一個新行的文本。它的工作原理,如果光標在一個新行開始與但如就在它結束的時候,所有事物都在同一行上。

有什麼我失蹤了嗎?會使用Streamwriter或其他方法解決這個問題嗎?

+0

它做你應該期望的。您的文本不會以換行符初始化,因此它會緊接在前一個文本結束的位置後面添加,您是否在追加前讀取前一個文本? – Steve

+1

請確保您追加到文件的行以'Environment.NewLine'結尾,或者將整個文件讀入內存並查看最後一個字符是否爲換行符。如果不是,則在文本前加一個換行符。 –

+0

我很好奇你爲什麼認爲這些會附加到下面的行(正如當前寫入的),並且光標指向它所在的位置。 –

回答

1

實際上,正如在其他答案中指出的那樣。這是設計。 File.AppendAllLines在文件末尾添加文本。在追加文本之前,它不會添加換行符。爲此,您必須以某種方式讀取文件並確定最後一個字符是否爲換行符。有多種方法可以做到這一點。

最簡單的方法是隻讀取所有行並檢查最後一行是否爲空。如果沒有,只需在將字符串傳遞給File.AppendAllLines之前在其中添加一個換行符。

但是,如果處理大文件,或者如果您不想多次打開該文件 - 就像下面的方法一樣會執行此操作,但仍然只打開一次文件。

public void AppendAllLinesAtNewLine(string path, IEnumerable<string> content) 
{ 
    // No file, just append as usual. 
    if (!File.Exists(path)) 
    { 
     File.AppendAllLines(path, content); 
     return; 
    } 

    using (var stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite)) 
    using (var reader = new StreamReader(stream)) 
    using (var writer = new StreamWriter(stream)) 
    { 
     // Determines if there is a new line at the end of the file. If not, one is appended. 
     long readPosition = stream.Length == 0 ? 0 : -1; 
     stream.Seek(readPosition, SeekOrigin.End); 
     string end = reader.ReadToEnd(); 
     if (end.Length != 0 && !end.Equals("\n", StringComparison.Ordinal)) 
     { 
      writer.Write(Environment.NewLine); 
     } 

     // Simple write all lines. 
     foreach (var line in content) 
     { 
      writer.WriteLine(line); 
     } 
    } 
} 

注意:long readPosition = s.Length == 0? 0:-1;用於處理空文件。

1

如果你把Environment.NewLine在文本的前面,它應該給你,你要尋找的結果:

File.AppendAllText(@"Location", Environment.NewLine + tb.Text); 
1

這是你所要求做什麼。它將您擁有的文本附加到現有文件。如果那個文件是'錯誤的',作者不能幫助它。

如果文件完全在您的控制之下,您可以確保將行結束寫入文件。否則,您可以閱讀每一行,將其附加到它,然後將整個文件寫回。這對於大文件顯然是不利的:

File.WriteAllLines(@"Location" 
        , File.ReadAllLines(@"Location") 
        .Concat(new string[] { text }) 
       ); 
3

它做你應該期望的。您的文本不會以換行符進行初始化,因此它會緊接在前一個文本結束的位置之後。爲了解決您的問題,您可以在寫入文件之前打開文件並嘗試讀取最後一個字節。

bool addNewLine = true; 
using (FileStream fs = new FileStream(@"location", FileMode.Open)) 
using (BinaryReader rd = new BinaryReader(fs)) 
{ 
    fs.Position = fs.Length - 1; 
    int last = rd.Read(); 

    // The last byte is 10 if there is a LineFeed 
    if (last == 10) 
     addNewLine = false; 
} 
string allLines = (addNewLine ? Environment.NewLine + tb.Text : tb.Text); 
File.AppendAllLines(@"Location", new[]{allLines}); 

正如你可以看到這一點更復雜,但這避免了讀取內存中的所有文件。

0

謝謝大家的建議,這裏是我決定做

FileStream stream = new FileStream("location", FileMode.Open, FileAccess.Read); 
     char actual = '\0'; 
     if(stream.Length != 0) 
     { 
      stream.Seek(-1, SeekOrigin.End); 
      var lastChar = (byte)stream.ReadByte(); 
      actual = (char)lastChar; 
     } 
     stream.Close(); 

     try { 
      if(addCompT.Text != "") 
      { 

       if (actual == '\n' || actual == '\0') 
        File.AppendAllText("location", addCompT.Text + Environment.NewLine); 
       else 
        File.AppendAllText("location", Environment.NewLine + addCompT.Text + Environment.NewLine); 

       addCompT.Text = ""; 
      } 

     } 
     catch(System.UnauthorizedAccessException) 
     { 
      MessageBox.Show("Please Run Program As Administrator!"); 
     } 

我感謝大家的幫助!