2017-06-05 29 views
1

我想問一些關於C#閱讀/寫作部分的提示和幫助。StreamWriter:在特定的行號碼上開始和結束

現狀:

  • 我要讀一個CSV文件; - 確定
  • 如果CSV文件名以「Load_」開頭,我想在另一個CSV上寫入從第2行到最後一個的數據;
  • 如果CSV文件名以「RO_」開頭,我想在2個不同的CSV上寫1,第1行到第4行,其他4到最後一個;

我至今是:

public static void ProcessFile(string[] ProcessFile) 
    { 

     // Keeps track of your current position within a record 
     int wCurrLine = 0; 

     // Number of rows in the file that constitute a record 
     const int LINES_PER_ROW = 1; 
     int ctr = 0; 
     foreach (string filename in ProcessFile) 
     { 

      var sbText = new System.Text.StringBuilder(100000); 
      int stop_line = 0; 
      int start_line = 0; 

      // Used for the output name of the file 
      var dir = Path.GetDirectoryName(filename); 
      var fileName = Path.GetFileNameWithoutExtension(filename); 
      var ext = Path.GetExtension(filename); 
      var folderbefore = Path.GetFullPath(Path.Combine(dir, @"..\")); 


      var lineCount = File.ReadAllLines(@filename).Length; 

      string outputname = folderbefore + "output\\" + fileName; 

      using (StreamReader Reader = new StreamReader(@filename)) 
      { 

       if (filename.Contains("RO_")) 
       { 
        start_line = 1; 
        stop_line = 5; 
       } 
       else 
       { 
        start_line = 2; 
        stop_line = lineCount; 
       } 


       ctr = 0; 
       while (!Reader.EndOfStream && ctr < stop_line) 
       { 
        // Add the text 
        sbText.Append(Reader.ReadLine()); 

        // Increment our current record row counter 
        wCurrLine++; 

        // If we have read all of the rows for this record 
        if (wCurrLine == LINES_PER_ROW) 
        { 
         // Add a line to our buffer 
         sbText.AppendLine(); 
         // And reset our record row count 
         wCurrLine = 0; 
        } 
        ctr++; 


       } // end of the while 
      } 

      int total_lenght = sbText.Length 
      // When all of the data has been loaded, write it to the text box in one fell swoop 
      using (StreamWriter Writer = new StreamWriter(dir + "\\" + "output\\" + fileName + "_out" + ext)) 
      { 
       Writer.Write.(sbText.); 
      } 


     } // end of the foreach 

    } // end of ProcessFile 

我在想使用的if/else:「用(StreamWriter的作家=新的StreamWriter(DIR + 「\」 + 「輸出\」 + fileName +「_out」+ ext))「part。但是,我不確定如何將它傳遞給StreamWriter,只能從/到特定行號進行寫入。

任何幫助,歡迎!如果我錯過了一些信息,請告訴我(我在stackoverflow上很新)。

謝謝。

回答

0

代碼是太複雜

using System.Collections.ObjectModel; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 


namespace ConsoleApplication57 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 



     } 
     public static void ProcessFile(string[] ProcessFile) 
     { 
      foreach (string filename in ProcessFile) 
      { 

       // Used for the output name of the file 
       var dir = Path.GetDirectoryName(filename); 
       var fileName = Path.GetFileNameWithoutExtension(filename); 
       var ext = Path.GetExtension(filename); 
       var folderbefore = Path.GetFullPath(Path.Combine(dir, @"..\")); 


       var lineCount = File.ReadAllLines(@filename).Length; 

       string outputname = folderbefore + "output\\" + fileName; 

       using (StreamWriter Writer = new StreamWriter(dir + "\\" + "output\\" + fileName + "_out" + ext)) 
       { 

        int rowCount = 0; 
        using (StreamReader Reader = new StreamReader(@filename)) 
        { 
         rowCount++; 
         string inputLine = ""; 
         while ((inputLine = Reader.ReadLine()) != null) 
         { 

          if (filename.Contains("RO_")) 
          { 
           if (rowCount <= 4) 
           { 
            Writer.WriteLine(inputLine); 
           } 
           if (rowCount == 4) break; 
          } 
          else 
          { 
           if (rowCount >= 2) 
           { 
            Writer.WriteLine(inputLine); 
           } 
          } 

         } // end of the while 
         Writer.Flush(); 
        } 
       } 

      } // end of the foreach 

     } // end of ProcessFile 

    } 




} 
0

您可以使用LINQ到TakeSkip線。

public abstract class CsvProcessor 
{ 
    private readonly IEnumerable<string> processFiles; 

    public CsvProcessor(IEnumerable<string> processFiles) 
    { 
     this.processFiles = processFiles; 
    } 

    protected virtual IEnumerable<string> GetAllLinesFromFile(string fileName) 
    { 
     using(var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using(var reader = new StreamReader()) 
     { 
      var line = String.Empty; 
      while((line = reader.ReadLine()) != null) 
      { 
       yield return line; 
      } 
     } 
    } 

    protected virtual void ProcessFiles() 
    { 
     var sb1 = new StringBuilder(); 
     var sb2 = new StringBuilder(); 

     foreach(var file in this.processFiles) 
     { 
      var fileName = Path.GetFileNameWithoutExtension(file); 
      var lines = GetAllLinesFromFile(file); 

      if(fileName.StartsWith("RO_", StringComparison.InvariantCultureIgnoreCase)) 
      { 
       sb1.AppendLine(lines.Take(4)); //take only the first four lines 
       sb2.AppendLine(lines.Skip(4).TakeWhile(s => !String.IsNullOrEmpty(s))); //skip the first four lines, take everything else 
      } 
      else if(fileName.StartsWith("Load_", StringComparison.InvariantCultureIgnoreCase) 
      { 
       sb2.AppendLine(lines.Skip(1).TakeWhile(s => !String.IsNullOrEmpty(s))); 
      } 
     } 

     // now write your StringBuilder objects to file... 
    } 

    protected virtual void WriteFile(StringBuilder sb1, StringBuilder sb2) 
    { 
     // ... etc.. 
    } 
}