VB如何区块读取二进制的文件内容保存到数组中

FrankWang 2018-08-30 11:29:43
type data
a as long
b as long
end type

Open App.Path & "\data.dat" For Random As #1 Len = Len(data)

一般用的方法是循环读取,这样速度太慢了,怎么能区块读取呢
比如读取指针为2-20的数据保存到一个数组中
...全文
2112 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
idealguy 2018-10-08
  • 打赏
  • 举报
回复
引用 17 楼 idealguy 的回复:
给一个完整的范例(包含DEMO.DAT文件生成)
从 Istart 字节开始 一次读入 Lrec 个记录(可以是任意类型)的数据到 DatBuf


Option Explicit
......


第22行一次都入所有数据
idealguy 2018-10-08
  • 打赏
  • 举报
回复
给一个完整的范例(包含DEMO.DAT文件生成)
从 Istart 字节开始 一次读入 Lrec 个记录(可以是任意类型)的数据到 DatBuf


Option Explicit

Private Type DataType
A As Long
B As Long
End Type

Dim FileName$ '文件名
Dim Istart As Long '起始字节
Dim Lrec As Long '需读取的记录数
Dim DatBuf() As DataType '数据存放数组

Private Sub Command1_Click()
'读取数据文件
Dim L&
ReDim DatBuf(Lrec - 1)
L = Len(DatBuf(0)) * Lrec
If FileLen(FileName) < L + Istart - 1 Then
MsgBox "文件长度太小!"
Else
Open FileName For Binary As #1
Get #1, Istart, DatBuf
Close #1
'
MsgBox "文件读取成功,从" & Istart & "字节起读取了" & L & "字节。"
End If
End Sub

Private Sub Command2_Click()
' 生成DEMO数据
ReDim DatBuf(Lrec - 1)
Dim i&, H$
For i = 1 To Lrec
DatBuf(i - 1).A = Int(Rnd * 10000)
DatBuf(i - 1).B = Int(Rnd * 10000)
Next i
Open FileName For Binary As #1
H = "This is a DEMO !"
Put #1, , H
Put #1, Istart, DatBuf
Close #1
End Sub

Private Sub Form_Load()
FileName = "demo.dat"
Istart = 17 '文件字节从1起算
Lrec = 32767
End Sub
  • 打赏
  • 举报
回复
比如读取指针为2-20的数据保存到一个数组中?
也可以把一个结构直接保存为一个文件。反过来如果要从文件中把相应的结构再还原成数组那也应该是可以的。
假如一个文件中保存了5个数组的数据,每个数组占用多少字节,这个是要精确记录好的。然后还原数组。
假如3-20才是一个数组的完整内容,你少了一个字节就没法还原。
这就像是一个你看不懂的WAV录音文件一样,其实他可能是由很多个小小的片断声音字节组成的。EXE也是有他自个的PE结构.
qq:2776478814,可以一起研究
脆皮大雪糕 2018-09-03
  • 打赏
  • 举报
回复
他的分段读取无非就是觉得一条一条循环读太慢,一口气读的话又怕自己无法把控。
我给的代码也就一简单用例,告诉他程序能做到什么,让他放开手脚干。然后要注意我在帖子中的提示:
“实际使用这段代码的时候自己搞清楚数据结构,算清楚读取的起止偏移,自己算清楚数组的大小。”
of123 2018-09-03
  • 打赏
  • 举报
回复
其实楼主不是想全文件读取,是要读其中的一段。

试试:
    Dim bytData(20-2) As Byte

Open App.Path & "\data.dat" For Binary As #1
Get #1, 2, bytData
Close #1

脆皮大雪糕 2018-08-31
  • 打赏
  • 举报
回复




数据弄到100兆
用上面的代码读入
一秒不到,而且是你要的数据结构。
满足了么?
结贴吧。
脆皮大雪糕 2018-08-31
  • 打赏
  • 举报
回复
引用 6 楼 FrankWang 的回复:
这样读取的都是BYTE吧,要转TYPE格式的话就比较麻烦了不

引用 4楼 FrankWang 的回复:
文件很大没办法读取到数组中




其实就是懒,我懒得把代码写完整,你也懒得改改代码试一下,好人做到底,按你的type改一下代码。


Option Explicit
Private Type TyData
a As Long
b As Long
End Type

Private Sub Command1_Click()
Dim aryInput() As TyData

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.dat") / 8 - 1) '因为tydata的长度为8个字节
Open "B:\1.dat" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub


用来测试的数据如下,懒得多造,就造16个字节,一次性读进来。实际使用这段代码的时候自己搞清楚数据结构,算清楚读取的起止偏移,自己算清楚数组的大小。
不要怕大,100兆的文件也可以这么读,超过读取时间超过10秒算我输。读进来你的程序崩溃我请吃饭

数据在UE里面编辑如下。自己搞清楚数据的格式哈。


执行后效果如下
笨狗先飞 2018-08-30
  • 打赏
  • 举报
回复
就像楼上说的,用Binary模式来打开文件,而且Get语句可以定位到你想要读的那块文件位置,然后读一个指定数组大小的数据上来。
脆皮大雪糕 2018-08-30
  • 打赏
  • 举报
回复
一口气把文件直接读入内存的例子,然后你再慢慢处理。


Private Sub Command2_Click()
Dim aryInput() As Byte

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.txt") ) '按照文件长度设置数据读取内存大小
Open "B:\1.txt" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub
舉杯邀明月 2018-08-30
  • 打赏
  • 举报
回复
你要“区块”读取,应该用Binary模式操作文件才行吧!

如果要想读写“结构体数组”的“中间一段元素”,
1维数组比较好办,可以把这个对应的“数据区”绑定到一个Byte数组上,并设置相应的字节大小,
  然后就可以直接通过字节数组来“读一片数据”了。
