有一个 1G 大的 文本 行文件, 首先我要计出特定行在文件中位置,保存到一个偏移量表文件, 便于后面任意时候打开时可定位取文件块;

以为是一个发展了 30多年的代码早就解决的基本问题(当年在文件流上做过各种定位、分块读),看看老外(很多是10年前写的)这么多的讨论,要解决这个问题, 到现在竟然没有发展出一个基本应用的类来解决 :

https://www.daniweb.com/programming/software-development/threads/35078/streamreader-and-position

http://stackoverflow.com/questions/5404267/streamreader-and-seeking

在 StreamReader.ReadLine 下 StreamReader.Position 和 FileStream.Position 都是读入 1024 大小的 byte, 读入指针如下变化

也就是说, 你根本不可能通过 当前文件位置 FileStream.Position  获得真正的当前文件位置指针, 而且没有任何成熟办法支持你获得这个位置

以上打印结果由如下代码实现:

strLine = sr.ReadLine ();

Debug.Log ("offset = " + sr.BaseStream.Position + " | " + strLine + " | " + strLine.Length);

在网上也看到同样问题 :

使用stream.Seek可以正确定位读取文件某位置上的数据吗..._CSDN论坛 最后也没有答案, 不知道这位兄弟是怎么解决的。

先解决第一问题, 如何可以在文件里定位:

FileStream 打开文件, 通过 Seek 定位后, 要在 StreamRead 里起到定位作用

在看了一堆文档和做了一堆试验, 确认在流里 seek 有效方法 :

无论你是

FileStream.Seek( 10, SeekOrigin.Begin);

还是

StreamReader.BaseStream.Seek (4, SeekOrigin.Begin);

都要重新获取一个流, 才能得到当前文件的正确位置:
sr = new StreamReader (aFile);

也就是说 seek 实质上发生在 FileStream 中, 要用一个新的 Stream 来重新对应, 进行存取;

第二个问题, 如何在读入字串后, 可以得到读出后的真正文件指针位置

如果你用 StreamReader.ReadLine,  如今看是没有 基础方法 的得到真实位置

我的是文本文件,我采用的方法是逐行累加一下, 自己记录一个长度, 第一次没记入回车, 位置得到的不对,

回车的处理处理有一个问题,就是系统是如何处理的, 在老外的文章里有一个办法

如果你是用 ReadLine , 想得到读出长度要加回车长度, 而回车的长度是不定的,

这里  c# - StreamReader and seeking - Stack Overflow  最后一个回答里,给出一个得到回车长度的方法:

intnewLineBytes =System.Environment.NewLine.Length;

经试验不一定对, 我的回车 “x0A"  而这个返回是2个字节;

暂时我只好是 readline  + 1 来得到我自己文件的长度了。

看样子, 还是用 readbyte 来自己写是最终方法

重新设计代码方案: 

关于FileStream读取大文件问题 - YoMe - 博客园

我自己写的记录偏移量的代码如下, 个人可根据不同文件格式来改变位置标志:

    //    voidoyRecordOffset(){using (FileStream fsRead = new FileStream(xPath + "/1014test1.txt",FileMode.Open)) {            //oyOffset.txt   1014test1.txtbyte[] arr = new byte[2000];//记录到底读取了多少字节的数据int count = 0;bool beol = false;long lOffset = 0;int iLines = 0;while (fsRead.Position <fsRead.Length) {//每一次读取,。返回真正读取到的字节数,用count记录(最后一次读取后可能count可能会小于200)count = fsRead.Read (arr, 0, arr.Length);//Debug.Log ("count ===> " + count);for (int i = 0; i < arr.Length; i++, lOffset++) {if (arr [i] == '\x0a') {//一个行尾beol = true;}else{if (arr [i] == '\x0d') {//一个行尾beol = true;}else{if(beol){//Debug.Log (" * line offset => " + lOffset);iLines++;beol= false;} }}if (iLines >= 8000) {arOffset [iFrames]=lOffset; iFrames++;Debug.Log ("* => iFrames" + iFrames + "|" +lOffset);iLines= 0;}}//if(iFrames > 5)//break;//string s = Encoding.ASCII.GetString(arr);//Debug.Log (" => len "+ s.Length + " | " + s);
}Debug.Log ("=> iFrames" +iFrames);}}


另外:对如何正确使用 FileStream.Seek 我进行的测试

FileStream aFile = new FileStream (path + "/oyOffset.txt",FileMode.Open,FileAccess.ReadWrite);

StreamReader sr = new StreamReader (aFile);

....

aFile.Seek( 10, SeekOrigin.Begin);
sr = new StreamReader (aFile);  重新定位后, 要重新打开 stream 才会有效

参考 :关于C#中的StreamReader与FileStream这两个类

转载于:https://www.cnblogs.com/ouyang800/articles/6127819.html

