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的数据保存到一个数组中
...全文
2108 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

文件很大没办法读取到数组中
RAR 是一个让你在命令行模式中管理压缩文件的控制台应用。RAR 提供压缩、加 密、数据恢复和许多其它此手册中描述的其它功能。 RAR 只支持 RAR 格式压缩文件,它默认有 .rar 扩展名。不支持ZIP 和其他格 式。即使创建压缩文件时指定了 .zip 扩展名,它仍然是 RAR 格式的。Windows 用户 可以 WinRAR,它支持更多的压缩文件类型,包括 RAR 和 ZIP 格式。 WinRAR 提供了图形用户界面和命令行模式。虽然控制台 RAR 和图形界面 WinRAR 有相似的命令行语法,但是它们还有有一些不同。所以推荐使用此 rar.txt 手册用于 控制台 RAR(rar.exe 在 Windows 版本的情况下),winrar.chm 是图形界面 WinRAR (winrar.exe) 的帮助文件。 配置文件 ~~~~~~~~ Unix 版本的 RAR 从用户的 home 或 /etc 目录中的 .rarrc 文件读取配置文件信息 (存储在 HOME 环境变量中) Windows 的版本 RAR 从 rar.ini 文件读取配置文件信息,它放在 rar.exe 文件相 同的目录中。 这个文件包含下列字符串: switches=任何 RAR 开关,用空格分开 例如: switches=-m5 -s 环境变量 ~~~~~~~~ 可以通过建立"RAR"环境变量来添加默认参数到命令行中. 例如,在 Unix 中,下列命令行可以被添加到你的配置中: RAR='-s -md1024' export RAR RAR 将使用这个字符串作为命令行的默认参数,并将使用 1024KB 字典大小来创建 “固实”压缩文件。 RAR 控制选项使用下列优先级: 命名行开关 最高优先级 在 RAR 变量中的开关 低优先级 保存在配置文件中的开关 最低优先级 日志文件 ~~~~~~~~ 如果在命令行或配置文件中指定开关 -ilog ,RAR 将会把处理压缩文件中遇到的错误 等写到日志文件中。读取开关 -ilog 描述获得更多信息。 固实压缩的文件列表 - rarfiles.lst ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rarfiles.lst 包含一个用户定义的文件列表,告诉 RAR 添加文件到固实压缩文件时的顺 序。它可以包含文件名通配符和指定项目 -$default。默认项目定义了这个文件中与 其他项目不相符时的顺序清单位置。 注释字符是 ';'. 在 Windows 中,这个文件应该放在 RAR 所在的或 %APPDATA%\WinRAR 目录中, 在 Unix 中- 放在用户的 home 目录或在 /etc 中。 提高压缩率和操作速度的提示: - 在压缩文件中,小文件应该被组织在一起; - 频繁被处理的文件应该放在开始的位置。 普通的掩码越靠近顶端优先权就越高,但是这个规则存在例外。如果 rarfiles.lst 包含两个掩码,并且所有文件既匹配第一个掩码,也匹配第二个掩码, 较小的子集 或者更精确的匹配拥有更高的优先权。例如,如果你用 *.cpp 和 f*.cpp 掩码, f*.cpp 拥有更高的优先权。 RAR 命令行语法 ~~~~~~~~~~~~~~ 语法 RAR [ - ] [ ] [ ] [ ] 描述 命令行选项 (命令和开关) 提供了使用 RAR 创建和管理压缩文件的控制方法。命 令是一个字符串(或单个的字母),命令 RAR 去执行一个相应的操作。开关被用来 改变 RAR 执行操作的方法。其它参数是压缩文件名和被压缩的文件或要从压缩文件 中被解压文件。 列表文件是一个包括处理的文件名的纯文本文件。第一列应该以文件名开始。可以 在//字符后添加注释。例如,你可以创建包含下列字符串的 backup.lst: c:\work\doc\*.txt //备份文本文档 c:\work\image\*.bmp //备份图片 c:\

7,762

社区成员

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

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