C# 如何读取文本文件中的指定行?

C# 如何读取文本文件中的指定行?,c#,string,file-io,input,C#,String,File Io,Input,给定一个文本文件,如何读取任意一行而不读取文件中的其他内容 比如说,我有一个文件test.txt。我如何阅读文件中的第15行 我所看到的只是将整个文本文件存储为字符串数组,然后使用行号的值作为要从数组中使用的字符串的编号。。。但也有一些复杂之处:文本文件非常庞大,而我正在编写的应用程序所使用的机器并不是一个一流的系统。速度不是最重要的,但绝对是个大问题 是否有任何方法可以仅读取文本文件的特定行并将结果存储为字符串 感谢您的回复: 这个文件有点结构化。它有25行信息,然后是X行数字,但前25行的第

给定一个文本文件,如何读取任意一行而不读取文件中的其他内容

比如说,我有一个文件test.txt。我如何阅读文件中的第15行

我所看到的只是将整个文本文件存储为字符串数组,然后使用行号的值作为要从数组中使用的字符串的编号。。。但也有一些复杂之处:文本文件非常庞大,而我正在编写的应用程序所使用的机器并不是一个一流的系统。速度不是最重要的,但绝对是个大问题

是否有任何方法可以读取文本文件的特定行并将结果存储为字符串

感谢您的回复: 这个文件有点结构化。它有25行信息,然后是X行数字,但前25行的第17行的值是X

但是,这里有一个空行,它作为文件中的第二条记录在整个文件中重复,X可以为每条记录指定不同的值

我要做的是读取并存储前25行作为独立值,然后将下一个X(通常约250)行作为数组存储。然后,我将把它存储在SQL数据库中,并对下一条记录进行重复,直到到达Yth记录(文件中的记录数在第3行)

编辑2: 好吧,我想我已经找到了一个基于你的ALL反应组合的解决方案

我将读取前25行并将其存储为数组。我将把数组的相关内容复制到局部变量,然后删除前25行。然后,我可以使用该信息将接下来的X行(数组中第13项的值)存储为数组,将其序列化,存储在数据库中,然后删除我刚才读取的行

然后,我可以为每个后续记录重复该过程


当然,这取决于我的一个假设,老实说,我不确定这是真的。是否可以从C#中删除文本文件的前n行,而不必读取整个内容,并在没有前n行的情况下重新写入?

.NET 4.0 edit

自.NET4.0以来,可以直接访问文件的一行。例如,要访问第15行:

string line = File.ReadLines(FileName).Skip(14).Take(1).First();
这将只返回所需的行


由于您无法预测文件中第i行的位置(可以吗?),因此您也必须阅读前面的所有行。如果行号很小,这可能比
ReadAllLines
方法更有效