这么多年代码发展, 竟然发现读到一个文件位置竟不容易相关推荐

  1. 如何读到一个文件的最后更新日期和时间

    type   //分别对应文件创建时间,访问时间,修改时间   TFileTimeType = (fttCreation, fttLastAccess, fttLastWrite);     func ...

  2. 我擦!迅雷的代码结构竟然被扒了精光~

    作者:jiawen 链接:juejin.im/post/6890344584078721031 # 背景 之前扒过飞书的源码,从代码设计架构层面里里外外学习一把,飞书还是挺"大方" ...

  3. 卧槽!迅雷的代码结构竟然被扒了精光!

    背景 之前扒过飞书的源码,从代码设计架构层面里里外外学习一把,飞书还是挺 "大方" 的,源码在客户端和网页端都一览无余,不过好像新版本已经看不到了.相关的文章由于在内网技术论坛发过 ...

  4. 大神尝试扒迅雷的代码,竟然被扒了个精光!

    欢迎大家关注 来源:juejin.im/post/6890344584078721031 文末送书5本 背景 之前扒过飞书的源码,从代码设计架构层面里里外外学习一把,飞书还是挺 "大方&qu ...

  5. MFC打开一个文件方法汇总

    第1个回答 CFileDialog  文件选择对话框的使用:首先构造一个对象并提供相应的参数,构造函数原型如下:  CFileDialog::CFileDialog( BOOL bOpenFileDi ...

  6. 对已有文件进行既读又写的操作时关于文件位置注意事项(适用于Python和C/C++)

    当我们需要对现有文件进行读取数据并修改文件中的数据时,就需要用到对已有文件进行既读又写的操作.有多种可读且可写的文件打开方式:r+,w+,a+,rb+,wb+,ab+,具体含义见下表. 打开 方式 读 ...

  7. 输出一个文件的最后n行数据,如果文件总行数不足n行,则显示全部数据

    C程序,功能如题,代码如下: /* 功能:输出一个文件的最后n行数据,如果文件总行数不足n行,则显示全部数据 基本思路:产生一个长度为n的二维数组,将它作为一个循环队列来看待 */ #include ...

  8. 如果表不存在则创建_当创建一个文件的时候,操作系统发生了什么

    操作文件是我们平时经常有的操作.但是我们可能并不是很了解他们原理,比如为什么删除一个很大的文件,会非常快?创建一个文件的时候,系统发生了什么?为什么删除的文件,还可以恢复?知其然知其所以然.我们一起深 ...

  9. python红楼梦人物词频统计_用Python绘制红楼梦词云图,竟然发现了这个!

    原标题:用Python绘制红楼梦词云图,竟然发现了这个! Python在数据分析中越来越受欢迎,已经达到了统计学家对R的喜爱程度,Python的拥护者们当然不会落后于R,开发了一个个好玩的数据分析工具 ...

最新文章

  1. View绘制流程的入口
  2. AR SDK引擎技术选型和使用实现方案
  3. Solr 建立多对多对象索引,检索时只显示了第一条
  4. Flutter开发Flutter与原生OC、Java的交互通信-1(47)
  5. Go进阶(7): JSON 序列化和反序列化
  6. firefox 4b7截图
  7. 让人郁闷的“DesktopCompatible”
  8. C#机器学习之判断日报是否合格
  9. C++学习之路 | PTA乙级—— 1043 输出PATest (20 分)(精简)
  10. Golang入门(1):安装与配置环境变量的意义
  11. 让菜鸟飞上天,简单搞定linux服务器
  12. Docker Hub 将放弃支持客户端 1.5 及以下版本
  13. 190609每日一句,科比·布莱恩特:这就是我成功的原因,即使身陷低谷,也要抬头仰望星空
  14. 投标文件 医院弱电系统_甲级办公楼智能化弱电设计方案适合弱电行业人士学习!...
  15. NetCore Vue前端实现导出功能及解决导出excel表格无法打开的问题
  16. error: exportArchive: No signing certificate “iOS Distribution“ found
  17. 编程及C/C++初学者 FAQ
  18. 企企通采购网“企销通2.0”重磅上线 助力中小企业打通数字化生态
  19. 【C语言】PAT乙级:1007 素数对猜想
  20. 我输就输在,我没想要赢,只想被爱。

热门文章

  1. h3c交换机重启_h3c交换机恢复出厂设置图文教程
  2. 如何从InfluxDB/OpenTSDB无缝连接到TDengine
  3. PCI-SIG 文档 Ncb和cb的区别
  4. Maven 多profile及指定编译问题
  5. 随机森林,随机森林中进行特征重要性
  6. 三国志战略版:如何省出裸衣血战,暴力蜀枪的次级选择
  7. X96 Max Plus sd卡 刷Emuelec
  8. [原创]农村孩子要不要上那些“烂大学”?
  9. 【JAVASE小新】关于静态方法的使用(含打印*长方形例子)
  10. 利用Backtrader进行期权回测之四:Covered Call策略