Posts: 67
Threads: 18
Joined: Jan 2005
The SEEK function in FB is (as far as I can tell) still limited
to a 4 byte integer, thereby limiting the maximum file size
you can access to 2.1 GIG.
In C (I am told by my coworkers here who are making fun
of me for coding in basic), there's the function:
_lseeki64
to allow you to go beyond that limitation. They say I need an include file of:
io.h
What can I do to shut them up? Can I use the crt.bi to do this?
Would be nice if the SEEK & PUT functions could simply handle
more than 4 byte integers.
Dean
Posts: 77
Threads: 27
Joined: Dec 2004
Try using a variable of type UNSIGNED INTEGER -- it's still four bytes, but doesn't allow negative numbers, thereby increasing the maximum size to 4 GB.
And tell them how much C sucks. If C were so wonderful, FreeBASIC wouldn't be written in FreeBASIC.
Posts: 39
Threads: 3
Joined: Apr 2005
There should be function in Win32 API with 64 bit parameter I think. You can encapsulate it with your func to make your code portable. Most C programmers I met are very ignorant persons that think that their language is only one on the Earth.
Posts: 922
Threads: 15
Joined: Jun 2003
There's no standard in C to use 64-bit offsets, that's why it wasn't implemented, and also because every file routine would have to be changed to support 64-bit offs, what would bloat the generated exe's due the long long int's support needed.
Posts: 67
Threads: 18
Joined: Jan 2005
For commercial or business applications, being limited to a 2GB
file size is a rather significant limitation. As for bloating, if that's
the case, then an option in the compiler can allow the user
to decide the priorites for a given application. The 2GB limit goes
back to the late 80's. Hard disks themselves were limited
to 1.2 gig. I can buy 300gig hard drives now for a few hundred
bucks. Business databases are very often > 2GB, so I do need
to figure out the work around for this. As far as encapsulating
the C function, perhaps someone could show me an example
since I'm not a C programmer. Or, maybe I can ask these
C programmers in my office to write some functions that resemble
basic syntax and make a .LIB that I can link to?
As for this C function that I mentioned, This is what I found out about it on MSDN:
Move a file pointer to the specified location.
long _lseek(
int fd,
long offset,
int origin
);
__int64 _lseeki64(
int fd,
__int64 offset,
int origin
);
Parameters
fd
File descriptor referring to open file.
offset
Number of bytes from origin.
origin
Initial position.
Return Value
_lseek returns the offset, in bytes, of the new position from the beginning of the file. _lseeki64 returns the offset in a 64-bit integer. The function returns â1L to indicate an error and sets errno either to EBADF, meaning the file descriptor is invalid, or to EINVAL, meaning the value for origin is invalid or the position specified by offset is before the beginning of the file. On devices incapable of seeking (such as terminals and printers), the return value is undefined.
See _doserrno, errno, _sys_errlist, and _sys_nerr for more information on these, and other, return codes.
And here's something I found out on TheCodeProject.com
(not that it makes much sense to me):
Introduction
Recently, I was working on completing a port of a Linux program to Windows. It's called mpgtx, and is a command line MPEG editing program. The port was pretty easy, since it didn't use many Linux-specific functions (and someone had already done part of the port), but I did run across one big problem: it would fail on any long MPEG-2 clip. I quickly realized that it was because the fseek/ftell functions use the data type long for file offsets, which is a 32-bit signed integer on most systems. Therefore, those functions don't work on files that are bigger than 2048 megabytes. I then searched around for information on getting around that problem, and the only info I found was on Linux-specific functions (fseeko/ftello) or a non-buffered function (_lseeki64). I didn't want to use Cygwin, and I really didn't want to convert all the fopen/fread/fseek/etc... function calls to _open/_read/_lseeki64/etc... and still maintain code compatibility with Linux, so I had to find another way. I thought that because there was a _lseeki64 function there might be a fseeki64 function, but nothing was mentioned about that function in the Help system and hardly anything was listed when searching Google for it. One thing Google did find, though, was a page that said there was a file named "fseeki64.c" in "crt/src". Sure enough, both the fseeki64.c and ftelli64.c files existed in my "Microsoft Visual Studio .NET 2003\Vc7\crt\src" folder. Unfortunately, neither function is mentioned in stdio.h, so it's going to take a little extra work to use those functions...
Using the code
First, you'll have to add the following imports into your code:
extern "C" int __cdecl _fseeki64(FILE *, __int64, int);
extern "C" __int64 __cdecl _ftelli64(FILE *);
Note that they use __in64 for the file offset data type, instead of long.
Next, replace all calls to fseek and ftell with _fseeki64 and _ftelli64, respectively. Finally, change all the variables that you use to hold file offsets from long to __int64. That's it; now you should be good to go!
Can someone maybe show me an example of how to call
these C functions, or encapsulate them, etc.?
Dean
Posts: 67
Threads: 18
Joined: Jan 2005
I also hate to say that PB's seek function takes a 64 bit quad integer.
Posts: 1,439
Threads: 15
Joined: Apr 2003
You won't be able to use those C functions with regular FB file handles, unless you want to use a hack something like this (untested):
Code:
option explicit
#include "crt.bi"
Declare function _fseeki64 CDecl Alias "_fseeki64" (Byval f As file Ptr, ByVal newpos as Longint, Byval relative_to as integer) as integer
Declare Function _ftelli64 CDecl Alias "_ftelli64" (ByVal f As File Ptr) As Longint
#define FB_MAX_FILES 255
Type FB_FILE
f As FILE Ptr
mode As Integer
_len As Integer
size As Integer
_type As Integer
_access As Integer
End Type
Extern _fb_fileTB Alias "fb_fileTB" As FB_FILE
Dim Shared fb_fileTB As FB_FILE Ptr
Sub InitFileTB()
fb_fileTB = @_fb_fileTB
End Sub
Sub Seek64(Byval filenum As Integer, Byval newpos As LongInt)
_fseeki64(fb_fileTB[filenum].f, newpos, SEEK_SET)
End Sub
Function Tell64(Byval filenum as integer) As longint
Tell64 = _ftelli(fb_fileTB[filenum].f)
End function
'' example
dim filenum As integer
filenum = freefile
open "test.dat" for binary access read as #filenum
Seek64 filenum, &H100000000
print #filenum, "this is a waste of disk space"
Print "file position after write: "; Tell64(filenum)
close #filenum
Posts: 67
Threads: 18
Joined: Jan 2005