删除csv文件中的多行

时间:2017-06-22 09:11:45

标签: c# csv

我有一个大型的csv文件记录,我想要删除,直到更接近当前日期取决于我提供的输入。

目标:
*最小化我的csv日志文件的内容 *如果找不到所选择的日期,请通过再次写入文件来保留整个日志(因为据我所知,如果我们正在做某事,我们会一次又一次地阅读它。)

表单:
我有一个包含浏览按钮的表单和一个名为“txtfilename”的文本框(在此处显示目录)。 Datagridview查看我的csv文件。 Datetimepicker是我可以选择日期。在选择日期之前删除多行的一个按钮。

代码任务:
使用streamreader读取整行。 “如果”条件评估是否已找到所选日期并打破该行。 Streamwriter写出其余的行。注意!在阅读它时,包括要删除的标题,所以我再次使用了一个带有其余行的临时文件的编写器,并在行的开头插入一个标题。

代码错误:
*如果我再次选择过滤后的文件。错误说:进程无法访问该文件,因为它正由另一个进程使用。

缺乏代码:
*如何关闭streamreader。
*如果读者不能遇到datetimepicker给出的日期,如何再写整行。

示例csv文件:

“EmployeeCode”, “日期”, “时间”, “类型”
“3434”, “2013年1月22日”, “7时54分”, “0”
“3023”, “2013年1月23日”, “7时54分”, “0”
..... ..... ..... ..... ..... ..... ..... ..... ..... “4863”, “2017年1月26日”, “7时55”, “0”
“2513”, “2017年1月28日”, “7时55”, “0”
“2582”, “2017年1月29日”, “7时55”, “0”

  private void button11_Click(object sender, EventArgs e)
  {
    String line = null;

    String tempFile = Path.GetTempFileName();          

    using (StreamReader reader = new StreamReader(txtFileName.Text))
    {
      using (StreamWriter writer = new StreamWriter(tempFile))
      {
       while ((line = reader.ReadLine()) != null)
       {
         if (line.Contains(dateTimePicker1.Text)) //reading if the line contains the date by datetimepicker.
         { 
           writer.WriteLine("\"EmployeeCode\",\"Date\",\"Time\",\"Type\"");

           writer.WriteLine(line); 

           break; // stop reading the line if it encounter the given date.
         }                       
       }   
    //writing the lines after the break                 
       while ((line = reader.ReadLine()) != null)
       {
         writer.WriteLine(line);
       }                  
      }            
    }
      if (File.Exists(tempFile))
       {
         File.Delete(txtFileName.Text);  
         File.Move(tempFile, txtFileName.Text);
       }
        string tempfile = Path.GetTempFileName();
        using (var writer = new StreamWriter(tempfile))
        using (var reader = new StreamReader(txtFileName.Text))
        {
            writer.WriteLine("\"EmployeeCode\",\"Date\",\"Time\",\"Type\"");
            while (!reader.EndOfStream)
            writer.WriteLine(reader.ReadLine());
        }
        File.Copy(tempfile, txtFileName.Text, true);     
        //reload the datagridview   
        Import();

        Application.DoEvents();
  }

上面的代码正在运行,但需要改进我上述陈述的基础。

注意!一个文件名处理 - 使用TempFile。

1 个答案:

答案 0 :(得分:2)

我建议删除ReadersWritersStreams,但使用File类;类似的东西:

   private static void ProcessLog(string sourceFileName, 
                                  string targetFileName, 
                                  string textToFind) {   
     // Do nothing if "file contains the date given by DateTimePicker"
     if (File
          .ReadLines(fileName)
          .Any(line => line.Contains(textToFind))) 
       return;

     // "Write again the whole file" ( == copy it ?)
     File.Copy(sourceFileName, targetFileName, true);
   }

   private void button11_Click(object sender, EventArgs e) {
     ProcessLog(txtFileName.Text, Path.GetTempFileName(), dateTimePicker1.Text);

     ...
   }

修改:如果我误解了你,你实际上想要在第一个DateTimePicker的日期出现之前跳过所有行,然后写下休息线(参见Chris的评论):

   private static void ProcessLog(string sourceFileName, 
                                  string targetFileName, 
                                  string textToFind) {   
     File
       .WriteAllLines(targetFileName, File
         .ReadLines(sourceFileName)
         .SkipWhile(line => !line.Contains(textToFind)));
   }