当文件的定位区域小于2g时用下面的方式就可以正确定位
SetFilePointer hdlSRCFile, NowsSart, ByVal 0&, FILE_BEGIN
当定位区域超过2g时也就是nowstart的数值大于2g时,就会溢出,看了一下网上的说明,SetFilePointer可以用高低位的方式为定位超2g的文件支持64bit
但小弟不知这个高低位应该是怎么算出来呢?
在SetFilePointer hdlSRCFile, NowsSart, ByVal 0&, FILE_BEGIN
中应该怎么写呢?例如nowstart现在的值需要为2146959360也就是说超过2g时,直接将nowstart设为该值,肯定要益出,那么设成高低位该怎么写呢
还望高人们写个简单的例子就成了。。小弟感激不尽啊。
SetFilePointer hdlSRCFile, NowsSart, ByVal 0&, FILE_BEGIN
当定位区域超过2g时也就是nowstart的数值大于2g时,就会溢出,看了一下网上的说明,SetFilePointer可以用高低位的方式为定位超2g的文件支持64bit
但小弟不知这个高低位应该是怎么算出来呢?
在SetFilePointer hdlSRCFile, NowsSart, ByVal 0&, FILE_BEGIN
中应该怎么写呢?例如nowstart现在的值需要为2146959360也就是说超过2g时,直接将nowstart设为该值,肯定要益出,那么设成高低位该怎么写呢
还望高人们写个简单的例子就成了。。小弟感激不尽啊。
解决方案 »
- 选中
- 五个内裤了,散分~~~~~~~~~~~~
- 如何用功能键F1结束关闭程序?
- toolbar简单问题
- 小弟的菜鸟问题,哪位好心的大哥帮帮我啊,谢谢啦!
- VB中怎样实现压缩ACCESS数据库?
- 奇怪的问题,我有一个MDIForm,菜单上加了一个"退出",还有窗体右上方的"X"
- 我在pb中使用ole控件调word,发现自动屏蔽了word的file菜单,如何编写VBA脚本可以实现WORD的打印
- 如何得到一个容器控件(如Frame, PictureBox)上的所有控件的TEXT属性的内容呢?
- 编好的VB程序如何制作key盘(软盘)
- VB关于半角全角数字的问题
- Microsoft Jet 数据库引擎找不到对象'Sheet1$
SetFilePointer hdlSRCFile, NowsSart,2146959360, FILE_BEGIN
这样???那前面该填什么呢?
小弟对于变量之类的东东还有数学基础很差,还望高人指点。
是否应该这样呢?
SetFilePointer hdlSRCFile, 2147483647,2146959360-2147483647, FILE_BEGIN
我这样写好向没有益出,但结果好向不对。。
看起来就是Size2Long Position, PosL, PosH这里是关键,可我怎么看它们之间也没办法联系起来呀,都是sub没有返回参数。posl,posh是从哪里来的呢????55~~~~~~高人要是能提醒一下就好了。Size2Long关键应该就是在这里,可我看里面的ByRef LongLow As Long, ByRef LongHigh As Long并没有输出啊。真的是搞不明白了,,,,Public Sub API_ReadFile(ByVal FileNumber As Long, ByVal Position As Currency, ByRef BlockSize As Long, ByRef Data() As Byte)
Dim PosL As Long
Dim PosH As Long
Dim SizeRead As Long
Dim Ret As Long
Size2Long Position, PosL, PosH
Ret = SetFilePointer(FileNumber, PosL, PosH, FILE_BEGIN)
Ret = ReadFile(FileNumber, Data(0), BlockSize, SizeRead, 0&)
BlockSize = SizeRead
End SubPrivate Sub Size2Long(ByVal FileSize As Currency, ByRef LongLow As Long, ByRef LongHigh As Long)
'&HFFFFFFFF unsigned = 4294967295
Dim Cutoff As Currency
Cutoff = 2147483647
Cutoff = Cutoff + 2147483647
Cutoff = Cutoff + 1 ' now we hold the value of 4294967295 and not -1
LongHigh = 0
Do Until FileSize < Cutoff
LongHigh = LongHigh + 1
FileSize = FileSize - Cutoff
Loop
If FileSize > 2147483647 Then
LongLow = -CLng(Cutoff - (FileSize - 1))
Else
LongLow = CLng(FileSize)
End If
End SubPrivate Sub Long2Size(ByVal LongLow As Long, ByVal LongHigh As Long, ByRef FileSize As Currency)
Dim Cutoff As Currency
Cutoff = 2147483647
Cutoff = Cutoff + 2147483647
Cutoff = Cutoff + 1
FileSize = Cutoff * LongHigh
If LongLow < 0 Then
FileSize = FileSize + (Cutoff + (LongLow + 1))
Else
FileSize = FileSize + LongLow
End If
End Sub
FileKB是Currency变量
并且filekb=大于2g的数
用此种方法Size2Long filekb, LongLow, LongHigh
SetFilePointer hdlSRCFile, LongLow, LongHigh, FILE_BEGIN
Private Sub Size2Long(ByVal FileSize As Currency, ByRef LongLow As Long, ByRef LongHigh As Long)
'&HFFFFFFFF unsigned = 4294967295
Dim Cutoff As Currency
Cutoff = 2147483647
Cutoff = Cutoff + 2147483647
Cutoff = Cutoff + 1 ' now we hold the value of 4294967295 and not -1
LongHigh = 0
Do Until FileSize < Cutoff
LongHigh = LongHigh + 1
FileSize = FileSize - Cutoff
Loop
If FileSize > 2147483647 Then
LongLow = -CLng(Cutoff - (FileSize - 1))
Else
LongLow = CLng(FileSize)
End If
End Sub
结果是 LongLow = -CLng(Cutoff - (FileSize - 1))益出。。
唉。上帝。
Dim hdlSRCFile As Long
Dim NowsStart As Currency
Dim lMoveLo As Long, lMoveHi As Long
...
NowsStart = 3146959360@ '假定这是你要定位的位置
Size2Long NowsStart, lMoveLo, lMoveHi '用你7楼的函数转换
SetFilePointer hdlSRCFile, lMoveLo, lMoveHi, FILE_BEGIN
End Sub
顾名思义,就是64位、8字节长的数据类型
在某些高级语言中有专门相对应的类型
在系统API中,有专门的LARGEINTEGER等结构来存放这种数
但不幸的是,VB中没有所谓的int64类型2. Currency类型
在VB中,与64位大整数的性质最相似的数据类型就是Currency了
Currency是一个可以用来存储64位大整数的,比较理想的基本数据类型。
Currency的取值范围是-922,337,203,685,477.5808 到 922,337,203,685,477.5807,
在内存中的表示形式为从 &H8000000000000000 到 &H7FFFFFFFFFFFFFFF
但是要注意的是,该类型数值的最后四位在VB中表现为小数部分,因此,你虽然在使用该类型进行计算时可以不去理会小数点,但在表现时却要将其乘上10000,变为整数3. 大文件处理
首先,文件大小、指针位置等需要用到64位大整数的地方都改用 Currency。其次,在实际使用时,或采取公式
函数中的移动距离 = 移动距离/10000,以配合Currency类型的特质以下为代码:首先是Currency类型和LARGEINTEGER结构之间的转换。这个东西比较简单,因为两个东西的内存布局是完全一样的,所以拿出CopyMemory即可。'货币类型转换为大整数结构
Public Function Currency2LargeInteger(ByVal curDistance As Currency) As LARGE_INTEGER
CopyMemory Currency2LargeInteger, curDistance, 8
End Function
'大整数结构转换为货币类型
Public Function LargeInteger2Currency(li As LARGE_INTEGER) As Currency
CopyMemory LargeInteger2Currency, li, 8
End Function接下去是对SetFilePointer的小小封装,参照了MSDN中的建议:Public Function MySeek(ByVal hFile As Long, ByVal curDistance As Currency, ByVal lMoveMethod As Long) As Currency
Dim li As LARGE_INTEGER
li = Currency2LargeInteger(curDistance)
li.lowpart = SetFilePointer(hFile, li.lowpart, li.highpart, lMoveMethod)
If li.lowpart = -1 Or Err.LastDllError <> 0 Then
li = Currency2LargeInteger(-1@)
End If
MySeek = LargeInteger2Currency(li)
Debug.Print "Seek to "; Hex(li.highpart); Hex(li.lowpart)
End Function
Public Const MOVEFILE_REPLACE_EXISTING = &H1
Public Const FILE_ATTRIBUTE_TEMPORARY = &H100
Public Const FILE_BEGIN = 0
Public Const FILE_SHARE_READ = &H1
Public Const FILE_SHARE_WRITE = &H2
Public Const CREATE_NEW = 1
Public Const OPEN_EXISTING = 3
Public Const GENERIC_READ = &H80000000
Public Const GENERIC_WRITE = &H40000000Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Any) As Long
Public Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Public Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Public Declare Function SetEndOfFile Lib "kernel32" (ByVal hFile As Long) As Long
' 32 bit
'signed int
'1000 0000 0000 0000 0000 0000 0000 0000
' =
'8000 0000 -> -2147483648
'
'0111 1111 1111 1111 1111 1111 1111 1111
' =
'7FFF FFFF -> 0 ~ 2^31-1 2147483647
'
'unsigned int
'1111 1111 1111 1111 1111 1111 1111 1111
' =
'FFFF FFFF -> 0 ~ 2^32-1 4294967295
'
' 64 bit
'signed int
'1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
' =
'8000 0000 0000 0000 -> -9223372036854775808
'
'0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
' =
'7FFF FFFF FFFF FFFF -> 0 ~ 2^63-1 9223372036854775807
' VB Currency 922337203685477.5807
'
'unsigned int
'1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
' =
'FFFF FFFF FFFF FFFF -> 0 ~ 2^64-1 18446744073709551615
Public Type LARGE_INTEGER
lowpart As Long
highpart As Long
End TypePublic Function Currency2LargeInteger(ByVal curDistance As Currency) As LARGE_INTEGER
CopyMemory Currency2LargeInteger, curDistance, 8
End FunctionPublic Function LargeInteger2Currency(li As LARGE_INTEGER) As Currency
CopyMemory LargeInteger2Currency, li, 8
End FunctionPublic Function MyOpen(ByVal sFileName As String) As Long
MyOpen = CreateFile(sFileName, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0, 0)
End FunctionPublic Function MySeek(ByVal hFile As Long, ByVal curDistance As Currency, ByVal lMoveMethod As Long) As Currency
Dim li As LARGE_INTEGER
li = Currency2LargeInteger(curDistance)
li.lowpart = SetFilePointer(hFile, li.lowpart, li.highpart, lMoveMethod)
If li.lowpart = -1 Or Err.LastDllError <> 0 Then
li = Currency2LargeInteger(-1@)
End If
MySeek = LargeInteger2Currency(li)
Debug.Print "Seek to "; Hex(li.highpart); Hex(li.lowpart)
End Function这里是窗体测试代码,我测试读取了一个2.38G的页面文件,偏移量2451374078处1个字节的内容Option Explicit
Private Sub Command1_Click()
Dim hFile As Long
hFile = MyOpen("c:\pagefile2.sys")
If hFile Then
Dim curPos As Currency
curPos = 2451374078@
Debug.Print MySeek(hFile, curPos / 10000@, FILE_BEGIN)
Dim b As Byte, lBytesRead As Long
ReadFile hFile, b, 1, lBytesRead, ByVal 0
Debug.Print b
CloseHandle hFile
End If
End Sub
特意转了进来,以后再有朋友有类似困扰就方便了,,,,,希望对大家有用。
'超过2g时利用指针定位SetFilePointer
Private Function SeekPosDouble(ByVal FHandle As Long, ByVal NewPos As Double) As Boolean
Dim SizeLow As Long, SizeHigh As Long
SizeLow = DoubleToLongs(NewPos, SizeHigh)
SeekPosDouble = SeekPos(FHandle, SizeLow, SizeHigh)
End FunctionPrivate Function SeekPos(ByVal FHandle As Long, ByVal NewPos As Long, Optional ByVal PosHigh As Long = 0) As Boolean
Dim Ret As Long, dwError As Long
Ret = SetFilePointer(FHandle, NewPos, PosHigh, FILE_BEGIN)If Ret = -1 Then
dwError = GetLastError
If dwError = NO_ERROR Then SeekPos = True
Else
SeekPos = True
End IfEnd FunctionPrivate Function DoubleToLongs(ByVal Dbl As Double, ByRef SizeHigh As Long) As Long
Dim SizeLowDbl As Double
SizeHigh = Fix(Dbl / 4294967296#)
SizeLowDbl = Dbl - SizeHigh * 4294967296#
If SizeLowDbl > 2147483647 Then
DoubleToLongs = CLng(SizeLowDbl - 2147483648#) Xor &H80000000
Else
DoubleToLongs = SizeLowDbl
End If
'---------------------------------------
End Function
然后后面的模块会将SetFilePointer 移到起点位置YES!!!!头疼的问题终于解决了,另外今天14点时,跟朋友反复调试,居然发现我下载时的数据超2g时crc校验不正确居然是因为控件版本没有正确换成最新的当时图方便用迅雷下载的控件,结果。。该死的。迅雷,害人啊此问题及FTP下载超2g问题搞了我正正2天。终于。YES了!
HANDLE hFile, // handle to file
LONG lDistanceToMove, // bytes to move pointer
PLONG lpDistanceToMoveHigh, // bytes to move pointer
DWORD dwMoveMethod // starting point
);
最後一個參數 可以有三值值
FILE_BEGIN 從開頭
FILE_CURRENT 從當前位 置
FILE_END 從文件尾,如果大於 4G,可以先用 SetFilePointer 把位置定到 4 G, 再用 SetFilePointer + FILE_CURRENT 再加一個新的位置上去
更簡單的方法是用
BOOL SetFilePointerEx(
HANDLE hFile, // handle to file
LARGE_INTEGER liDistanceToMove, // bytes to move pointer
PLARGE_INTEGER lpNewFilePointer, // new file pointer
DWORD dwMoveMethod // starting point
);
16楼的朋友,内存影射对这些大文件也能高效么?????现在小弟还处于初学阶段,对这些还不甚了解