Как узнать размер файла c
На 32-битных системах вы должны скомпилировать это с опцией -D_FILE_OFFSET_BITS=64 , иначе off_t будет содержать только значения до 2 ГБ. Подробности смотрите в разделе "Использование LFS" в разделе " Поддержка больших файлов в Linux".
Не использовать int , В наши дни файлы размером более 2 гигабайт часто встречаются как грязь
Не использовать unsigned int , Файлы размером более 4 гигабайт часто встречаются как немного менее распространенная грязь
Если у вас Windows, вы должны использовать GetFileSizeEx - он на самом деле использует 64-разрядное целое число со знаком, поэтому они начнут сталкиваться с проблемами с 8 эксабайтными файлами. Глупый Microsoft!:-)
Исправил вашу скобку для вас тоже.;)
Обновление: это не самое лучшее решение. Он ограничен 4 ГБ файлами в Windows и, вероятно, медленнее, чем просто использование вызова конкретной платформы, такого как GetFileSizeEx или же stat64 ,
Цитируя стандартный документ C99, который я нашел в Интернете: "Установка индикатора положения файла в конец файла, как и в случае с fseek(file, 0, SEEK_END), имеет неопределенное поведение для двоичного потока (из-за возможных завершающих нулевых символов) или для любого потока с кодированием, зависящим от состояния, которое не обязательно заканчивается в начальном состоянии сдвига.**
Стандарт POSIX имеет свой собственный метод для получения размера файла.
Включить sys/stat.h заголовок для использования функции.
конспект
- Получить статистику файла, используя stat(3) ,
- Получить st_size имущество.
Примеры
Примечание: он ограничивает размер 4GB , Если не Fat32 файловую систему, тогда используйте 64-битную версию!
ANSI C не предоставляет прямой способ определения длины файла.
Нам придется использовать наш разум. Сейчас мы будем использовать подход поиска!
конспект
- Ищите файл до конца, используя fseek(3) ,
- Получить текущую позицию, используя ftell(3) ,
пример
Если файл stdin или труба. POSIX, ANSI C не будет работать.
Будет возвращаться 0 если файл представляет собой трубу или stdin ,Мнение: Вы должны вместо этого использовать стандарт POSIX. Потому что он имеет поддержку 64 бит.
Как оказалось, узнать размер файла в языке C - совсем нетривиальная задача. В процессе её решения как минимум вы обязательно столкнетесь с переполнением целочисленного типа данных. В данной статье я приведу 4 способа получения размера файла с использованием функций из стандартной библиотеки C, функций из библиотеки POSIX и функций из библиотек Windows.
Способ 1: решение "в лоб" (скомпилируется везде, но работает очень долго)
Мы просто откроем файл в бинарном режиме и в цикле считаем из него байт за байтом.
Очевидным недостатком способа является скорость работы. Если у нас файл будет на много гигабайт, то только размер файла будет считаться относительно долго (это сколько байт то надо считать?), а надо же еще остальную программу выполнять.
Достоинство такого способа - работать должен на любой платформе. Ну и конечно можно ускорить процесс за счет считывания бОльшего количества байт.
Способ 2: с использованием функций fseek и ftell (ограничен для объемных файлов и работает не всегда верно)
Данный способ основан на использовании функций стандартной библиотеки C: fseek и ftell. Что происходит - открываем файл в бинарном режиме, перемещаем внутренний указатель положения в файле сразу в конец с помощью fseek, получаем номер последнего байта с помощью ftell.
Проблем у данного способа несколько.
Первое - это возвращаемый тип функции ftell. У разных компиляторов на разных платформах по разному. Если у вас 32х битная система, то данный способ будет работать только для файлов, размером меньше 2048 Мб, поскольку максимальное значение для возвращаемого функцией типа long там будет 2147483647. На системах с большей разрядностью будет работать лучше, из-за большего значения максимума для long. Но подобная нестабильность будет мешать. Хотя у меня на 64х битой системе на компиляторе gcc данный способ для файлов больше 8 Гб выводил некорректные значения.
Второе - гарантированность работы fseek и ftell. Коротко говоря, на разных платформах работает по-разному. Где то будет точно возвращать значение положения последнего байта, где то будет возвращать неверное значение. То есть точность данного способа негарантированна.
Плюсом является то, что эти функции из стандартной библиотеки - скомпилируется почти везде.
Стоит сказать, что хитрые инженеры из Microsoft придумали функции _fseeki64 и _ftelli64, которые, как понятно из их названия, работают с int64, что решает проблему с размером файла в MSVC под Windows.
Способ 3: (под Linux (POSIX))
Данный способ основан на использовании системном вызове fstat с использованием специальной структуры struct stat. Как работает: открываем файл через open() или fopen(), вызываем fstat для дескриптора файла (если открыли через fopen, то в fstat надо положить результат fileno от указателя потока FILE), указав на буферную структуру для результатов, и получаем значения поля буферной структуры st_size.
Узнать размер файла
Мне нужно прочитать обычный текстовый файл. Я думаю это сделать с помощью одной из функций.
Узнать размер файла больше 4гб
сабж какой функцией можно узнать размер файла больше 4 гб (+ другие св-ва - опционально)? ++.
Решение
Но их нету в стандартном наборе ни CodeBlock'а, ни Builder'а, ни DEV'а во первых, то что вы перечислили это были IDE, во вторых плохо искаличтобы получить информацию о файле
вот пример
погаречился с зачемом,изменил песадж:)
Спасибо! и я что-то не подумал, что есть такая библиотека <sys/stat.h> Aero93, вы знаете, я до сих пор не могу поверить в то, что есть такая библиотека. Заголовочный файл - да, но библиотека. Ну не знаю, не знаюПосле компиляции, пишет что ошибок ноль, но Warning в тексте есть, с чем это может быть связано ?
warning C4244: '=' : conversion from 'std::streamoff' to 'int', possible loss of data
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Если преобразовать в Int - таким способом:
size = (int)file.tellg();
логичное будет или переписать получение размера ?
Добавлено через 9 часов 22 минуты
Croessmah, Нашел одну статейку на этом форуме, там tellq приравнивался streamoff
сделал замену в коде:
с int size = 0;
на streamoff size = 0;
Т.е., если в файле будут использоваться символы юникода или расширенного ASCII, то полученный ответ не будет соответствовать с весом файла.
Если файл состоит только из символов весом в 2 байта, можно было-бы домножить на 2, а если они идут в перемешку, и не известно количество тех и других отдельно, тогда как? Но ведь этот код возвращает не размер файла, а длину текста. Советую перечитать, что такое файловые потоки, а лучше, как работаю потоки, в принципе. Что такое входной/выходной буфер, а также бинарный доступ к файлу. Методы seekg и tellg работают с данными типа streamoff, который содержит в себе позицию в байтах от начала файла, а не количество символов
Как узнать размер файла? (студия 2013)
Доброго времени суток, форумчане и гости! Есть небольшой код и хочется прикрутить определитель.
Как узнать текущий размер копируемого файла?
Здраствуйте! Как узнать текущий размер копируемого файла? У HTML-их нашел, а как у других не.
Как узнать текущий размер файла, открытого для записи?
File=CreateFile(FilePath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS.
Как узнать размер файла
Вобщем программа -кодировщик методом Хаффмана, взята из интернета. Нужно добавить к ней вывод.
В 32-битных системах вы должны скомпилировать это с опцией -D_FILE_OFFSET_BITS=64 , иначе off_t будет содержать значения только до 2 ГБ. Подробности смотрите в разделе "Использование LFS" в разделе " Поддержка больших файлов в Linux".
Ответ 2
Не используйте int . Файлы размером более 2 гигабайт обычно являются грязью в эти дни.
Не используйте unsigned int . Файлы размером более 4 гигабайт являются общими, так как некоторые немного менее распространенные загрязнения
IIRC стандартная библиотека определяет off_t как неподписанное 64-битное целое число, которое все должны использовать. Мы можем переопределить это до 128 бит за несколько лет, когда мы начнем работать с 16 файлами exabyte.
Если вы находитесь в окнах, вы должны использовать GetFileSizeEx - на самом деле он использует подписанное 64-битное целое число, поэтому они начнут сталкиваться с проблемами с 8 файлами exabyte. Глупый Microsoft!: -)
Ответ 3
Решение Matt должно работать, за исключением того, что это С++ вместо C, и исходный запрос не нужен.
Исправлена ваша скобка для вас.;)
Обновление: это не лучшее решение. Он ограничивается файлами размером 4 ГБ в Windows, и это, вероятно, медленнее, чем просто использование определенного для платформы вызова типа GetFileSizeEx или stat64 .
Ответ 4
Цитата стандартного документа C99, который я нашел в Интернете: "Установка индикатора положения файла в конец файла, как и в файле fseek (файл, 0, SEEK_END), имеет поведение undefined для бинарного потока (из-за возможного завершающие нулевые символы) или для любого потока с зависящей от состояния кодировкой, которая не обязательно заканчивается в исходном состоянии сдвига. **
Ответ 5
Если вам хорошо с помощью библиотеки std c:
Ответ 6
Стандарт POSIX имеет свой собственный метод для получения размера файла.
Включите заголовок sys/stat.h для использования функции.
конспект
- Получить статистику файла, используя stat(3) .
- Получите свойство st_size .
Примеры
Примечание. Размер ограничен 4GB . Если не Fat32 система Fat32 тогда используйте 64-битную версию!
ANSI C не предоставляет прямой способ определения длины файла.
Нам придется использовать наш разум. Сейчас мы будем использовать подход поиска!
конспект
- Найдите файл до конца, используя fseek(3) .
- Получить текущую позицию, используя ftell(3) .
пример
Если файл stdin или труба. POSIX, ANSI C не будет работать.
Будет возвращаться 0 если файл представляет собой канал или стандартный stdin .Мнение: Вы должны вместо этого использовать стандарт POSIX. Потому что он имеет поддержку 64 бит.
Ответ 7
И если вы создаете приложение Windows, используйте API GetFileSizeEx, поскольку ввод/вывод файлов CRT бесполезен, особенно для определения файла длина из-за особенностей файловых представлений в разных системах;)
Ответ 8
Быстрый поиск в Google нашел метод, использующий fseek и ftell, и поток с этим вопросом с ответами, что это невозможно сделать в просто C по-другому.
Вы можете использовать библиотеку переносимости, например NSPR (библиотека, которая активирует Firefox) или проверьте его реализация (довольно волосатая).
Ответ 9
Я использовал этот набор кода для поиска длины файла.
Ответ 10
Что это значит, прежде всего, ищите конец файла; затем сообщите, где находится указатель файла. Наконец (это необязательно) он перематывается обратно в начало файла. Обратите внимание, что fp должен быть двоичным потоком.
file_size содержит количество байтов, содержащихся в файле. Обратите внимание, что поскольку (согласно climits.h) беззнаковый длинный тип ограничен 4294967295 байтами (4 гигабайта), вам нужно будет найти другой тип переменной, если вы, вероятно, будете иметь дело с файлами, большими, чем это.
Ответ 11
Здесь простая и понятная функция, которая возвращает размер файла.
Ответ 12
Для этого мы будем использовать fseek(3) , ftell(3) / ftello(3) которые определены в <stdio.h> .
Этот метод работает как в Linux, так и в Windows!
32- битный метод может рассчитывать до 4GB размера файла, также как ограничение размера файла Fat32.
Примечание: если ввод stdin /pipe, метод не будет работать.
Ответ 13
У меня есть функция, которая хорошо работает только с stdio.h . Мне это очень нравится, оно работает очень хорошо и довольно лаконично:
Ответ 14
Вам понадобится использовать библиотечную функцию для получения сведений о файле. Поскольку C полностью независима от платформы, вам нужно сообщить нам, какую платформу/операционную систему вы разрабатываете!
Ответ 15
Рассматривая вопрос, ftell может легко получить количество байтов.
Ответ 16
Вы можете открыть файл, перейти к 0 смещению относительно нижней части файла с помощью
значение, возвращаемое из файла fseek, - это размер файла.
Я долгое время не записывал код на C, но я думаю, что он должен работать.
В 32-битных системах вы должны скомпилировать это с опцией -D_FILE_OFFSET_BITS=64 , иначе off_t будет содержать только значения до 2 ГБ. См. Подробности в разделе «Использование LFS» в статье « Поддержка больших файлов в Linux» .
Это специфично для Linux / Unix - вероятно, стоит указать на это, поскольку в вопросе не указана ОС. Вероятно, вы могли бы без проблем изменить возвращаемый тип на ssize_t и преобразовать размер из off_t. Казалось бы, имеет смысл использовать ssize_t :-) (не путать с size_t, которое не имеет знака и не может использоваться для обозначения ошибки.) Для более переносимого кода используйте fseek +, ftell предложенный Дереком. Для более переносимого кода используйте fseek +, ftell предложенный Дереком. Нет. Стандарт C специально указывает, что fseek() для SEEK_END двоичного файла поведение undefined. 7.19.9.2 fseek Функция . Двоичный поток не обязательно должен поддерживать fseek вызовы со значением источника SEEK_END , равным , как указано ниже, из сноски 234 на стр. 267 связанных C стандарта, и которые специфически этикетками , fseek чтобы SEEK_END в двоичном потоке в качестве неопределенного поведения. . Из руководства gnu libc : . Системы [не-POSIX] делают различие между файлами, содержащими текст, и файлами, содержащими двоичные данные, и средства ввода и вывода ISO C предусматривают это различие. . В библиотеке GNU C и во всех системах POSIX нет разницы между текстовыми потоками и двоичными потоками. Когда вы открываете поток, вы получаете тот же поток независимо от того, запрашиваете ли вы двоичный файл. Этот поток может обрабатывать любое содержимое файла и не имеет ограничений, которые иногда имеют текстовые потоки.Не используйте int . Файлы размером более 2 гигабайт в наши дни стали обычным явлением
Не используйте unsigned int . Файлы размером более 4 гигабайт обычно встречаются как немного менее распространенная грязь.
IIRC стандартная библиотека определяет off_t как 64-битное целое число без знака, которое следует использовать всем. Мы можем переопределить это значение до 128 бит через несколько лет, когда мы начнем иметь файлы размером 16 эксабайт.
Я использовал компиляторы, где off_t - 32 бита. Конечно, это во встроенных системах, где файлы размером 4 ГБ встречаются реже. В любом случае, POSIX также определяет off64_t и соответствующие методы, чтобы добавить путаницы. Мне всегда нравятся ответы, которые предполагают наличие Windows и ничего не делают, кроме критики вопроса. Не могли бы вы добавить что-нибудь, совместимое с POSIX? @ JL2210 принятый ответ от Теда Персиваля показывает решение, совместимое с posix, поэтому я не вижу смысла повторять очевидное. Я (и еще 70 человек) подумал, что добавление примечания об окнах и отказ от использования 32-битных целых чисел со знаком для представления размеров файлов было добавлением ценности к этому. УраПоправил и скобу для тебя. ;)
Обновление: это не лучшее решение. В Windows он ограничен файлами размером 4 ГБ и, вероятно, медленнее, чем простой вызов для конкретной платформы, например GetFileSizeEx или stat64 .
Да, ты должен. Однако, если нет действительно веской причины не писать для конкретной платформы, вам, вероятно, следует просто использовать вызов для конкретной платформы, а не шаблон open / seek-end / tell / close. Извините за поздний ответ, но у меня серьезная проблема. Это приводит к зависанию приложения при доступе к файлам с ограниченным доступом (например, защищенным паролем или системным файлам). Есть ли способ при необходимости запросить пароль у пользователя? @Justin, вам, вероятно, следует открыть новый вопрос конкретно о проблеме, с которой вы столкнулись, и предоставить подробную информацию о платформе, на которой вы находитесь, о том, как вы получаете доступ к файлам и каково поведение. И C99, и C11 возвращаются long int из ftell() . (unsigned long) приведение не улучшает диапазон, который уже ограничен функцией. ftell() вернуть -1 при ошибке, и это будет запутано с приведением. Предлагаю fsize() вернуть тот же тип, что и ftell() . Согласен. Актерский состав должен был соответствовать оригинальному прототипу в вопросе. Я не могу вспомнить, почему я превратил его в unsigned long вместо unsigned int.Цитата из стандартного документа C99, который я нашел в Интернете: «Установка индикатора положения файла на конец файла, как и в случае fseek(file, 0, SEEK_END) , имеет неопределенное поведение для двоичного потока (из-за возможных завершающих нулевых символов) или для любого потока с кодированием, зависящим от состояния это не обязательно заканчивается в начальном состоянии сдвига. **
Читайте также: