2011-05-06 35 views
0

我有幾種方法,每個應用的操作的一個文本,在接下來的操作需要輸入以前的操作結果:使用多個文件搜索迭代一個MemoryStream的

private TextReader input = new StreamReader("input.txt"); 
private TextWriter output = new StreamWriter("output.txt"); 
MemoryStream result_1 = new MemoryStream(); 
MemoryStream result_2 = new MemoryStream(); 

Operation_1(input, ref result_1); 
Operation_2(result_1, ref result_2); 
Operation_3(result_2, output); 

代碼爲Operation_1:

private void Operation_1(TextReader input, ref MemoryStream output) 
    { 
     TextWriter outputWriter = new StreamWriter(output); 
     String line; 

     while (input.Peek() >= 0) //while not end of file 
     { 
      line = input.ReadLine(); 
      //perform operation on line 
      outputWriter.writeline(line); 
     } 
     input.Close(); 
    } 

爲operation_2的代碼:

private void Operation_2(TextReader input, ref MemoryStream output) 
    { 
     input.Seek(0, SeekOrigin.Begin); //reset stream to start of file 
     TextReader inputReader = new StreamReader(input); 
     TextWriter outputWriter = new StreamWriter(output); 
     String line; 

     while (inputReader.Peek() >= 0) //while not end of file 
     { 
      line = inputReader.ReadLine(); 
      //perform operation on line 
      outputWriter.writeline(line); 
     } 
     inputReader.Close(); 
    } 

operation_3的代碼:

private void operation_3(MemoryStream input, TextWriter output) 
    { 
     input.Seek(0, SeekOrigin.Begin); //reset stream to start of file 
     TextReader inputReader = new StreamReader(input); 
     String line; 

     while (inputReader.Peek() >= 0) //while not end of file 
     { 
      line = inputReader.ReadLine(); 
      //perform operation on line 
      output.writeline(line); 
     } 
     inputReader.Close(); 
     output.Close(); 
    } 

現在的問題是,我沒有得到相同的結果,每個中間結果存儲到在硬盤的物理txt文件,並使用下一個操作該文件。幾行和文件的末尾丟失。

此外,這似乎不是一個非常乾淨和通用的方式來做到這一點。

因此,我的問題;爲什麼當使用MemoryStream獲得中間結果時,結果會有所不同,並且是否有更乾淨,更靈活的方法? (我想努力尋找解決方案,如果您想要保存中間結果,可以選擇)。

回答

1
  • 他們是不同的,因爲你忘了沖洗你的作家。不需要
  • ref改性劑,因爲你不創建一個在您操作的新MemoryStream

你的方法會有點這種方式清潔:

private void Operation_1(TextReader input, Stream output) 
{ 
    TextWriter outputWriter = new StreamWriter(output); 
    String line; 

    outputWriter.Write(input.ReadToEnd()); 
    outputWriter.Flush(); 

    input.Close(); 
} 

private void Operation_2(Stream input, Stream output) 
{ 
    input.Seek(0, SeekOrigin.Begin); //reset stream to start of file 
    TextReader inputReader = new StreamReader(input); 
    TextWriter outputWriter = new StreamWriter(output); 

    outputWriter.Write(inputReader.ReadToEnd()); 
    outputWriter.Flush(); 
    inputReader.Close(); 
} 

爲operation_3的代碼:

private void operation_3(Stream input, TextWriter output) 
{ 
    input.Seek(0, SeekOrigin.Begin); //reset stream to start of file 
    TextReader inputReader = new StreamReader(input); 

    output.Write(inputReader.ReadToEnd()); 

    inputReader.Close(); 
    output.Flush(); 
    output.Close(); 
} 
+0

啊事實上,.flush()工作:d輸出是現在一樣只用TextWriters :) 所以不可能只使用一個MemoryStream的代碼? – user741317 2011-05-06 08:45:44

+0

這當然是可以的。但是很難告訴你如何去做,因爲你的代碼沒有任何意義。 Operation_2採用兩個MemoryStream,將輸入內容複製到輸出流。如果您只想使用一個MemoryStream,則可以完全跳過此方法。 – 2011-05-06 08:50:19

+0

嗯,實際上我修改了很多輸入行,但是我把這部分留給了我,因爲我認爲這與我的問題無關,只會掩蓋真正的問題。無論如何,對於Operation_2來說,這意味着我會從流中讀取一行,對其進行更改,然後將其寫回到同一個流中。當我這樣說的時候,看起來有點不可能 – user741317 2011-05-06 08:56:26

0

我有一個建議更改您的代碼。也許不用Streams和TextReaders,你可以使用IEnumerable。

請參考下面的樣本(這只是一個樣本。處理不包括在內,以保持樣品簡單的錯誤。)

前面操作的結果被作爲參數傳遞給下一個提供。因此,執行如下操作3(操作2(操作1)))。

下面的第一個示例是讀取並更改文件行中包含的行,行 第二個示例讀取整個文件並更改提供所有行到下一個操作的行(lines.ToArray()讀取整個文件)。

對於流,您總是必須小心,它們在正確的時間和期望的時間處理(例如StreamReader在處理StreamReader時默認關閉內部流)。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Globalization; 
using System.Linq; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main() 
     { 
      //line per line... 
      File.WriteAllLines 
       (
        @"C:\temp\output.txt", 
        ChangeLines(File.ReadLines(@"C:\temp\input.txt"), 
           line => 
           LineOperation3 
            (
             LineOperation2 
              (
               LineOperation1(line) 
              ) 
            ) 
         ) 
       ); 

      //lines per lines... 
      File.WriteAllLines 
       (
        @"C:\temp\output2WithCount.txt", 
        ChangeLines(File.ReadLines(@"C:\temp\input.txt"), 
           lines => 
             LinesCountOperation 
             (
              LinesCountOperation 
              (
               LinesCountOperation(lines,LineOperation1), 
               LineOperation2 
              ) 
              , LineOperation3 
             ) 
         ) 
       ); 
     } 

     private static IEnumerable<string> ChangeLines(IEnumerable<string> lines, Func<string, string> lineFunc) 
     { 
      foreach (var line in lines) 
      { 
       yield return lineFunc(line); 
      } 
     } 

     private static IEnumerable<string> ChangeLines(IEnumerable<string> lines, Func<IEnumerable<string>, IEnumerable<string>> linesFunc) 
     { 
      foreach(var changedLine in linesFunc(lines)) 
      { 
       if (changedLine != null) 
       { 
        yield return changedLine; 
       } 
      } 
     } 

     private static IEnumerable<string> LinesCountOperation(IEnumerable<string> lines, Func<string, string> lineFunc) 
     { 
      var readAllLines = lines.ToArray(); 
      var linesCount = readAllLines.Count(); 

      foreach (var line in readAllLines) 
      { 
       var changedLine = lineFunc(line); 
       if (changedLine == null) 
       { 
        continue; 
       } 
       yield return string.Format(CultureInfo.InvariantCulture, "{0}-{1}", linesCount, changedLine); 
      } 
     } 

     private static string LineOperation1(string line) 
     { 
      return string.Format(CultureInfo.InvariantCulture, "{0}{1}", line, "1"); 
     } 

     private static string LineOperation2(string line) 
     { 
      return string.Format(CultureInfo.InvariantCulture, "{0}{1}", line, "2"); 
     } 

     private static string LineOperation3(string line) 
     { 
      return string.Format(CultureInfo.InvariantCulture, "{0}{1}", line, "3"); 
     } 
    } 
}