Delphi Pascal - 使用 SetFilePointerEx 和 GetFileSizeEx,在作为文件读取时获取物理媒体的确切大小 [英] Delphi Pascal - Using SetFilePointerEx and GetFileSizeEx, Getting Physical Media exact size when reading as a file

查看:21
本文介绍了Delphi Pascal - 使用 SetFilePointerEx 和 GetFileSizeEx,在作为文件读取时获取物理媒体的确切大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何使用任何不在 RTL 中的 API.我一直在使用 SetFilePointer 和 GetFileSize 将物理磁盘读入缓冲区并将其转储到文件中,类似这样的循环可以完成 2GB 以下的闪存卡的工作:

I do not know how to use any API that is not in the RTL. I have been using SetFilePointer and GetFileSize to read a Physical Disk into a buffer and dump it to a file, something like this in a loop does the job for flash memory cards under 2GB:

SetFilePointer(PD,0,nil,FILE_BEGIN);
SetLength(Buffer,512);
ReadFile(PD,Buffer[0],512,BytesReturned,nil);

然而,GetFileSize 有 2GB 的限制,SetFilePointer 也是如此.我完全不知道如何删除外部 API,我查看了 RTL 并在谷歌上搜索了许多示例,但没有找到正确的答案.

However GetFileSize has a limit at 2GB and so does SetFilePointer. I have absolutley no idea how to delcare an external API, I have looked at the RTL and googled for many examples and have found no correct answer.

我试过了

function GetFileSizeEx(hFile: THandle; lpFileSizeHigh: Pointer): DWORD; 
    external 'kernel32';

并按照建议

function GetFileSizeEx(hFile: THandle; var FileSize: Int64): DWORD;
    stdcall; external 'kernel32';

但是,即使我使用的是有效的磁盘句柄,我已经确认并转储了使用旧 API 的数据,但该函数仍返回 0.

But the function returns a 0 even though I am using a valid disk handle which I have confirmed and dumped data from using the older API's.

我使用 SetFilePointer 每 512 字节跳转,使用 ReadFile 写入缓冲区,相反,当我使用 WriteFile 将初始程序加载程序代码或其他内容写入磁盘时,我可以使用它进行设置.我需要能够将文件指针设置为超过 2gb.

I am using SetFilePointer to jump every 512 bytes and ReadFile to write into a buffer, in reverse I can use it to set when I am using WriteFile to write Initial Program Loader Code or something else to the disk. I need to be able to set the file pointer beyond 2gb well beyond.

有人可以帮助我进行外部声明并调用 GetFileSizeEx 和 SetFilePointerEx 工作,以便我可以修改旧代码以使用 4 到 32gb 闪存卡.

Can someone help me make the external declarations and a call to both GetFileSizeEx and SetFilePointerEx that work so I can modify my older code to work with say 4 to 32gb flash cards.

推荐答案

我建议你看看这个 Primoz Gabrijelcic 博客文章 和他的 GpHugeFile 单元应该给你足够的指导获取文件大小.

I suggest that you take a look at this Primoz Gabrijelcic blog article and his GpHugeFile unit which should give you enough pointers to get the file size.

编辑 1鉴于对问题的编辑,这现在看起来相当愚蠢.

Edit 1 This looks rather a daft answer now in light of the edit to the question.

编辑 2 现在这个答案已经被接受,在对 jachgate 的答案发表了很长的评论之后,我觉得有必要总结一下所学到的东西.

Edit 2 Now that this answer has been accepted, following a long threads of comments to jachguate's answer, I feel it incumbent to summarise what has been learnt.

  • GetFileSize and SetFilePointer have no 2GB limitation, they can be used on files of essentially arbitrary size.

GetFileSizeExSetFilePointerEx 很多更易于使用,因为它们有效直接使用 64 位数量和有更简单的错误条件信号.

GetFileSizeEx and SetFilePointerEx are much easier to use because they work directly with 64 bit quantities and have far simpler error condition signals.

OP 实际上不需要计算他的磁盘的大小.自从OP正在阅读整个磁盘的内容大小不是需要.所需要的只是依次读取内容直到什么都没有了.

The OP did not in fact need to calculate the size of his disk. Since the OP was reading the entire contents of the disk the size was not needed. All that was required was to read the contents sequentially until there was nothing left.

事实上GetFileSize/GetFileSizeEx不支持设备句柄(例如物理磁盘或卷)作为是 OP 要求的.更重要的是,SetFilePointer/SetFilePointerEx无法搜索到此类设备的末尾处理.

In fact GetFileSize/GetFileSizeEx do not support handles to devices (e.g. a physical disk or volume) as was requested by the OP. What's more, SetFilePointer/SetFilePointerEx cannot seek to the end of such device handles.

为了获得一个磁盘、卷或分区,应该通过IOCTL_DISK_GET_LENGTH_INFO控制代码DeviceIoControl.

In order to obtain the size of a disk, volume or partition, one should pass the the IOCTL_DISK_GET_LENGTH_INFO control code to DeviceIoControl.

最后,是否需要使用 GetFileSizeExSetFilePointerEx 那么它们可以声明如下:

Finally, should you need to use GetFileSizeEx and SetFilePointerEx then they can be declared as follows:

function GetFileSizeEx(hFile: THandle; var lpFileSize: Int64): BOOL;
    stdcall; external 'kernel32.dll';
function SetFilePointerEx(hFile: THandle; liDistanceToMove: Int64;
    lpNewFilePointer: PInt64; dwMoveMethod: DWORD): BOOL;
    stdcall; external 'kernel32.dll';

获取这些 API 导入的一种简单方法是通过优秀的 JEDI API 库.

One easy way to obtain these API imports them is through the excellent JEDI API Library.

这篇关于Delphi Pascal - 使用 SetFilePointerEx 和 GetFileSizeEx,在作为文件读取时获取物理媒体的确切大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