To work with files, I use the functions C: fopen, fread, fwrite, fseek, ftell, fclose. fseek and ftell work with 32-bit numbers, but if the file is larger than 2 GB, then there will be problems. Visual C ++ has _ftelli64 and _fseeki64 functions, but it looks like this is a Microsoft extension. Is there any kind of cross-compiler analogue of these functions?

  • fseeko, ftello? - alexlz
  • I do not have such. - gammaker

3 answers 3

LSEEK64 (3) Linux Programmer's Manual LSEEK64 (3)

NAME

lseek64 - reposition 64-bit read / write file offset

SYNOPSIS

#define _LARGEFILE64_SOURCE #include <sys/types.h> #include <unistd.h> off64_t lseek64(int fd, off64_t offset, int whence); 

UPDATE

From stdio.h :

 #ifdef __USE_LARGEFILE64 extern FILE *fopen64 (__const char *__restrict __filename, __const char *__restrict __modes) __wur; extern FILE *freopen64 (__const char *__restrict __filename, __const char *__restrict __modes, FILE *__restrict __stream) __wur; #endif ... #ifdef __USE_LARGEFILE64 extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); extern __off64_t ftello64 (FILE *__stream) __wur; extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); extern int fsetpos64 (FILE *__stream, __const fpos64_t *__pos); #endif 

UPDATE 2

From MinGW/include/stdio.h "gcc in 32-bit Windows":

 #if __MSVCRT_VERSION__ >= 0x800 _CRTIMP int __cdecl __MINGW_NOTHROW _fseek_nolock (FILE*, long, int); _CRTIMP long __cdecl __MINGW_NOTHROW _ftell_nolock (FILE*); _CRTIMP int __cdecl __MINGW_NOTHROW _fseeki64 (FILE*, __int64, int); _CRTIMP __int64 __cdecl __MINGW_NOTHROW _ftelli64 (FILE*); _CRTIMP int __cdecl __MINGW_NOTHROW _fseeki64_nolock (FILE*, __int64, int); _CRTIMP __int64 __cdecl __MINGW_NOTHROW _ftelli64_nolock (FILE*); #endif 

Try it, maybe it will. Immediately I say, I did not try it myself and did not even look for info on them.

If it #ifedf , then wrap it in #ifedf in POSIX- fseeko() and ftello() for portability.

  • Well, the question was about sream input / output - alexlz
  • Sorry, updated for stream - avp
  • I do not have such. I connected stdio.h, but there are no functions for 64. I even tried to define the __USE_LARGEFILE64 macro before enabling it, but it did not help. Even search in stdio.h could not find. This is from which compiler? Maybe this is also an extension of a compiler? - gammaker
  • Linux avp-xub11 3.0.0-16-generic # 28-Ubuntu SMP Fri Jan 27 17:50:54 UTC 2012 i686 i686 i386 GNU / Linux gcc.real (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1 @GLmonster , you probably have the product B. Gates. I 'm sorry ... - avp
  • @GLmonster posix'om defined functions fseeko, ftello. But if the kit is from ms, then it is somewhat indecent to talk about posix. - alexlz

The following should be considered a comment to the discussion in the answer @avp , I just again did not meet the limitations of the comment;)

@GLmonster , the fgetpos and fsetpos functions work with the fpos_t structure, unfortunately, the standard defines this type of very vaguely:

It is not necessary to specify uniquely every position within a file.

From this formulation it is not clear whether in any file, in any system.

I did a little research (openSUSE Linux, 32-bit):

 // stdio.h #ifndef __USE_FILE_OFFSET64 typedef _G_fpos_t fpos_t; #else typedef _G_fpos64_t fpos_t; #endif // _G_config.h typedef struct { __off_t __pos; __mbstate_t __state; } _G_fpos_t; typedef struct { __off64_t __pos; __mbstate_t __state; } _G_fpos64_t; 

My constant __USE_FILE_OFFSET64 not defined. Thus, the choice of the type to represent the offset in the file is determined by the compiler, which does not make this approach cross-platform.

However, if I focus only on 64-bit platforms, the approach using fgetpos / fsetpos seems to me more portable than fseek / ftell. The fseek / ftell function interface uses long int to represent the offset, and if you believe the data model table , long int can be 32-bit on a 64-bit platform. At the same time, fgetpos / fsetpos are based on the off_t memsize-type. The same is true of the Data Size Neutrality and 64-bit Support article at unix.org. See the Porting issues section:

Use utilities such as the following:
...
- The functions lseek() , fseek() , ftell() , fgetpos() , and so on. Use either off_t or fpos_t as appropriate for offset arguments. Do not use file offsets.

In general, thanks for the question, interesting food for thought and discussion with students;)

  • My fpos_t is defined differently: #if defined ( POSIX ) typedef long fpos_t; #define FPOSOFF (fp) ((long) (fp)) #else / * _POSIX / #if! __ STDC__ / compat issues / typedef __int64 fpos_t; #define _FPOSOFF (fp) ((long) (fp)) #else typedef long long fpos_t; #define _FPOSOFF (fp) ((long) (fp)) #endif #endif / POSIX * / #define _FPOS_T_DEFINED #endif - gammaker
  • > the fgetpos and fsetpos functions work with the fpos_t structure, unfortunately, the standard defines this type very vaguely. Well, okay. The question is no longer so relevant, because I plan to rewrite my project on D. Everything has been done much more carefully than in C ++. - gammaker
  • @GLmonster, you are fine. Do not bother with the absolute portability of your programs. In real life, the program, which may require some refinement for the existing infrastructure of a particular customer, is a gain. (And personally the author (team) too) - avp

In my opinion, you need to look in the direction of the files being projected into memory. You can read more in the book "Jeffrey Richter, Christoph Nazar - Windows via C / C ++. Programming in Visual C ++" Chapter 17. Memory-Projected Files

  • I myself know how to work with large files using Windows tools (the SetFilePointerEx function). I did just that, but then I decided to redo it into functions from the standard library to make the code cross-platform. - gammaker
  • I can not say for sure how crossformatism is possible in this case and whether it will work quickly, especially as a limitation at the level of the operating system. Moreover, if you want to write 64-bit code, it will work differently on different machines. Here everything depends on the capabilities of the operating system, and not on the capabilities of the programming language - theathlet
  • What does the OS? Large files can be in absolutely any OS. Any OS should be able to work with files> 2 GB. > Especially if you want to write 64-bit code, it will work differently on different machines. In a sense, in different ways? And where does the 64-bit code come in? You need to work with large files in 32-bit too. - gammaker
  • You need to work with large files in 32-bit too. Windows 95? - alexlz
  • > Any OS should be able to work with files> 2 GB. You yourself wrote "but if the file is more than 2 GB, then there will be problems" - theathlet