StreamWriter:以特定行号开始和结束

时间:2017-06-05 13:59:39

标签: c#

我想在C#的阅读/写作部分提出一些提示和帮助。

情况:

  • 我必须阅读CSV文件; - 好的
  • 如果CSV文件名以“Load_”开头,我想在另一个CSV上写入第2行到最后一行的数据;
  • 如果CSV文件名以“RO_”开头,我想写两个不同的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 Writer = new StreamWriter(dir +”\“+”output \“+ fileName +”_ out“+ ext))”part。但是,我不知道如何传递给StreamWriter,只能从/向特定的行号写入。

欢迎任何帮助!如果我遗漏了一些信息,请告诉我(我在stackoverflow上很新)。

谢谢。

2 个答案:

答案 0 :(得分: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  

    }




}

答案 1 :(得分: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..
    }
}