Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SEEK TO FILE POSITION > 2GIG
#1
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
Reply
#2
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.
color=blue]subxero - admin at this place.[/color]
Reply
#3
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.
Reply
#4
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.
Reply
#5
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
Reply
#6
I also hate to say that PB's seek function takes a 64 bit quad integer.
Reply
#7
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
Reply
#8
Here's the links to the files:


http://www.cct.com/lib/file64.h
http://www.cct.com/lib/file64.cpp
http://www.cct.com/lib/file64.lib


Hope this works.

Dean
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)