简体   繁体   English

StreamWriter只写一行

[英]StreamWriter only writes one line

I am trying to write from a .csv file to a new file. 我正在尝试从.csv文件写入新文件。

Every time StreamWriter writes, it writes to the first line of the new file. 每次StreamWriter写入时,它都会写入新文件的第一行。 It then overwrites that line with the next string, and continues to do so until StreamReader reaches EndOfStream . 然后,它用下一个字符串覆盖该行,并继续这样做,直到StreamReader到达EndOfStream
Has anybody ever experienced this? 有人经历过吗? How did you overcome it? 您是如何克服它的?

This is my first solution outside of those required in by my school work. 这是我学校工作所要求的解决方案之外的第一个解决方案。 There is an unknown number of rows in the original file. 原始文件中的行数未知。 Each row of the .csv file has only 17 columns. .csv文件的每一行只有17列。 I need to write only three of them and in the order found in the code snippet below. 我只需要按照下面的代码片段中的顺序编写其中的三个即可。
Before coding the StreamWriter I used Console.WriteLine() to make sure that each line was in the correct order. 在编码StreamWriter之前,我使用Console.WriteLine()来确保每一行的顺序正确。

Here is the code snippet: 这是代码片段:

{
    string path = @ "c:\directory\file.csv";
    string newPath = @ "c:\directory\newFile.csv"

    using(FileStream fs = new FileStream(path, FileMode.Open))
    {
        using(StreamReader sr = new StreamReader(fs))
        {
            string line;
            string[] columns;
            while ((line = sr.ReadLine()) != null)
            {
                columns = line.Split(',');
                using(FileStream aFStream = new FileStream(
                    newPath, 
                    FileMode.OpenOrCreate, 
                    FileAccess.ReadWrite))
                using(StreamWriter sw = new StreamWriter(aFStream))
                {
                    sw.WriteLine(columns[13] + ',' + columns[10] + ',' + columns[16]);
                    sw.Flush();
                    sw.WriteLine(sw.NewLine);
                }
            }
        }
    }
}

You should open the target in the same scope as you are opening the source instead of doing so in the loop which will cause you to overwrite the file every time with the FileMode option OpenOrCreate . 您应该在与打开源相同的范围内打开目标,而不是在循环中打开目标,这将导致您每次使用FileMode选项OpenOrCreate覆盖文件。

var path = @"c:\directory\file.csv";
var newPath = @"c:\directory\newFile.csv"

using(var sr = new StreamReader(new FileStream(path, FileMode.Open)))
using(var sw = new StreamWriter(new FileStream(newPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)))
{
    while(!sr.EndOfStream)
    {
        string line = sr.ReadLine();
        var columns = line.Split(',');
        sw.WriteLine(columns[13] + ',' + columns[10] + ',' + columns[16]);
        sw.WriteLine(sw.NewLine);
    }
    sw.Flush();
}

I also hope you are sure about your CSV spacing as you are hard coding the positions in your code. 我也希望您能确定自己的CSV间距,因为您正在对代码中的位置进行硬编码。

First off, you are creating and closing a write stream to the same file for every single line. 首先,您正在为每一行创建并关闭到同一文件的写流。 This means the file gets overwritten every line. 这意味着文件被每一行覆盖。 You want to take your using block outside of the while loop; 您希望将using块放在while循环之外; however, if you insist on opening and closing the write stream for every single line, then you need to use FileMode.Append 但是,如果您坚持要打开和关闭每一行的写流,则需要使用FileMode.Append

{
  string path=@"c:\directory\file.csv";
  string newPath=@"c:\directory\newFile.csv"
  using(StreamReader sr = new StreamReader(new FileStream(path, FileMode.Open))) // no need for 2 usings
  using (FileStream aFStream = new FileStream (newPath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
  {
    string line;
    string[] columns;
    {
      while((line = sr.ReadLine()) != null)
      {
        columns = line.Split(',');
        using (StreamWriter sw = new StreamWriter(aFStream))
        {
          sw.WriteLine(columns[13] + ',' + columns[10] + ',' + columns[16]);
          sw.Flush();
          sw.WriteLine(sw.NewLine);
        }
      }
    }
  }
}

To correctly fix your code, you'll want to structure more: 为了正确地修复您的代码,您将需要构建更多结构:

public void CopyFileContentToLog()
{
     var document = ReadByLine();
     WriteToFile(document);
}

public IEnumerable<string> ReadByLine()
{
     string line;
     using(StreamReader reader = File.OpenText(...))
          while ((line = reader.ReadLine()) != null)
              yield return line;
}

public void WriteToFile(IEnumerable<string> contents)
{
     using(StreamWriter writer = new StreamWriter(...))
     {
          foreach(var line in contents)
              writer.WriteLine(line);

          writer.Flush();
     }
}

You could obviously tailor and make it a bit more flexible. 您显然可以进行剪裁,使其更加灵活。 But this should demonstrate and resolve some of the issues you have with your loop and streams. 但这应该演示并解决您的循环和流问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM