65.9K
CodeProject is changing. Read more.
Home

Bypassing ftell/fseek's 2gb limitation

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (12 votes)

Jan 29, 2005

2 min read

viewsIcon

92444

Instructions on how to implement _fseeki64 and _ftelli64.

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!

Points of Interest

Does anyone know why _fseeki64 and _ftelli64 are completely, mysteriously undocumented?