那位高手在WINCE下处理20M左右文本文件的经验(读写文件,重点是写)。

时间:2022-05-10 07:58:23
现在WinCE想开发一个文本编辑器(C#语言),用现成控件TextBox大于65KB就会失败,已经开发2.0版本是画出文件内容,只能查看不能修改。现在开发3.0版本,要求能查看,能修改。请各位多帮助。

74 个解决方案

#1


在 CE 下处理大文本文件是比较麻烦的,不管是哪种语言都一样

建议分块处理:将文本文件内容分成如 2K 的块,每次在块中进行处理。

#2


“建议分块处理:将文本文件内容分成如 2K 的块,每次在块中进行处理。”
意思是把大的TXT文件分成很多小的TXT文件,再最后把它拼接起来?还是采用内存映射的方法,分段映射分段操作。

#3


应该采用内存映射吧,这样读写文件就是直接操作内存。
系统负责处理数据的缓存,写入以及内存分配释放,可以提高读写速度。

#4


不过没这方面的经验,还是帮顶吧。呵呵。

#5


专门的文本编辑器都是采用的“显示那段就读哪段”的方式

通过显示框大小,字体,和滚动条位置,动态计算屏幕所显示的内容在文件的偏移和长度,然后通过文件操作的方式打开,读取需要的内容到内存。 保存的时候也同样要这样做。
读文件调用底层的api:open,seek,read,write会比c#里面直接用流方式操作高效

#6


专门的文本编辑器都是采用的“显示那段就读哪段”的方式,
只读是比较简单的。但是对写,一个10W行的文件(每一行的内容虽然不多),修改10W行文件中的某一行,比喻说第5W行,怎么保存,删除了第5W行,怎么保存?对于效率有一定的要求。

#7


内存映射

#8


引用 6 楼 cjdxling 的回复:
专门的文本编辑器都是采用的“显示那段就读哪段”的方式,
只读是比较简单的。但是对写,一个10W行的文件(每一行的内容虽然不多),修改10W行文件中的某一行,比喻说第5W行,怎么保存,删除了第5W行,怎么保存?对于效率有一定的要求。

没实际做过,只是知道读得时候不是全部读取,只读显示的那部分

写的话我自己揣测一下,可以记录当前读出来的文本的开始和结束位置,然后整段替换成修改后的。比如你读取了第50~100行,然后修改了66行,保存的时候,实际上是(文件头~原50行位置)+编辑后显示的文本+(原100行位置~文件尾) 三段重新拼接成一个文件

#9


内存映射,当文件映射进内存后,是连续的,如果修改过后映射部分变大,那么写会文件会出现文件数据覆盖的问题,怎么解决?

#10


现在一点思路也没有,悲剧了

#11


有木有试过通过逐行读取的方式来操作。比如说,10W行的数据,读取第5W行的数据,把指针跳到第5W行。要修改的话,试试把你修改的内容在原文本的头尾位置记录下来,然后把这段数据删掉,再把你的数据插入到记录的开始位置。这个方法木有试过,LZ可以试试看行不行

#12


[Quote=引用 11 楼 brantyou 的回复:]

有木有试过通过逐行读取的方式来操作。比如说,10W行的数据,读取第5W行的数据,把指针跳到第5W行。要修改的话,试试把你修改的内容在原文本的头尾位置记录下来,然后把这段数据删掉,再把你的数据插入到记录的开始位置。这个方法木有试过,LZ可以试试看行不行
但是问题在于这第5万行后面的文件内容怎么办?对于文件的操作好像像链表一样,如你插入一行新内容,你要把文件后面的内容都像后移动了,你删除一样内容也你把删除行的所有内容向前移动对应的行。是吧?这个问题怎么处理,关键。

#13


对于大文件度的问题比较好解决,我在打开时做一个文件地图,事先做一些标记,这样在读的时侯,就能比较快的处理了。但这个方法好像对于写不顶用。写我只是暂时想到了一个有点业余的做法,把大点文件在打开时分割成一个小的文件,然后在编辑时操作的对象是这些小的对象,最后一次保存操作时,再把这些小文件拼成一个完整的大文件。但是我又考虑到这个方法可能不太合适,因为查看到网上在嵌入式环境下对于大文件的处理一般都是采用内存映射的方式来实现的,不过大多也只是读,修改的很少。

#14


引用 13 楼 cjdxling 的回复:
对于大文件度的问题比较好解决,我在打开时做一个文件地图,事先做一些标记,这样在读的时侯,就能比较快的处理了。但这个方法好像对于写不顶用。写我只是暂时想到了一个有点业余的做法,把大点文件在打开时分割成一个小的文件,然后在编辑时操作的对象是这些小的对象,最后一次保存操作时,再把这些小文件拼成一个完整的大文件。但是我又考虑到这个方法可能不太合适,因为查看到网上在嵌入式环境下对于大文件的处理一般都是采用……

还是内存映射好一点

#15


引用 14 楼 woshi_ziyu 的回复:
引用 13 楼 cjdxling 的回复:

对于大文件度的问题比较好解决,我在打开时做一个文件地图,事先做一些标记,这样在读的时侯,就能比较快的处理了。但这个方法好像对于写不顶用。写我只是暂时想到了一个有点业余的做法,把大点文件在打开时分割成一个小的文件,然后在编辑时操作的对象是这些小的对象,最后一次保存操作时,再把这些小文件拼成一个完整的大文件。但是我又考虑到这个方法可能不太合适,因为查……

但对于内存映射时,文件覆盖的问题怎么解决了,有没有思路可以提供一下,求指教!有做个类似的案例吗?

#16


怎么没人了?

#17


内存映射,与磁盘操作

#18


引用 17 楼 kingmax54212008 的回复:
内存映射,与磁盘操作

能否再稍微点详细点解释一下?我比较关注的是写文件。我现在手头上的硬件平台是EP9315 ,64MRAM,2G CT卡,软件平台 WINCE 5.0

#19


IntPtr mapSourceAddress = MapViewOfFile(mappingFileHandle, FILE_MAP_WRITE,
                       0, (uint)offset, blockBytes);
                   // Marshal.Copy(mapSourceAddress, temp, 0, (int)blockBytes);
                   //string str = string.Empty;
                   // str = System.Text.Encoding.GetEncoding("gb2312").GetString(temp, 0, (int)blockBytes);
                    IntPtr mapTatgetAddress = MapViewOfFile(targetMappingHandle, FILE_MAP_WRITE,
                       0, 0, 0);

                    if (mapSourceAddress == IntPtr.Zero)
                    {
                        error = GetLastError();

                    }
                    if (mapTatgetAddress == IntPtr.Zero)
                    {
                        error = GetLastError();

                    }
                    memcpy(mapTatgetAddress, mapSourceAddress, (int)blockBytes);
                    error = GetLastError();
                    FlushViewOfFile(mapTatgetAddress, (int)blockBytes);
                    error = GetLastError();
                     UnmapViewOfFile(mapSourceAddress);
                    UnmapViewOfFile(mapTatgetAddress);
把源文件中复制到一个新空白文件中,运行不出错,但是运行结束后,容白文件中还是什么也没有,什么也没写入。请问哪位知道是怎么回事。

#20


1 内存映射
2 仔细想想fread的参数,为什么有个读取长度,就是针对你的这种需求,可以逐步读入,分批处理的。

#21


分页吧。。

#22


用TextReader和TextWriter  一段一段读,
一下全读完再加载,肯定会死

#23


该回复于2011-12-15 10:02:53被版主删除

#24


没遇到过

#25


先分块把 感觉最简单的方法了

#26


一个曾经考虑过但没去仔细验证的方案:
操作过程中,不直接写原始文件,记录成del和insert操作步骤,保存时,分块读入文件,应用所有的操作(可优化),并写入新生成的文件,删除原文件

内存映射无法解决文件写操作的效率问题的,但可以使得编码变得简单

#27


该回复于2011-12-15 12:59:34被版主删除

#28


20M的文本,不会继续增大的话,可以考虑内存映射;否则,分块算了。

#29


这个我也遇到过,好像没什么好办法!

#30


该回复于2011-12-15 16:32:51被版主删除

#31


该回复于2011-12-16 09:03:13被版主删除

#32


该回复于2011-12-16 10:01:16被版主删除

#33


如果是文本文件,修改后保存必须重新写入整个文件,至少修改之后的内容必须写入。除非你修改的内容和原内容长度完全一样。
写入的时候可以优化一下,根据文件长度的变化将没有变化的文件内容逐块复制。

#34


路过不懂学习帮顶,这个问题确实没有遇到过 但是看了上面的东西 突然发现其实做标签的方式也是可以的比如说vs里面的行号 每次修改了以后前面就会变颜色 你也可以用标记符记录下某一段的标识 然后只修改某一段也可以一段一段的保存 这个应该还是有可行性的....每次操作都会有回车 回车的时候就保存这一段内容到一个临时文件上或者一个标记片段上...最后在组合 或者到了一定行数组合一次.....

#35


我在CE5上实现过,用内存映射,比你这个大十倍,一般能到四五百M,最多是几G,没什么问题。

#36


引用 35 楼 fpcc 的回复:
我在CE5上实现过,用内存映射,比你这个大十倍,一般能到四五百M,最多是几G,没什么问题。

高手,能详细一点吗?用内存映射其实主要问题在如果写回文件中后,超过原映射块的长度,就会出现覆盖现象?这个怎么解决?还是内存映射加上分块吗?如果当前分的块继续变大,怎么处理?

#37


我现在采用两种方式同时优化,内存映射加上分块?但是在所有操作完成后,合并重生成文件的时候比较慢,文件越大越慢,请问那位有什么好的方法来优化?老大要求在两个10M的文件,在0.5s内合并完成?能否实现!

#38


WinCE 5.0平台,200MHZ ARM9,64MRAM

#39


分块读取
根据当前屏的行数,每行要显示的字节数分配相应的内存(buf),然后将文件读取到内存(buf)
如果存在字符转换,还要考虑字符转换。
根据系统的性质,可以考虑添加书签等操作

#40


引用 39 楼 sxg_lyy 的回复:
分块读取
根据当前屏的行数,每行要显示的字节数分配相应的内存(buf),然后将文件读取到内存(buf)
如果存在字符转换,还要考虑字符转换。
根据系统的性质,可以考虑添加书签等操作

首先,谢谢你的回贴,读文件没有什么太大困难,关键是写文件,假若我把几十万行的文本文件中的某几行删除了,请问怎么处理,是不是不要把后面的文件行都向前挪动?对于效率也是有要求的

#41


引用 40 楼 cjdxling 的回复:
引用 39 楼 sxg_lyy 的回复:

分块读取
根据当前屏的行数,每行要显示的字节数分配相应的内存(buf),然后将文件读取到内存(buf)
如果存在字符转换,还要考虑字符转换。
根据系统的性质,可以考虑添加书签等操作

首先,谢谢你的回贴,读文件没有什么太大困难,关键是写文件,假若我把几十万行的文本文件中的某几行删除了,请问怎么处理,是不是不要把后面的文件行都向前挪动?对于……


我觉得如果有删除操作了以后再显示的话,你可以把删除的部分的偏移记录下来例如删除起始偏移是beginIndex,偏移后的偏移是EndIndex;操作了删除之后可以把这部分保存成一个结构体,遇到就跳过这部分。

如果仅仅是不显示删除部分则按照这种做法比较快速。


如果要求文件本身也要在删除操作后改变,这个也没有什么简便的方法吧,只能把后面的数据往前挪啦

#42


如果要保存的话,也是可以把添加的文本或者删除的文本保存在这样一个结构体中
bool attri;// add or del
int AddrIndex;//添加或者删除的文本在源文件中的位置
cstring Addstr;

有操作的时候把该结构体写到一个临时文件上。

如果关闭一个文件后再打开,就先去读取对应的临时文件,判断文件从哪里读取,显示,等等

#43


如果要保存的话,也是可以把添加的文本或者删除的文本保存在这样一个结构体中
bool attri;// add or del
int AddrIndex;//添加或者删除的文本在源文件中的位置
int length;
cstring Addstr;

有操作的时候把该结构体写到一个临时文件上。

如果关闭一个文件后再打开,就先去读取对应的临时文件,判断文件从哪里读取,显示,等等

#44


引用 43 楼 sxg_lyy 的回复:
如果要保存的话,也是可以把添加的文本或者删除的文本保存在这样一个结构体中
bool attri;// add or del
int AddrIndex;//添加或者删除的文本在源文件中的位置
int length;
cstring Addstr;

有操作的时候把该结构体写到一个临时文件上。

如果关闭一个文件后再打开,就先去读取对应的临时文件,判断文件从哪里读取,显示,等等

总结你的思路实际上也是有文件分块的思想,关键是我们硬件平台太不给力了64MRAM,32M给操作系统,应用程序只有32M,200MHZ的主频,我这个模块只是应用程序的一部分。老大还要求有效率,不能修改操作过后,让人家等半天。悲剧。。。。。。

#45


我初步验证,现在用内存映射加文件分块的思路,最在性能瓶颈在最后文件写入上?文件大如果有几十M的话,合并起来很慢?但修改的操作的瓶颈是没有了,比较快。老大又来的新要求,能不能在0.5S内实现两个20M文件的合并?意思是在最后整合文件块时,也必须要足够快。

#46


保存的加速,思路就只能在保存之前做优化,这样实际保存的操作才能迅速。
将分片的小文件进行拼接,必定需要对原有的整个文件以及分片块做扫描,这个不可能快起来。
楼下继续。。。

#47


不清楚是个什么原因

#48


只要想到TEXT控件不可能同时显示那么多文字,就想到可以分块显示啦,不是吗?方法都说出来了,看你自己怎么调节咯,总不能叫别人写代码给你吧.

#49


LS的好像会实现一样

#50


有这个方法的  用RandomAccessFile这个类,设置和记录读写文件的偏移量


java.io 
类 RandomAccessFile
java.lang.Object
  java.io.RandomAccessFile
所有已实现的接口: 
Closeable, DataInput, DataOutput 

--------------------------------------------------------------------------------

public class RandomAccessFileextends Objectimplements DataOutput, DataInput, Closeable此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。 

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。 

#1


在 CE 下处理大文本文件是比较麻烦的,不管是哪种语言都一样

建议分块处理:将文本文件内容分成如 2K 的块,每次在块中进行处理。

#2


“建议分块处理:将文本文件内容分成如 2K 的块,每次在块中进行处理。”
意思是把大的TXT文件分成很多小的TXT文件,再最后把它拼接起来?还是采用内存映射的方法,分段映射分段操作。

#3


应该采用内存映射吧,这样读写文件就是直接操作内存。
系统负责处理数据的缓存,写入以及内存分配释放,可以提高读写速度。

#4


不过没这方面的经验,还是帮顶吧。呵呵。

#5


专门的文本编辑器都是采用的“显示那段就读哪段”的方式

通过显示框大小,字体,和滚动条位置,动态计算屏幕所显示的内容在文件的偏移和长度,然后通过文件操作的方式打开,读取需要的内容到内存。 保存的时候也同样要这样做。
读文件调用底层的api:open,seek,read,write会比c#里面直接用流方式操作高效

#6


专门的文本编辑器都是采用的“显示那段就读哪段”的方式,
只读是比较简单的。但是对写,一个10W行的文件(每一行的内容虽然不多),修改10W行文件中的某一行,比喻说第5W行,怎么保存,删除了第5W行,怎么保存?对于效率有一定的要求。

#7


内存映射

#8


引用 6 楼 cjdxling 的回复:
专门的文本编辑器都是采用的“显示那段就读哪段”的方式,
只读是比较简单的。但是对写,一个10W行的文件(每一行的内容虽然不多),修改10W行文件中的某一行,比喻说第5W行,怎么保存,删除了第5W行,怎么保存?对于效率有一定的要求。

没实际做过,只是知道读得时候不是全部读取,只读显示的那部分

写的话我自己揣测一下,可以记录当前读出来的文本的开始和结束位置,然后整段替换成修改后的。比如你读取了第50~100行,然后修改了66行,保存的时候,实际上是(文件头~原50行位置)+编辑后显示的文本+(原100行位置~文件尾) 三段重新拼接成一个文件

#9


内存映射,当文件映射进内存后,是连续的,如果修改过后映射部分变大,那么写会文件会出现文件数据覆盖的问题,怎么解决?

#10


现在一点思路也没有,悲剧了

#11


有木有试过通过逐行读取的方式来操作。比如说,10W行的数据,读取第5W行的数据,把指针跳到第5W行。要修改的话,试试把你修改的内容在原文本的头尾位置记录下来,然后把这段数据删掉,再把你的数据插入到记录的开始位置。这个方法木有试过,LZ可以试试看行不行

#12


[Quote=引用 11 楼 brantyou 的回复:]

有木有试过通过逐行读取的方式来操作。比如说,10W行的数据,读取第5W行的数据,把指针跳到第5W行。要修改的话,试试把你修改的内容在原文本的头尾位置记录下来,然后把这段数据删掉,再把你的数据插入到记录的开始位置。这个方法木有试过,LZ可以试试看行不行
但是问题在于这第5万行后面的文件内容怎么办?对于文件的操作好像像链表一样,如你插入一行新内容,你要把文件后面的内容都像后移动了,你删除一样内容也你把删除行的所有内容向前移动对应的行。是吧?这个问题怎么处理,关键。

#13


对于大文件度的问题比较好解决,我在打开时做一个文件地图,事先做一些标记,这样在读的时侯,就能比较快的处理了。但这个方法好像对于写不顶用。写我只是暂时想到了一个有点业余的做法,把大点文件在打开时分割成一个小的文件,然后在编辑时操作的对象是这些小的对象,最后一次保存操作时,再把这些小文件拼成一个完整的大文件。但是我又考虑到这个方法可能不太合适,因为查看到网上在嵌入式环境下对于大文件的处理一般都是采用内存映射的方式来实现的,不过大多也只是读,修改的很少。

#14


引用 13 楼 cjdxling 的回复:
对于大文件度的问题比较好解决,我在打开时做一个文件地图,事先做一些标记,这样在读的时侯,就能比较快的处理了。但这个方法好像对于写不顶用。写我只是暂时想到了一个有点业余的做法,把大点文件在打开时分割成一个小的文件,然后在编辑时操作的对象是这些小的对象,最后一次保存操作时,再把这些小文件拼成一个完整的大文件。但是我又考虑到这个方法可能不太合适,因为查看到网上在嵌入式环境下对于大文件的处理一般都是采用……

还是内存映射好一点

#15


引用 14 楼 woshi_ziyu 的回复:
引用 13 楼 cjdxling 的回复:

对于大文件度的问题比较好解决,我在打开时做一个文件地图,事先做一些标记,这样在读的时侯,就能比较快的处理了。但这个方法好像对于写不顶用。写我只是暂时想到了一个有点业余的做法,把大点文件在打开时分割成一个小的文件,然后在编辑时操作的对象是这些小的对象,最后一次保存操作时,再把这些小文件拼成一个完整的大文件。但是我又考虑到这个方法可能不太合适,因为查……

但对于内存映射时,文件覆盖的问题怎么解决了,有没有思路可以提供一下,求指教!有做个类似的案例吗?

#16


怎么没人了?

#17


内存映射,与磁盘操作

#18


引用 17 楼 kingmax54212008 的回复:
内存映射,与磁盘操作

能否再稍微点详细点解释一下?我比较关注的是写文件。我现在手头上的硬件平台是EP9315 ,64MRAM,2G CT卡,软件平台 WINCE 5.0

#19


IntPtr mapSourceAddress = MapViewOfFile(mappingFileHandle, FILE_MAP_WRITE,
                       0, (uint)offset, blockBytes);
                   // Marshal.Copy(mapSourceAddress, temp, 0, (int)blockBytes);
                   //string str = string.Empty;
                   // str = System.Text.Encoding.GetEncoding("gb2312").GetString(temp, 0, (int)blockBytes);
                    IntPtr mapTatgetAddress = MapViewOfFile(targetMappingHandle, FILE_MAP_WRITE,
                       0, 0, 0);

                    if (mapSourceAddress == IntPtr.Zero)
                    {
                        error = GetLastError();

                    }
                    if (mapTatgetAddress == IntPtr.Zero)
                    {
                        error = GetLastError();

                    }
                    memcpy(mapTatgetAddress, mapSourceAddress, (int)blockBytes);
                    error = GetLastError();
                    FlushViewOfFile(mapTatgetAddress, (int)blockBytes);
                    error = GetLastError();
                     UnmapViewOfFile(mapSourceAddress);
                    UnmapViewOfFile(mapTatgetAddress);
把源文件中复制到一个新空白文件中,运行不出错,但是运行结束后,容白文件中还是什么也没有,什么也没写入。请问哪位知道是怎么回事。

#20


1 内存映射
2 仔细想想fread的参数,为什么有个读取长度,就是针对你的这种需求,可以逐步读入,分批处理的。

#21


分页吧。。

#22


用TextReader和TextWriter  一段一段读,
一下全读完再加载,肯定会死

#23


该回复于2011-12-15 10:02:53被版主删除

#24


没遇到过

#25


先分块把 感觉最简单的方法了

#26


一个曾经考虑过但没去仔细验证的方案:
操作过程中,不直接写原始文件,记录成del和insert操作步骤,保存时,分块读入文件,应用所有的操作(可优化),并写入新生成的文件,删除原文件

内存映射无法解决文件写操作的效率问题的,但可以使得编码变得简单

#27


该回复于2011-12-15 12:59:34被版主删除

#28


20M的文本,不会继续增大的话,可以考虑内存映射;否则,分块算了。

#29


这个我也遇到过,好像没什么好办法!

#30


该回复于2011-12-15 16:32:51被版主删除

#31


该回复于2011-12-16 09:03:13被版主删除

#32


该回复于2011-12-16 10:01:16被版主删除

#33


如果是文本文件,修改后保存必须重新写入整个文件,至少修改之后的内容必须写入。除非你修改的内容和原内容长度完全一样。
写入的时候可以优化一下,根据文件长度的变化将没有变化的文件内容逐块复制。

#34


路过不懂学习帮顶,这个问题确实没有遇到过 但是看了上面的东西 突然发现其实做标签的方式也是可以的比如说vs里面的行号 每次修改了以后前面就会变颜色 你也可以用标记符记录下某一段的标识 然后只修改某一段也可以一段一段的保存 这个应该还是有可行性的....每次操作都会有回车 回车的时候就保存这一段内容到一个临时文件上或者一个标记片段上...最后在组合 或者到了一定行数组合一次.....

#35


我在CE5上实现过,用内存映射,比你这个大十倍,一般能到四五百M,最多是几G,没什么问题。

#36


引用 35 楼 fpcc 的回复:
我在CE5上实现过,用内存映射,比你这个大十倍,一般能到四五百M,最多是几G,没什么问题。

高手,能详细一点吗?用内存映射其实主要问题在如果写回文件中后,超过原映射块的长度,就会出现覆盖现象?这个怎么解决?还是内存映射加上分块吗?如果当前分的块继续变大,怎么处理?

#37


我现在采用两种方式同时优化,内存映射加上分块?但是在所有操作完成后,合并重生成文件的时候比较慢,文件越大越慢,请问那位有什么好的方法来优化?老大要求在两个10M的文件,在0.5s内合并完成?能否实现!

#38


WinCE 5.0平台,200MHZ ARM9,64MRAM

#39


分块读取
根据当前屏的行数,每行要显示的字节数分配相应的内存(buf),然后将文件读取到内存(buf)
如果存在字符转换,还要考虑字符转换。
根据系统的性质,可以考虑添加书签等操作

#40


引用 39 楼 sxg_lyy 的回复:
分块读取
根据当前屏的行数,每行要显示的字节数分配相应的内存(buf),然后将文件读取到内存(buf)
如果存在字符转换,还要考虑字符转换。
根据系统的性质,可以考虑添加书签等操作

首先,谢谢你的回贴,读文件没有什么太大困难,关键是写文件,假若我把几十万行的文本文件中的某几行删除了,请问怎么处理,是不是不要把后面的文件行都向前挪动?对于效率也是有要求的

#41


引用 40 楼 cjdxling 的回复:
引用 39 楼 sxg_lyy 的回复:

分块读取
根据当前屏的行数,每行要显示的字节数分配相应的内存(buf),然后将文件读取到内存(buf)
如果存在字符转换,还要考虑字符转换。
根据系统的性质,可以考虑添加书签等操作

首先,谢谢你的回贴,读文件没有什么太大困难,关键是写文件,假若我把几十万行的文本文件中的某几行删除了,请问怎么处理,是不是不要把后面的文件行都向前挪动?对于……


我觉得如果有删除操作了以后再显示的话,你可以把删除的部分的偏移记录下来例如删除起始偏移是beginIndex,偏移后的偏移是EndIndex;操作了删除之后可以把这部分保存成一个结构体,遇到就跳过这部分。

如果仅仅是不显示删除部分则按照这种做法比较快速。


如果要求文件本身也要在删除操作后改变,这个也没有什么简便的方法吧,只能把后面的数据往前挪啦

#42


如果要保存的话,也是可以把添加的文本或者删除的文本保存在这样一个结构体中
bool attri;// add or del
int AddrIndex;//添加或者删除的文本在源文件中的位置
cstring Addstr;

有操作的时候把该结构体写到一个临时文件上。

如果关闭一个文件后再打开,就先去读取对应的临时文件,判断文件从哪里读取,显示,等等

#43


如果要保存的话,也是可以把添加的文本或者删除的文本保存在这样一个结构体中
bool attri;// add or del
int AddrIndex;//添加或者删除的文本在源文件中的位置
int length;
cstring Addstr;

有操作的时候把该结构体写到一个临时文件上。

如果关闭一个文件后再打开,就先去读取对应的临时文件,判断文件从哪里读取,显示,等等

#44


引用 43 楼 sxg_lyy 的回复:
如果要保存的话,也是可以把添加的文本或者删除的文本保存在这样一个结构体中
bool attri;// add or del
int AddrIndex;//添加或者删除的文本在源文件中的位置
int length;
cstring Addstr;

有操作的时候把该结构体写到一个临时文件上。

如果关闭一个文件后再打开,就先去读取对应的临时文件,判断文件从哪里读取,显示,等等

总结你的思路实际上也是有文件分块的思想,关键是我们硬件平台太不给力了64MRAM,32M给操作系统,应用程序只有32M,200MHZ的主频,我这个模块只是应用程序的一部分。老大还要求有效率,不能修改操作过后,让人家等半天。悲剧。。。。。。

#45


我初步验证,现在用内存映射加文件分块的思路,最在性能瓶颈在最后文件写入上?文件大如果有几十M的话,合并起来很慢?但修改的操作的瓶颈是没有了,比较快。老大又来的新要求,能不能在0.5S内实现两个20M文件的合并?意思是在最后整合文件块时,也必须要足够快。

#46


保存的加速,思路就只能在保存之前做优化,这样实际保存的操作才能迅速。
将分片的小文件进行拼接,必定需要对原有的整个文件以及分片块做扫描,这个不可能快起来。
楼下继续。。。

#47


不清楚是个什么原因

#48


只要想到TEXT控件不可能同时显示那么多文字,就想到可以分块显示啦,不是吗?方法都说出来了,看你自己怎么调节咯,总不能叫别人写代码给你吧.

#49


LS的好像会实现一样

#50


有这个方法的  用RandomAccessFile这个类,设置和记录读写文件的偏移量


java.io 
类 RandomAccessFile
java.lang.Object
  java.io.RandomAccessFile
所有已实现的接口: 
Closeable, DataInput, DataOutput 

--------------------------------------------------------------------------------

public class RandomAccessFileextends Objectimplements DataOutput, DataInput, Closeable此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。 

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。