【问题标题】:Extracting the first 10 lines of a file to a string将文件的前 10 行提取为字符串
【发布时间】:2014-02-23 09:44:39
【问题描述】:
public void get10FirstLines()
{ 
     StreamReader sr = new StreamReader(path);
     String lines = "";
     lines = sr.readLine();
}

如何获取字符串中文件的前 10 行?

【问题讨论】:

  • 你的问题不是很清楚 - 你的方法是调用 skip10Lines 这与 getting 前 10 行到一个字符串不同。也不清楚您是否真的想要单个字符串或列表中的行。
  • 如果这是来自 ypur 真实代码:path 应该是一个参数。

标签: c# streamreader


【解决方案1】:

不要直接使用StreamReader,而是使用返回IEnumerable<string>的File.ReadLines。然后您可以使用 LINQ:

var first10Lines = File.ReadLines(path).Take(10).ToList();

使用File.ReadLines 而不是File.ReadAllLines 的好处是它只 读取您感兴趣的行,而不是读取整个文件。另一方面,它仅在 .NET 4+ 中可用。如果您希望在 .NET 3.5 中使用迭代器块,则很容易实现它。

对ToList() 的调用是为了强制对查询进行评估(即实际读取数据),以便准确读取一次。如果没有ToList 调用,如果您尝试多次迭代first10Lines,它将多次读取该文件(假设它完全有效;我似乎记得File.ReadLines 在尊重)。

如果您希望前 10 行作为 单个 字符串(例如用“\r\n”分隔它们),那么您可以使用string.Join:

var first10Lines = string.Join("\r\n", File.ReadLines(path).Take(10));

显然,您可以通过更改调用中的第一个参数来更改分隔符。

【讨论】:

  • 非常好的解决方案,我建议将它放在可测试性的抽象后面。
【解决方案2】:
var lines = File.ReadAllLines(path).Take(10);

【讨论】:

  • 如果用户读取一个 2 GB(9999 行)的文件并且只想要前 10 行,它会只访问前 10 行吗?
  • @huseyintugrulbuyukisik:不,它会读取所有内容 - 因此我的回答。
  • File.ReadLines() 在这里可能是一个非常大的优化。
  • 谢谢大家的回答。问题是,我需要它在一个字符串中。因为我之后要去 g.drawline() 它。它不能是迭代器。它需要直接进入一个字符串。 String myString = "";
【解决方案3】:

您可以尝试使用File.ReadLines。试试这个:-

var lines = File.ReadLines(path).Take(10);

在您的情况下尝试此操作,因为您希望前 10 行作为单个字符串,因此您可以尝试像这样使用 string.Join():

var myStr= string.Join("", File.ReadLines(path).Take(10));

【讨论】:

  • 应该使用string.Empty而不是""
【解决方案4】:
StringBuilder myString = new StringBuilder();

TextReader sr = new StreamReader(path);

for (int i=0; i < 10; i++)
{
myString.Append(sr.ReadLine())
}

【讨论】:

    【解决方案5】:
    String[] lines = new String[10];
    for (int i = 0; i < 10; i++)
         lines[i] = sr.readLine();
    

    循环十次并将结果放入一个新数组中。

    【讨论】:

      【解决方案6】:
      public void skip10Lines()
      { 
          StringBuilder lines=new StringBuilder();
          using(StreamReader sr = new StreamReader(path))
          {
           String line = "";
           int count=0;
      
            while((line= sr.ReadLine())!=null)
            {
               if(count==10)
                 break;
               lines.Append(line+Environment.NewLine);
               count++;
            }
           }
      
       string myFileData=lines.ToString();
       }
      

      或

      public void skip10Lines()
      { 
           int count=0;
           List<String> lines=new List<String>();
           foreach(var line in File.ReadLines(path))
           {
               if(count==10)
                 break;
               lines.Add(line);
               count++;
           }
       }
      

      【讨论】:

      • 这不会编译(ReadLine,不是readLine),它不会在最后关闭阅读器。
      【解决方案7】:

      原因是嵌套运算符File.ReadLines(path).Take(10).ToList(); 将真正做到以下几点:

      string[] lines = File.ReadLines(path); // reads all lines of the file
      string[] selectedlines = lines.Take(10); // takes first 10 line s into a new array
      List<String> LinesList = selectedlines.ToList();
      

      尤其是第一部分很麻烦,因为它将整个文件读入可枚举的行中。这会消耗性能和内存。问题海报专门针对大文件提出。

      出于这个原因,我宁愿推荐:

      /// <summary>
      /// This function loads and returns the first x lines from a file
      /// </summary>
      /// <param name="path">The path to the file to read</param>
      /// <param name="amountOfLines">the number of lines which should be read</param>
      /// <param name="encoding">optional value, which specifies the format in which the text file is saved</param>
      /// <returns></returns>
      public List<string> GetFirstXLines(string path, int amountOfLines, Encoding encoding = null)
      {
          // if no encoding is set, try the default encoding (File Format)
          if (encoding == null) encoding = Encoding.Default;
          // create list which will be filled with the lines and returned later
          List<string> lines = new List<string>();
          // wrap streamreader around so it gets closed+disposed properly later
          using (StreamReader reader = new StreamReader(path, encoding))
          {
              // loop x times to get the first x lines
              for (int i = 0; i < amountOfLines; i++)
              {
                  // read the next line
                  string line = reader.ReadLine();
                  // if the line is null, we are at the end of file, break out of the loop
                  if (line == null) break;
                  // if the line was not null, add it to the lines list
                  lines.Add(line);
              }
          }
          // return the lines
          return lines;  
      }
      

      【讨论】:

        【解决方案8】:

        在基于 JVM 的语言 Groovy 中,一种方法是:

        def buf = new StringBuilder()
        
        Iterator iter = new File(path).withReader{
            for( int cnt = 0;cnt < 9;cnt++){    
                buf << it.readLine()
            }
        }
        
        println buf
        

        由于闭包没有“中断”,因此循环嵌套在闭包内,因此资源处理由 Groovy 运行时负责。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-27
          • 2011-12-17
          • 2023-03-07
          • 1970-01-01
          • 1970-01-01
          • 2015-05-08
          • 2014-09-23
          • 1970-01-01
          相关资源
          最近更新 更多