vb6 怎么很快的读取数据量大的TXT文件

hbutwzc 2010-07-05 10:57:58
vb6 怎么很快的读取数据量大的TXT文件
1)测量仪器测量数据保存在仪器的内存卡中,保存格式为TXT文件
2)数据一组一组的按顺序存储如:AA234567A3B46823BBAA234567A3B46823BBAA234567A3B46823BB.......
3)由于是按秒存储txt文本比较大,一分钟就快到0.2兆了,一天下来数据很大几百兆了
4)请教VB高手如何读取TXT中数据较快?怎么样的解决方案较好
...全文
1333 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 a1875566250 的回复:]
俺写的一个简单的文件读取函数。。。很潦草就是了,无聊无聊写的。。。


VB code
Private Declare Function OpenFile& Lib "kernel32" (ByVal FileName As String, ByVal OFs As Long, ByVal Flags As Long)
Private Declare Function NtRea……
[/Quote]333
lyserver 2010-07-07
  • 打赏
  • 举报
回复
自己按块读数据,最好要考虑内存对齐和字符边界,否则,会出现半个汉字的问题。
lyserver 2010-07-06
  • 打赏
  • 举报
回复
使用映射的最大好处是可以使用模拟指针来把数据地址绑定到数组中,使代码简洁易懂,而且效率也不错。
lyserver 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 myjian 的回复:]
看给出的示例内容,貌似是[AA][数据内容][BB]这样的格式,无物理分隔符,是内容逻辑分隔.

那么,如果其中的[数据内容]长度是一定的话,则可以参考上面10楼的方案,代码会很简单.

如果长度不一定,那就只有自己扫描这段内容了.

不过无论哪种方案,都有个读文件的问题,因为关键在于文件很大,能上G,那么我觉得就最好使用分段读取的方案,比如一次读取10M进来处理.

以前我在处理……
[/Quote]
遇到过,VB使用内存映射有一些内存限制,不像C++编译后内存是可预见的,而VB会把低端内存中某些高端地址保留给自己使用了,导致可用的连续地址不足1G,如果映射超过了500M,就很可能出问题。
of123 2010-07-06
  • 打赏
  • 举报
回复

我处理大文件一般用 Binary 方式打开。这样,打开文件时不必等待操作系统读取整个文件。每次读取并处理 4K 左右还是很快的。

对于定长记录的文件,最好每次读取记录长度的整倍数。
嗷嗷叫的老马 2010-07-06
  • 打赏
  • 举报
回复
好象一般硬盘速度能达到60M每秒的读取速度,写入为30M左右.

这样的话,一次读入的大小在10M左右应该问题不大.

但还有另一个问题,就是处理数据的时间.

这部分要好好写,VB6里面字符串操作如果不注意的话是能写出非常非常慢的代码的......
ldy888 2010-07-06
  • 打赏
  • 举报
回复
楼主如果要一块块 取出来处理的话,每一块数据不要太大
这个的代码应该能用。


Sub test楼主()
Dim B() As Byte
s = "d:\楼主的文件.txt" 'ANSI 码 几百兆的文件
t = Timer
Close
F = FreeFile
r = 20 '取第20块记录
k = 30 '30条算一块
ReDim B(1 To 18 * k) As Byte
Open s For Binary As F
Get F, (r - 1) * 18 * k + 1, B
Close F
Debug.Print StrConv(B, 64)
End Sub
ldy888 2010-07-06
  • 打赏
  • 举报
回复
我用了个8G的文件试了下,如果只取某一段值的话还是很快的。

Sub tset8g()
Dim b(1024& * 1024) As Byte, bb(1024& * 1024) As Byte
s = "g:\cp090822.GHO" '8G 的Ghost文件 ,超出2G, lof(1) 已经取不到值了
t = Timer
Open s For Binary As 1
Get 1, , b
Get 1, 1024& * 1024 * 1024, bb ' 在1G 处 取1M 字节
Close
Debug.Print Timer - t, "耗时也很短 0 秒 ,VB的计时不是很准 仅参考 "
'Debug.Print b
'Debug.Print bb, "能打印出来和上面不一样说明取到值了"
End Sub
嗷嗷叫的老马 2010-07-06
  • 打赏
  • 举报
回复
看给出的示例内容,貌似是[AA][数据内容][BB]这样的格式,无物理分隔符,是内容逻辑分隔.

那么,如果其中的[数据内容]长度是一定的话,则可以参考上面10楼的方案,代码会很简单.

如果长度不一定,那就只有自己扫描这段内容了.

不过无论哪种方案,都有个读文件的问题,因为关键在于文件很大,能上G,那么我觉得就最好使用分段读取的方案,比如一次读取10M进来处理.

以前我在处理大文件时也使用过内存映射,但发现一个问题,就是进程的连续逻辑内存必须要有文件那么大,不然会映射失败.

不过这个问题当时没时间详细跟进,就使用了分段读取.不知道这个问题江南兄是否遇到?
嗷嗷叫的老马 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 lyserver 的回复:]
遇到过,VB使用内存映射有一些内存限制,不像C++编译后内存是可预见的,而VB会把低端内存中某些高端地址保留给自己使用了,导致可用的连续地址不足1G,如果映射超过了500M,就很可能出问题。[/Quote]
汗,我也是映射差不多这么大的文件时出的问题.

