当前位置: 首页 > 编程语言 > C#

超大文件如何分词?分享

时间:2023-04-10 13:22:49 C#

一个巨大的文件如何拆分成单词?如何从文本文件中读取一个很长的字符串然后对其进行处理(拆分成单词)?我尝试了StreamReader.ReadLine()方法,但出现了OutOfMemoryexception。显然,我的台词非常长。这是我读取文件的代码:using(varstreamReader=File.OpenText(_filePath)){intlineNumber=1;字符串currentString=String.Empty;while((currentString=streamReader.ReadLine())!=null){ProcessString(currentString,lineNumber);Console.WriteLine("第{0}行",lineNumber);行号++;}}以及将行拆分为单词的代码:varwordPattern=@"w+";varmatchCollection=Regex.Matches(text,wordPattern);varwords=(fromMatchwordinmatchCollectionselectword.Value.ToLowerInvariant()).ToList();您可以按字符读取,随意构建单词,使用yield来延迟它,这样您就不必立即读取它获取整个文件:privatestaticIEnumerableReadWords(stringfilename){using(varreader=newStreamReader(filename)){varbuilder=newStringBuilder();while(!reader.EndOfStream){charc=(char)reader.Read();//模仿正则表达式/w/-差不多。if(char.IsLetterOrDigit(c)||c=='_'){builder.Append(c);}else{if(builder.Length>0){yieldreturnbuilder.ToString();建造者.清除();}}}yieldreturnbuilder.ToString();}}逐字编码字符,当遇到非单词字符时,它会yield返回构建到该点的单词(仅针对第一个非字母字符)代码使用StringBuilder构建单词字符串。Char.IsLetterOrDigit()的行为类似于字符的正则表达式字符w,但下划线(以及其他)也属于后一类。如果您的输入包含的字符比您希望的多,您将不得不更改if()。把它切成小块。因此,与其尝试读取4gb,我假设这是一个页面的大小,不如尝试读取8500mb块,这应该会有所帮助。垃圾收集可能是一种解决方案。我不确定这是问题的根源。但如果是这样的话,一个简单的GC.Collect通常效率不高,出于性能原因,它应该只在真正需要时调用。当可用内存太低(低于作为过程参数提供的阈值)时,请尝试以下过程调用垃圾。以上就是C#学习教程:超大文件如何分词?所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注—intcharReadSinceLastMemCheck=0;使用(varstreamReader=File.OpenText(_filePath)){intlineNumber=1;字符串currentString=String.Empty;while((currentString=streamReader.ReadLine())!=null){ProcessString(currentString,lineNumber);Console.WriteLine("第{0}行",lineNumber);行号++;totalRead+=currentString.Length;if(charReadSinceLastMemCheck>1000000){//检查每读取Mb剩余的内存,并在需要时收集垃圾CollectGarbage(100);charReadSinceLastMemCheck=0;}}}internalstaticvoidCollectGarbage(intSizeToAllocateInMo){long[,]{TheArray=newlong[SizeToAllocateInMo,125000];}低函数捕获{TheArray=null;GC.收集();GC.WaitForPendingFinalizers();GC.收集();}TheArray=null;代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: