[Win32utils-devel] win32-file, overlapped added
win32utils-devel at rubyforge.org
win32utils-devel at rubyforge.org
Mon Nov 22 19:26:00 EST 2004
Hi,
>
> > The problem is due to ReadFile cannot read large file at one
> > call in case of larger than 0x3000000 bytes with
> > NO_BUFFERING. I tested using while loop and it works. Just
> > borrow some code from it again.:)
>
> I must be dense, because even if I try to use that option on a small
> file, I get "the parameter is incorrect". What am I missing?
>
> Dan
>
Here is my test code for case NO_BUFFERING:
int getsectorcount(int x,char* str) { /*a function that returns number of sectors in file*sectorsize */
DWORD y[4];
if(GetDiskFreeSpace(str,&y[0],&y[1],&y[2],&y[3])==0)
rb_raise(cFileError,ErrorDescription(GetLastError()));
y[0]=x%y[1];
if(y[0]!=0)x+=y[1]-y[0];
return x;
}
/*
* Uses the native ReadFile() behind the scenes.
*/
static VALUE file_nread(int argc, VALUE* argv, VALUE self){
OVERLAPPED olap;
OpenFile *fptr;
int fd;
BOOL rv;
HANDLE hFile;
DWORD dwBytesToRead, dwBytesRead;
int dwToRead, dwRead;
VALUE rbLength, rbOffset, rbBuffer;
char* lpBuffer = NULL;
char* lpPtr = NULL;
VALUE rbPath;
char lpPath[256];
rbPath = file_get_path(self);
strcpy(lpPath,StringValuePtr(rbPath));
lpPath[3] = 0;
rb_scan_args(argc,argv,"02",&rbLength,&rbOffset);
GetOpenFile(self, fptr);
fd = _fileno(fptr->f);
hFile = (HANDLE)_get_osfhandle(fd);
memset(&olap, 0, sizeof(OVERLAPPED));
olap.Offset = 0;
olap.OffsetHigh = 0;
olap.hEvent = NULL; // TODO: Allow Win32::Event object
if(Qnil != rbOffset)
olap.Offset = NUM2INT(rbOffset);
if(hFile == INVALID_HANDLE_VALUE)
rb_raise(cFileError,ErrorDescription(GetLastError()));
if(NIL_P(rbLength)){
dwBytesToRead = GetFileSize(hFile,NULL);
}
else{
dwBytesToRead = NUM2UINT(rbLength);
}
lpBuffer = malloc(getsectorcount(dwBytesToRead,lpPath));
memset(lpBuffer,0x00,dwBytesToRead);
if(NULL == lpBuffer)
rb_raise(cFileError,"malloc() call failed in nread() method");
lpPtr = lpBuffer;
dwRead = 0;
dwToRead = getsectorcount(dwBytesToRead,lpPath);
if(dwBytesToRead>0x1000000)
while(dwToRead>0) {
if(dwToRead>0x1000000)
rv = ReadFile(
hFile,
(LPVOID)lpPtr,
0x1000000,
&dwRead,
&olap
);
else
rv = ReadFile(
hFile,
(LPVOID)lpPtr,
dwToRead,
&dwRead,
&olap
);
if(0 == rv)
rb_raise(cFileError,ErrorDescription(GetLastError()));
lpPtr += 0x1000000;
dwToRead -= 0x1000000;
dwBytesRead += dwRead;
}
else
{
rv = ReadFile(
hFile,
(LPVOID)lpPtr,
dwToRead,
&dwBytesRead,
&olap
);
if(0 == rv)
rb_raise(cFileError,ErrorDescription(GetLastError()));
}
if(dwBytesToRead != dwBytesRead)
rb_raise(cFileError,"bytes to read != bytes actually read");
// This exchange is necessary so that we don't have a memory leak (I think)
rbBuffer = rb_str_new(lpBuffer,dwBytesRead);
free(lpBuffer);
return rbBuffer;
}
Regards,
Park Heesob
--MIME Multi-part separator--
More information about the win32utils-devel
mailing list