Компиляция для доступа к 64-битным файлам

Я рассмотрел ряд ответов для компиляции кода, чтобы он мог читать / записывать файлы за пределы 4 ГБ, разрешенные 32-разрядными смещениями файлов. Мне не повезло ни с одним из «простых» решений, которые я нахожу.

Суть в том, что Ubuntu Server 11.10 работает на небольшом ноутбуке (32-битная архитектура Intel). Я пытаюсь прочитать файл unicode размером 343868522737 байт (0x50102940f1). Машина Ubuntu продолжает думать, что она намного меньше (0x102940f1), которая оказывается только младшими 32 битами истинного 64-битного файла.

Я написал небольшую программу, которую я скомпилировал на MacOS и в поле Ubuntu. Кажется, что Mac ведет себя правильно, в поле Ubuntu нет.

Маленькая программа ниже. Хотя я прокомментировал блок кода, это действительно необходимо только для Mac. Среда Ubuntu скомпилирует оба блока кода - и генерирует точно такой же ответ для обоих блоков.

// 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 \n",(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 \n",(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\n",fname);
        f = fopen(fname,"r");
        fileMaxLen(f);
        fprintf(stdout,"Done!\n");
    } else {
        fprintf(stdout,"Need a filename\n");
    }
}

Сохранить фрагмент как file_test.c, тогда компиляция действительно проста.

gcc file_test.c

Затем запустите a.out

Любые предложения для получения этого кода для распознавания файлов за пределами этой 32-битной границы? На данный момент я просто тупой.

1
задан 12 January 2012 в 13:01

3 ответа

В соответствии с этим размер long unsigned int в 32-разрядном Unix составляет 4 байта - может быть, это значение обрезается, когда вы производите fmaxlen (long unsigned int)?

2
ответ дан 25 May 2018 в 15:15
  • 1
    Это было полезно - спасибо. Да, похоже, что бросок делал усечение. Изменив приведение (long long unsigned int), а также изменив строку формата на% # llx, вы получили версию Ubuntu для создания правильного результата. – dwmc 12 January 2012 в 13:44

Согласно этому , размер long unsigned int в 32-разрядном Unix равен 4 байтам - может ли быть, что значение обрезается, когда вы производите fmaxlen (long unsigned int)?

2
ответ дан 10 August 2018 в 08:22

Вы можете найти документацию для макросов, контролирующих это поведение с помощью man feature_test_macros.

Из этой документации вам нужно только установить _FILE_OFFSET_BITS на 64. Это должно переопределить off_t и функции, такие как fseeko, ftello до 64-разрядных безопасных версий (это не-операционная система в 64-битных системах и перенаправляет символы в суффиксные версии 64 на 32-разрядные системы). Это предпочтительно использовать непосредственно суффиксные функции 64.

И как сказал Сергей, приведение значения off_t до long unsigned int потеряет информацию о 32-битных системах. Я не думаю, что есть стандартный формат printf для off_t, поэтому вам, вероятно, лучше всего отбросить значение до unsigned long long int и использовать %#llx в качестве кода формата. Это должно быть предупреждением бесплатно на обоих размерах слов и не потерять информацию.

0
ответ дан 25 May 2018 в 15:15

Другие вопросы по тегам:

Похожие вопросы: