2012-07-27 244 views
4

當我使用System.IO.File.WriteAllLines保存String []數組的內容時,文件末尾總是留空行。例如:.NET File.WriteAllLines在文件末尾留下空行

System.IO.File.WriteAllLines(Application.dataPath + "/test.txt",["a", "b", "c"]); 

主要生產文件(無下劃線):

a 
b 
c 
_ 

已經有這樣的話題:Empty line in .Net File.WriteAllLines, is a bug?,但作者日期說,「我覺得有什麼不對我的數據,這是我的問題但不是WritAllLines「,它被關閉爲」太本地化「(?!?)。

這是一個錯誤?我怎樣才能輕鬆擺脫它(現在我只是在再次閱讀文件時忽略它)?

+0

數組中的最後一項是否以換行符結束? – Polynomial 2012-07-27 14:02:56

+0

我已經給出了作爲參數給出的示例性數組:[「a」,「b」,「c」] 它只包含通常的字母。 – user1557862 2012-07-27 14:07:25

回答

6

WriteAllLines方法將寫出數組中的每一行,然後是換行符。這意味着你將永遠在你的文件中獲得這個「空行」。

在您鏈接的帖子中提出的一點是,在運行ReadAllLines時認爲一行是由換行符終止的字符。因此,當您對剛寫入的文件使用read方法時,應該返回完全相同的行。

如果你正在以不同的方式閱讀文件,那麼你將不得不自己處理換行符。

基本上你看到的是預期行爲。

+0

據我所知,擺脫它的最好方法是將'WriteAllText'與'String.Join'用'\ r \ n'作爲分隔符? – user1557862 2012-07-27 14:19:38

+0

看看[這個問題](http://stackoverflow.com/questions/585860/string-join-vs-stringbuilder-which-is-faster)關於String.Join和StringBuilder的性能 – Steve 2012-07-27 14:34:07

+0

由於總是有一個「最後一行「,不管它是否爲空,我都不明白爲什麼最後寫好的行必須是空的。 ReadAllLines產生的最後一個數組元素是一個不以換行符結束的文件行 - 它只是最後一行。 將WriteAllLines保存的文件與XmlSerializer.Serialize保存的文件進行比較,您會看到我的意思。 – 2016-06-19 10:11:46

3

WriteAllLines寫入數組中的每個條目並追加一個換行符。
正如你所看到的,每一個字符串都在它自己的行上,這意味着你的最後一個條目是換行符終止的,你會在文件中看到另一行。你可以用文件的十六進制轉儲來證明這一點

查看WriteAllLines的源代碼證實了這一點。
在內部,它使用TextWriter.WriteLine(string)方法。

9

正如其他人所指出的,這就是它的工作原理。下面是做它沒有額外的換行符的方法:

public static class FileExt 
{ 
    public static void WriteAllLinesBetter(string path, params string[] lines) 
    { 
     if (path == null) 
      throw new ArgumentNullException("path"); 
     if (lines == null) 
      throw new ArgumentNullException("lines"); 

     using (var stream = File.OpenWrite(path)) 
     using (StreamWriter writer = new StreamWriter(stream)) 
     { 
      if (lines.Length > 0) 
      { 
       for (int i = 0; i < lines.Length - 1; i++) 
       { 
        writer.WriteLine(lines[i]); 
       } 
       writer.Write(lines[lines.Length - 1]); 
      } 
     } 
    } 
} 

用法:

FileExt.WriteAllLinesBetter("test.txt", "a", "b", "c"); 

寫入:

 
    aenter 
    benter 
    c 
+0

工程就像一個魅力。 – 2016-06-19 10:21:10

0

我做同樣的事情,只是添加一行:3,希望幫助某人

for(int i = 0; i < Length; i++) 
    { 
     line = getLocation(i).X.ToString("0.0", nfi) + ',' + getLocation(i).Y.ToString("0.000", nfi) + ',' + getColorRaw(i).R.ToString("0.000", nfi) + ',' + getColorRaw(i).G.ToString("0.000", nfi) + ',' + getColorRaw(i).B.ToString("0.000", nfi); 
     writer.Write(line); 
     if(i < Length - 1) writer.Write("\n"); 
0

要得到擺脫尾隨的換行符,最好的解決方案是,當您用.ReadAllLines()讀取它時,實際上會解除字符串數組中的最後一個元素。

+1

這將是一個部分解決方案,以防空字符串被實際讀入接收數組結構中。這個問題表明事實並非如此。 – 2014-06-13 23:13:32

0

爲我做它usning AppendAllText的最後一行的最簡單方法:

if ($i -ne $lines.Count - 1){ 
    $newLines += $lines[$i] 
    } else { 
    $lastLine = $lines[$i] 
} 

[IO.File]::WriteAllLines($file.FullName, $newLines); 
[IO.File]::AppendAllText($file.FullName, $lastLine); 
1

@Virtlink解決方案是幾乎完美。實際上,有一種情況會在文件末尾發生垃圾 - 當文件存在並且其內容大於新內容時。在處理新文件內容之前,只需將文件長度重置爲零。

public static void WriteAllLinesBetter(string path, params string[] lines) 
    { 
     if (path == null) 
      throw new ArgumentNullException("path"); 
     if (lines == null) 
      throw new ArgumentNullException("lines"); 

     using (var stream = File.OpenWrite(path)) 
     { 
      stream.SetLength(0); 
      using (var writer = new StreamWriter(stream)) 
      { 
       if (lines.Length > 0) 
       { 
        for (var i = 0; i < lines.Length - 1; i++) 
        { 
         writer.WriteLine(lines[i]); 
        } 
        writer.Write(lines[lines.Length - 1]); 
       } 
      } 
     } 
    } 
+0

我也遇到過這個,很好。更改爲'var writer'的榮譽。 – Waescher 2017-09-12 12:45:25