在特定行读取文本文件

我有一个超过3000行的文本文件。 我找到了使用的行数

string[] lines = File.ReadAllLines(myPath); var lineCount = lines.Length; 

然后我生成一个随机数

 Random rand = new Random(); var lineToRead = rand.Next(1, lineCount); 

现在我需要读取由随机数生成的特定行。 我可以这样做

 string requiredLine = lines[lineToRead]; 

因为我的文件很大,我不认为创建这么大的数组是有效的。 是否有更有效或更简单的方法来做到这一点?

这是一个迭代文件两次的解决方案(第一次计算行,下次选择行)。 好处是您不需要在内存中创建3000个字符串的数组。 但是,如上所述,它可能会更慢。 为什么可能? – 因为File.ReadAllLines创建了一个字符串列表,并且该列表将在填充3000个项目时多次resize。 (初始容量将为4当内部数组完全填充时,将创建新的双倍大小数组,并在那里复制所有字符串)。

因此,该解决方案使用File.ReadLines方法,该方法使用行返回IEnumerable并跳过您不需要的行:

 IEnumerable lines = File.ReadLines(myPath); var lineToRead = rand.Next(1, lines.Count()); var line = lines.Skip(lineToRead - 1).First(); 

BTW,内部File.ReadLines使用SteamReader读取文件。

您可以做的是解析文件以查找每行的索引,然后稍后您可以使用Stream.Position返回到某一行来获取内容。 使用此方法,您无需在内存中保留任何内容,而且速度相当快。 我在一个20K行和1MB大小的文件上测试了这个 。 索引文件需要7毫秒,获得该行需要0.3。

  // Parse the file var indexes = new List(); using (var fs = File.OpenRead("text.txt")) { indexes.Add(fs.Position); int chr; while ((chr = fs.ReadByte()) != -1) { if (chr == '\n') { indexes.Add(fs.Position); } } } int lineCount = indexes.Count; int randLineNum = new Random().Next(0, lineCount - 1); string lineContent = ""; // Read the random line using (var fs = File.OpenRead("text.txt")) { fs.Position = indexes[randLineNum]; using (var sr = new StreamReader(fs)) { lineContent = sr.ReadLine(); } } 

您可以将流包装到StreamReader中并根据需要多次调用ReadLine以转到目标行。 这样您就不需要将整个文件内容保存在内存中。

但是,这只有在您很少这样做且文件非常大的情况下才可行。

使用水库采样可以一次性解决这个问题

如果要从事先未知该列表长度的项目列表中随机选择一个或多个项目,则可以使用“ 储层采样” 。

我们可以利用它,以及File.ReadLines()方法(避免缓冲内存中的所有行)来编写单遍算法,该算法只读取每一行,而不进行缓冲。

下面的示例代码显示了一个通用解决方案,可让您随机选择任意数量的行。 对于您的情况,N = 1。

示例代码还包括一个测试程序,用于certificate线条是随机选择的,具有均匀分布。

(要了解此代码的工作原理,请参阅上面链接的Wiki文章。)

 using System; using System.IO; using System.Collections.Generic; namespace Demo { internal class Program { public static List RandomlyChooseLinesFromFile(string filename, int n, Random rng) { var result = new List(n); int index = 0; foreach (var line in File.ReadLines(filename)) { if (index < n) { result.Add(line); } else { int r = rng.Next(0, index + 1); if (r < n) result[r] = line; } ++index; } return result; } // Test RandomlyChooseLinesFromFile() private static void Main(string[] args) { Directory.CreateDirectory("C:\\TEST"); string testfile = "C:\\TEST\\TESTFILE.TXT"; File.WriteAllText(testfile, "0\n1\n2\n3\n4\n5\n6\n7\n8\n9"); var rng = new Random(); int trials = 100000; var counts = new int[10]; for (int i = 0; i < trials; ++i) { string line = RandomlyChooseLinesFromFile(testfile, 1, rng)[0]; int index = int.Parse(line); ++counts[index]; } // If this algorithm is correct, each line should be chosen // approximately 10% of the times. Console.WriteLine("% times each line was chosen:\n"); for (int i = 0; i < 10; ++i) { Console.WriteLine("{0} = {1}%", i, 100*counts[i]/(double)trials); } } } } 

下面将帮助您阅读文件中的特定行。

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/4dbd68f6-61f5-4d36-bfa0-5c909101874b

代码snipet

 using System; using System.Collections.Generic; using System.Text; using System.IO; namespace ReadLine { class Program { static void Main(string[] args) { //Load our text file TextReader tr = new StreamReader("\\test.txt"); //How many lines should be loaded? int NumberOfLines = 15; //Make our array for each line string[] ListLines = new string[NumberOfLines]; //Read the number of lines and put them in the array for (int i = 1; i < NumberOfLines; i++) { ListLines[i] = tr.ReadLine(); } //This will write the 5th line into the console Console.WriteLine(ListLines[5]); //This will write the 1st line into the console Console.WriteLine(ListLines[1]); Console.ReadLine(); // close the stream tr.Close(); } } } 

这些也有帮助..

http://www.tek-tips.com/viewthread.cfm?qid=1460456

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

以下是编辑

在C#中编辑文本文件的特定行

希望能帮助到你...

你可以尝试下面的…它不能创建任何大arrays,但得到一个特定的线…

 string path = "D:\\Software.txt"; int lines = File.ReadAllLines(path).Length; Random rand = new Random(); var lineToRead = rand.Next(1, lines); var requiredLine = System.IO.File.ReadLines(path).Skip(lineToRead - 1).First(); Console.WriteLine(requiredLine.ToString());