刚刚看了一下以前的日志(http://www.m5home.com/blog/article.asp?id=182),是4XX大小的文件时就不行了.
hbutwzc 2010-07-06
  • 打赏
  • 举报
回复
都是带勋章的高手啊
感谢各位
hbutwzc 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 a1875566250 的回复:]
俺写的一个简单的文件读取函数。。。很潦草就是了,无聊无聊写的。。。


VB code
Private Declare Function OpenFile& Lib "kernel32" (ByVal FileName As String, ByVal OFs As Long, ByVal Flags As Long)
Private Declare Function NtRea……
[/Quote]
这个我知道讲数据写入数组处理,但几百兆上G的数据能写入一个数组么?那样读取处理很慢啊
hbutwzc 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bcrun 的回复:]
关键是你要读取到什么地方,作什么用途!!!!
如需要写代码给你,你最好生成一个1M左右的文本,压缩打包后上传到某处,供我们下载测试实际速度.
[/Quote]
要讲TXT文件里的数据一组一组(AA......BB为一组)分析,写入数据库啊
a1875566250 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 lyserver 的回复:]
一、使用内存映射方式读取文件。
二、将内存映射得到的文件内容指针绑定到VB的byte数组上,以数组形式访问文件内容。
具体代码可参考我博客中《VB快速查找大型文件中包含的字符串》一文。
[/Quote]

恩,支持内存映射方法,最好用的。
lyserver 2010-07-05
  • 打赏
  • 举报
回复
一、使用内存映射方式读取文件。
二、将内存映射得到的文件内容指针绑定到VB的byte数组上,以数组形式访问文件内容。
具体代码可参考我博客中《VB快速查找大型文件中包含的字符串》一文。
a1875566250 2010-07-05
  • 打赏
  • 举报
回复
俺写的一个简单的文件读取函数。。。很潦草就是了,无聊无聊写的。。。

Private Declare Function OpenFile& Lib "kernel32" (ByVal FileName As String, ByVal OFs As Long, ByVal Flags As Long)
Private Declare Function NtReadFile& Lib "ntdll" (ByVal Handle As Long, ByVal Events As Long, ByVal APCRoutine As Long, ByVal APCContext As Long, ByVal IoStatus As Long, ByVal Buffer As Long, ByVal Length As Long, Optional ByVal Number As Long, Optional ByVal Keys As Long)
Private Declare Function NtWriteFile& Lib "ntdll" (ByVal Handle As Long, ByVal Events As Long, ByVal APCRoutine As Long, ByVal APCContext As Long, ByVal IoStatus As Long, ByVal Buffer As Long, ByVal Length As Long, Optional ByVal Number As Long, Optional ByVal Keys As Long)
Private Declare Function CloseHandle& Lib "kernel32" (ByVal Handle As Long)

Public Function ReadFile(ByVal FileName As String, ByRef ByteIn() As Byte) As Boolean
Dim Handle&, Block&(1), Struct&(33)
ReDim ByteIn(FileLen(FileName))
Handle = OpenFile(FileName, VarPtr(Struct(0)), 0)
If NtReadFile(Handle, 0, 0, 0, VarPtr(Block(0)), VarPtr(ByteIn(0)), UBound(ByteIn)) = 0 Then ReadFile = True
CloseHandle Handle
End Function
Public Function WriteFile(ByVal FileName As String, ByRef ByteIn() As Byte) As Boolean
Dim Handle&, Block&(1), Struct&(33)
CloseHandle OpenFile(FileName, VarPtr(Struct(0)), 4096)
Handle = OpenFile(FileName, VarPtr(Struct(0)), 1)
If NtWriteFile(Handle, 0, 0, 0, VarPtr(Block(0)), VarPtr(ByteIn(0)), UBound(ByteIn)) = 0 Then WriteFile = True
CloseHandle Handle
End Function

'使用方法如:

Private Sub Form_Load()
Dim Temp() As Byte
Me.Caption = ReadFile("C:\WINDOWS\win.ini", Temp)
MsgBox StrConv(Temp, vbUnicode)
Erase Temp
Me.Caption = ReadFile("C:\WINDOWS\notepad.exe", Temp)
Me.Caption = WriteFile("C:\notepad.exe", Temp)
End Sub
bcrun 2010-07-05
  • 打赏
  • 举报
回复
关键是你要读取到什么地方,作什么用途!!!!
如需要写代码给你,你最好生成一个1M左右的文本,压缩打包后上传到某处,供我们下载测试实际速度.
贝隆 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 lyserver 的回复:]
一、使用内存映射方式读取文件。
二、将内存映射得到的文件内容指针绑定到VB的byte数组上,以数组形式访问文件内容。
具体代码可参考我博客中《VB快速查找大型文件中包含的字符串》一文。
[/Quote]
不错的方法!顶
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hbutwzc 的回复:]
要讲TXT文件里的数据一组一组(AA......BB为一组)分析,写入数据库啊
[/Quote]
每一组的记录长度似乎是固定的。
这样的话,就可以使用随机记录方式打开文件。事先定义好一个记录的结构体,随机方式打开时,取这个结构体的长度,读取时直接赋给这个结构体。然后就可以按结构体内定义的数据成员来取到对应的数据,进行分析处理。
饭fan有引力 2010-07-05
  • 打赏
  • 举报
回复
帮顶,,,,
加载更多回复(2)

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