Исправление
Moisha_Liberman,
(текущая версия)
:
Во-первых, да, можно определить размер через fstat()
и считать в память ровно столько, сколько можно (либо целиком файл, либо по кускам, но не более общей длины файла). Типа так:
struct stat buff;
...
printf("Size of the file is: %ld\n", buff.st_size);
Здесь buff.st_size
это и есть искомая полная длина файла.
Во-вторых, можно просто провести операцию чтения из файла, когда указатель позиции находится в конце файла, и, если напоролись на флаг EOF
, то дальше не читать. Типа так:
/**
* Set file pointer to the given position of the given file.
*
* - Returns 0 on success
* - Returns -1 on EOF
* - Returns -2 if an error occured, see errno for error code
* - Returns -3 if none of the above applies. This should never happen!
*/
static int8_t set_fp_pos(FILE *f, uint64_t fp_pos)
{
int err = fseek(f, fp_pos, SEEK_SET);
if (err != 0) {
if (feof(f) != 0) return -1;
if (ferror(f) != 0) return -2;
return -3;
}
return 0;
}
Нужно учитывать то, что fseek()
сама по себе да, может выходить за пределы последней позиции в файле на тот случай, если будет необходимость записать что-то за пределы конца файла. Это такой извращённый способ добавления (дозаписи) данных в файл. Избавлять от такого поведения fseek()
не нужно.
Третий вариант – отмапить (mmap()
) содержимое файла в адресное пространство процесса. Тогда просто работаете с массивом символов в памяти. По временам это и лучше, т.к. если идёт активная обработка файлов разной длины, то после того как Вы сделаете munmap()
, размеры потребляемой памяти уменьшатся. mmap()
не раздувает кучу. Так же нужно учитывать что можно не весь файл сразу мапить, а по кускам. Т.е., в начале определяем можем ли отмапить сразу весь файл в память, и, если вдруг не можем, то работаем с файлом кусками. Вдобавок, при обработке файлов, может оказаться что этот вариант работает слегка быстрее чем случай, когда система борется с винчестером, пытаясь читать порции из файла.
В общем, разные варианты – надо от задачи смотреть.
Исходная версия
Moisha_Liberman,
:
Во-первых, да, можно определить размер через fstat()
и считать в память ровно столько, сколько можно (либо целиком файл, либо по кускам, но не более общей длины файла). Типа так:
struct stat buff;
...
printf("Size of the file is: %ld\n", buff.st_size);
Здесь buff.st_size
это и есть искомая полная длина файла.
Во-вторых, можно просто провести операцию чтения из файла, когда указатель позиции находится в конце файла, и, если получили EOF
, то дальше не читать. Типа так:
/**
* Set file pointer to the given position of the given file.
*
* - Returns 0 on success
* - Returns -1 on EOF
* - Returns -2 if an error occured, see errno for error code
* - Returns -3 if none of the above applies. This should never happen!
*/
static int8_t set_fp_pos(FILE *f, uint64_t fp_pos)
{
int err = fseek(f, fp_pos, SEEK_SET);
if (err != 0) {
if (feof(f) != 0) return -1;
if (ferror(f) != 0) return -2;
return -3;
}
return 0;
}
Нужно учитывать то, что fseek()
сама по себе да, может выходить за пределы последней позиции в файле на тот случай, если будет необходимость записать что-то за пределы конца файла. Это такой извращённый способ добавления (дозаписи) данных в файл. Избавлять от такого поведения fseek()
не нужно.
Третий вариант – отмапить (mmap()
) содержимое файла в адресное пространство процесса. Тогда просто работаете с массивом символов в памяти. По временам это и лучше, т.к. если идёт активная обработка файлов разной длины, то после того как Вы сделаете munmap()
, размеры потребляемой памяти уменьшатся. mmap()
не раздувает кучу. Так же нужно учитывать что можно не весь файл сразу мапить, а по кускам. Т.е., в начале определяем можем ли отмапить сразу весь файл в память, и, если вдруг не можем, то работаем с файлом кусками. Вдобавок, при обработке файлов, может оказаться что этот вариант работает слегка быстрее чем случай, когда система борется с винчестером, пытаясь читать порции из файла.
В общем, разные варианты – надо от задачи смотреть.