2016-07-26 1 views
3

Мне нужно открыть файл и загрузить его в разделяемую память через mmap, но если файл еще не существует, я хочу его открыть, напишите несколько (поддельные) данные, а затем mmap. Я написал следующую функцию в C, но я получаю ошибку в записи (см. Ниже). (Я знаю, что часть mmap, вероятно, неверна (данные назначаются дважды!), Но до этого происходит ошибка, поэтому она не должна влиять на эту проблему).Ошибка при попытке написать() файл размером более 2 ГБ на Linux

// These 2 are global so they can be referenced in other functions. 
int dfd = -1; 
long* data = NULL; 

void load_data(char* filename) 
{ 
    dfd = open(filename, O_RDONLY); 

    if (dfd == -1) { 

    printf("Creating file %s\n", filename); 

    dfd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 

    if (dfd == -1) { 
     fprintf(stderr, "Couldn't create file %s\n", filename); 
     perror("create"); 
     exit(1); 
    } 

    data = (long *) valloc(M * GB); 

    if (data == nullptr) { 
     fprintf(stderr, "Couldn't allocate %ld bytes", (M * GB)); 
     perror("malloc"); 
     exit(1); 
    } 

    for (size_t i = 0; i < M * GB/sizeof(long); ++i) 
     data[i] = (long) i; 

    printf("%d %p %ld\n", dfd, data, M * GB); 

    ssize_t w = write(dfd, (void*) data, M * GB); 

    if (w != M * GB) { 
     fprintf(stderr, "Couldn't write %ld bytes to file %s\n", (M * GB), filename); 
     fprintf(stderr, "Wrote %ld bytes\n", w); 
     perror("write"); 
     exit(1); 
    } 
    } 

    data = (long *) mmap(0, M * GB, PROT_READ, MAP_SHARED, dfd, 0); 

    if (data == MAP_FAILED) { 
    perror("mmap"); 
    exit(1); 
    } 
} 

выход и ошибка на MacOS 64 бита, Apple г ++:

Creating file bench2_datafile.bin 
3 0x101441000 2147483648 
Couldn't write 2147483648 bytes to file bench2_datafile.bin 
Wrote -1 bytes 
write: Invalid argument 

Любой указатель? Я продолжаю читать открытые и писать документы и искать примеры в Интернете, но я не могу понять эту ошибку.

После выгоду от комментариев:

Выход на RHEL 6, г ++ 4.8:

Creating file bench2_datafile.bin 
3 0x7f79048af000 2147483648 
write: Success 
Couldn't write 2147483648 bytes to file bench2_datafile.bin 
Wrote 2147479552 bytes 

и 2147479552 действительно размер файла в латах.

Кроме того, он работает на Mac с 1 ГБ - но он выходит из-под контроля с 2 ГБ. Ой хорошо - моя реальная цель - Linux, так как было удобнее работать на Mac, пока я не получил ошибки :-)

+1

Почему использование 'open' вместо' fopen'? вы можете проверить, существует ли файл с 'fopen (filepath," r ")', и если он не существует, используйте 'fopen (filepath," w ")' для записи на него, после чего продолжайте, как вы делаете, когда файл существует –

+2

Не вызывайте другие функции между неудачным сбоем вызова и perror, вы можете сбросить errno и получить бессмысленные распечатки ошибок. Убедитесь, что включена поддержка большого файла. – Mat

+3

@MeikVtune * почему использование open вместо fopen? * Поскольку 'mmap()' требует дескриптора файла типа 'int', подобного тому, который возвращает' open() '. Кроме того, 'fopen()'/'fwrite()' выполняет операции записи буферов, что в этом случае не является необходимым. –

ответ

2

Многие платформы используют 32-битные значения для позиций файлов. Кроме того, для интерфейса требуется, чтобы значение было подписано. Это означает, что вы можете столкнуться с проблемами, когда хотите обрабатывать файлы размером более 2 ГБ.

Некоторые платформы предоставляют нестандартные функции для управления большими файлами.

Вам необходимо проверить документацию на платформу, чтобы узнать, что будет для платформы, на которую вы хотите настроить таргетинг.

Смежные вопросы