LINUX.ORG.RU

История изменений

Исправление 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() не раздувает кучу. Так же нужно учитывать что можно не весь файл сразу мапить, а по кускам. Т.е., в начале определяем можем ли отмапить сразу весь файл в память, и, если вдруг не можем, то работаем с файлом кусками. Вдобавок, при обработке файлов, может оказаться что этот вариант работает слегка быстрее чем случай, когда система борется с винчестером, пытаясь читать порции из файла.

В общем, разные варианты – надо от задачи смотреть.