string GetLine(string fileName, int line)
{
   using (var sr = new StreamReader(fileName)) {
       for (int i = 1; i < line; i++)
          sr.ReadLine();
       return sr.ReadLine();
   }
}
string GetLine(字符串文件名,int行)
{
使用(var sr=newstreamreader(文件名)){
对于(int i=1;i
除非你有固定大小的行,否则你需要阅读每一行,直到你到达你想要的行。虽然,您不需要存储每一行,但如果它不是您想要的行,就丢弃它

编辑:


如前所述,如果行长度是可预测的,也可以在文件中查找,也就是说,您可以应用一些确定性函数将行号转换为文件位置。

您可以逐行读取,这样您就不必一次读取整个行(可能根本不需要)


不,不幸的是没有。在原始级别,文件不以行号为基础工作。相反,它们在位置/偏移基础上工作。根文件系统没有行的概念。这是由更高级别的组件添加的概念


所以没有办法告诉操作系统,请在第行打开文件。相反,您必须打开文件并跳过计算新行数,直到超过指定的数字。然后将下一组字节存储到数组中,直到到达下一新行

如果每行都是固定长度的,那么您可以在其周围打开一个流,在文件中查找(每行字节)*n,然后从那里读取您的行

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin);
    using( StreamReader reader = new StreamReader(stream) )
    {
        string line = reader.ReadLine();
    }
}
或者,您可以使用StreamReader来阅读行,直到找到所需的行。这样读起来比较慢,但还是比读每一行要好

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    using( StreamReader reader = new StreamReader(fileStream) )
    {
        string line = null;
        for( int i = 0; i < myLineNumber; ++i )
        {
            line = reader.ReadLine();
        }
    }
}
使用(Stream=File.Open(fileName,FileMode.Open))
{
使用(StreamReader=newstreamreader(fileStream))
{
字符串行=null;
对于(int i=0;i
正如Mehrdad所说,如果不读取文件,就不能只查找第n行。 但是,您不需要将整个文件存储在内存中,只需丢弃不需要的数据即可

string line;
using (StreamReader sr = new StreamReader(path))
    for (int i = 0; i<15; i++)
    {
       line = sr.ReadLine();
       if (line==null) break; // there are less than 15 lines in the file
    }
字符串行;
使用(StreamReader sr=新StreamReader(路径))

对于(int i=0;i如果线都是固定长度的,则可以使用流的Seek方法移动到正确的起始位置

如果线的长度可变,则您的选项将更加有限

如果这是一个只使用一次然后丢弃的文件,那么最好在Memory中读取并使用它


如果这是一个您将保留的文件,并且将从中读取而不是写入,则可以创建一个自定义索引文件,其中包含每行的起始位置。然后使用该索引获取搜索位置。创建索引文件的过程需要大量资源。每次向文件添加新行时,您都需要更新索引,因此维护成为一个非常重要的问题。

如果您的文件包含不同长度的行,并且您需要经常读取行,并且需要快速读取,您可以通过读取一次来创建文件的索引,保存每一新行的位置,然后当您需要读取行时,只需在您的文件中查找行的位置即可r索引,在那里搜索,然后你读这行

如果向文件中添加新行,则只需添加新行的索引,而无需重新索引
string line;
using (StreamReader sr = new StreamReader(path))
    for (int i = 0; i<15; i++)
    {
       line = sr.ReadLine();
       if (line==null) break; // there are less than 15 lines in the file
    }
string line15 = ReadLine(@"C:\File.csv", 15);

public string ReadLine(string FilePath, int LineNumber){
    string result = "";
    try{
    if( File.Exists(FilePath) ){
        using (StreamReader _StreamReader = new StreamReader(FilePath)){
        for (int a = 0; a < LineNumber; a++) {
            result = _StreamReader.ReadLine();
        }
        }
    }
    }catch{}
    return result;
}
        String str1 = @"C:\Users\TEMP\Desktop\StaN.txt";   

        System.IO.StreamReader file = new System.IO.StreamReader(str1);

        line = file.ReadLine();

        Int32 ctn=0;

        try
        {

            while ((line = file.ReadLine()) != null)
            {

                    if (Counter == ctn)
                    {
                        MessageBox.Show("I am here");
                        ctn=ctn+5;
                        continue;
                    }
                    else
                    {
                        Counter++;
                        //MessageBox.Show(Counter.ToString());
                        MessageBox.Show(line.ToString());
                    } 
                }

            file.Close();
        }
        catch (Exception er)
        {

        }
        if (File.Exists(fpath))
        {

            var data = File.ReadLines(fpath);
            Console.WriteLine(data.ToArray()[14]);
        }
string line = File.ReadLines(filePath).ElementAt(actualLineNumber - 1);
string GetLine(string fileName, int lineNum)
{
    using (StreamReader sr = new StreamReader(fileName))
    {
        string line;
        int count = 1;
        while ((line = sr.ReadLine()) != null)
        {
            if(count == lineNum)
            {
                return line;
            }
            count++;
        }
    }
    return "line number is bigger than number of lines";  
}