Friday, May 3, 2024
 Popular · Latest · Hot · Upcoming
3
rated 0 times [  3] [ 0]  / answers: 1 / hits: 1248  / 1 Year ago, fri, march 3, 2023, 9:52:21

I've reviewed a number of answers for compiling code to make it read/write files beyond the 4GB max allowed by 32bit file offsets. I'm not having luck with any of the "simple" solutions that I'm finding.



The gist is I've got Ubuntu Server 11.10 running on a small laptop (32 bit Intel architecture). I'm trying to read a unicode file that is 343868522737 bytes in size (0x50102940f1). The Ubuntu machine keeps thinking it is much smaller (0x102940f1) which turns out to be only the lower 32 bits of a true 64bit sized file.



I wrote a small program that I've compiled on a MacOS and on the Ubuntu box. The Mac seems to behave correctly, the Ubuntu box does not.



The small program is below. While I've commented out a block of code, that is really only necessary for the Mac. Ubuntu environment will compile both blocks of code fine - and generates exactly the same response for both blocks.



// Necessary for Ubuntu build?
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
//#include <features.h>
// finish Ubuntu

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>

// Ubuntu version
off64_t fileMaxLen(FILE* fin) {
off64_t fmaxlen = 0;
if( (fin!=NULL) && (fseeko64(fin,0,SEEK_END) == 0) ) {
fmaxlen = ftello64(fin);
fprintf(stdout,"fileMaxLen(): file length is: %#lx
",(long unsigned int)fmaxlen);
fseeko64(fin,0,SEEK_SET);
}
}

// Mac OS version
//off_t fileMaxLen(FILE* fin) {
// off_t fmaxlen = 0;
// if( (fin!=NULL) && (fseeko(fin,0,SEEK_END) == 0) ) {
// fmaxlen = ftello(fin);
// fprintf(stdout,"fileMaxLen(): file length is: %#lx
",(long unsigned int)fmaxlen);
// fseeko(fin,0,SEEK_SET);
// }
//}

main(int argc, char* argv[]) {
char fname[255];
char *locale;
FILE* f = NULL;

locale = setlocale(LC_ALL, "");

if( argc>=2 ) {
// get the file for segmenting
memset(fname, '0', 255);
sprintf(fname,"%s",argv[1]);
fprintf(stdout,"Opening: %s
",fname);
f = fopen(fname,"r");
fileMaxLen(f);
fprintf(stdout,"Done!
");
} else {
fprintf(stdout,"Need a filename
");
}
}


Save the snippet as file_test.c, then the compile is really simple.



gcc file_test.c



Then run the a.out



Any suggestions for getting this code to recognize files beyond that 32bit boundary? At this point I'm simply stumped.


More From » 64-bit

 Answers
6

According to this, the size of long unsigned int on 32-bit Unix is 4 bytes - can it be that the value is trimmed where you're casting fmaxlen to (long unsigned int)?


[#40989] Saturday, March 4, 2023, 1 Year  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
irtuallyefu

Total Points: 429
Total Questions: 97
Total Answers: 119

Location: Hong Kong
Member since Tue, Oct 19, 2021
3 Years ago
irtuallyefu questions
;