多维的话就比较麻烦了,因为VB6的多维数组,与“平常认为”的存储顺序不一样。
舉杯邀明月 2018-08-30
  • 打赏
  • 举报
回复
你是说后面的300次“区块读取”,比前面的90000次“单个读取”还慢?
感觉不会这样吧。
FrankWang 2018-08-30
  • 打赏
  • 举报
回复
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type GzGdType
GD(3) As Byte
Dx(3) As Byte
End Type
Private Type TerrInfo
GD As Byte
index As Byte
GDtype As GzGdType
G As Byte
G1 As Byte
G2 As Byte
G3 As Byte
G4 As Byte
End Type

Private Sub Command1_Click()
Open "e:\Terr.map" For Random As #15 Len = 15
Open "e:\Terr.map" For Binary As #1 Len = 15
Dim tempdata(300) As TerrInfo
c = GetTickCount()
ReDim TempMapData(300, 300) As TerrInfo
For i = 0 To 300
For j = 0 To 300
Get #15, 2 + (i) + (j) * 5000, TempMapData(i, j)
Next
Next
d = GetTickCount()
c1 = d - c
c = GetTickCount()
For j = 0 To 300
Get #1, 2 + (j) * 5000, tempdata()
Next j
d = GetTickCount()
c2 = d - c
MsgBox ("分个读取:" & c1 & "区块读取:" & c2)
Close #15
Close #1
End Sub

先不说读取是否正确,反而变慢了呢
FrankWang 2018-08-30
  • 打赏
  • 举报
回复
引用 1 楼 Chen8013 的回复:
你要“区块”读取,应该用Binary模式操作文件才行吧!

如果要想读写“结构体数组”的“中间一段元素”,
1维数组比较好办,可以把这个对应的“数据区”绑定到一个Byte数组上,并设置相应的字节大小,
  然后就可以直接通过字节数组来“读一片数据”了。
多维的话就比较麻烦了,因为VB6的多维数组,与“平常认为”的存储顺序不一样。

你这个可以举例个代码吗?带TYPE的呢?谢谢
舉杯邀明月 2018-08-30
  • 打赏
  • 举报
回复
引用 6 楼 FrankWang 的回复:
[quote=引用 5 楼 bakw 的回复:]
[quote=引用 4 楼 FrankWang 的回复:]
[quote=引用 2 楼 chewinggum 的回复:]
一口气把文件直接读入内存的例子,然后你再慢慢处理。


Private Sub Command2_Click()
Dim aryInput() As Byte

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.txt") ) '按照文件长度设置数据读取内存大小
Open "B:\1.txt" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub

文件很大没办法读取到数组中[/quote]
分开读 Get #1, XXXX , aryInput 指定一下读写位置就好了[/quote]
这样读取的都是BYTE吧,要转TYPE格式的话就比较麻烦了不[/quote]
我说的方法就“不麻烦”,你“读到字节数组”内时,它实际同时就已经放入你的“结构体数组”对应的元素中了。

并且,要“写入文件”也是一样。
of123 2018-08-30
  • 打赏
  • 举报
回复
引用 6 楼 FrankWang 的回复:
[quote=引用 5 楼 bakw 的回复:]
[quote=引用 4 楼 FrankWang 的回复:]
[quote=引用 2 楼 chewinggum 的回复:]
一口气把文件直接读入内存的例子,然后你再慢慢处理。


Private Sub Command2_Click()
Dim aryInput() As Byte

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.txt") ) '按照文件长度设置数据读取内存大小
Open "B:\1.txt" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub

文件很大没办法读取到数组中[/quote]
分开读 Get #1, XXXX , aryInput 指定一下读写位置就好了[/quote]
这样读取的都是BYTE吧,要转TYPE格式的话就比较麻烦了不[/quote]
不麻烦。如果你要转成字符串,用 StrConv 函数就可以了。
FrankWang 2018-08-30
  • 打赏
  • 举报
回复
引用 5 楼 bakw 的回复:
[quote=引用 4 楼 FrankWang 的回复:]
[quote=引用 2 楼 chewinggum 的回复:]
一口气把文件直接读入内存的例子,然后你再慢慢处理。


Private Sub Command2_Click()
Dim aryInput() As Byte

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.txt") ) '按照文件长度设置数据读取内存大小
Open "B:\1.txt" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub

文件很大没办法读取到数组中[/quote]
分开读 Get #1, XXXX , aryInput 指定一下读写位置就好了[/quote]
这样读取的都是BYTE吧,要转TYPE格式的话就比较麻烦了不
笨狗先飞 2018-08-30
  • 打赏
  • 举报
回复
引用 4 楼 FrankWang 的回复:
[quote=引用 2 楼 chewinggum 的回复:]
一口气把文件直接读入内存的例子,然后你再慢慢处理。


Private Sub Command2_Click()
Dim aryInput() As Byte

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.txt") ) '按照文件长度设置数据读取内存大小
Open "B:\1.txt" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub

文件很大没办法读取到数组中[/quote]
分开读 Get #1, XXXX , aryInput 指定一下读写位置就好了
FrankWang 2018-08-30
  • 打赏
  • 举报
回复
引用 2 楼 chewinggum 的回复:
一口气把文件直接读入内存的例子,然后你再慢慢处理。


Private Sub Command2_Click()
Dim aryInput() As Byte

Debug.Print Now(), "开始"
ReDim aryInput(FileLen("B:\1.txt") ) '按照文件长度设置数据读取内存大小
Open "B:\1.txt" For Binary As #1
Get #1, , aryInput
Close #1
Debug.Print Now(), "输入文件读取完毕"

End Sub

文件很大没办法读取到数组中

7,763

社区成员

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

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