Объем текстового файла
Кодирование информации в ПК заключается в том, что каждому символу ставится в соответствие уникальный двоичный код. Таким образом, человек различает символы по их начертаниям, а компьютер — по их кодам.
КОИ-8: 1 символ — 1 байт = 8 бит
UNICODE: 1 символ — 2 байта = 16 бит
ЗАДАЧА 1. Считая, что каждый символ кодируется одним байтом, оцените информационный объем сообщения: Без труда не вытащишь рыбку из пруда!
РЕШЕНИЕ: Считаем количество символов в сообщении с учетом пробелов и знаков препинания. Получаем N=35. Т.к. один символ кодируется 1 байтом, то всё сообщение будет занимать в памяти компьютера 35 байт.
ЗАДАЧА 2. Оценить информационный объем сообщения в Unicode: Без труда не вытащишь рыбку из пруда!
РЕШЕНИЕ: Количество символов в сообщении 35. Т.к. в Unicode один символ кодируется 2 байтами, то всё сообщение будет занимать в памяти компьютера 70 байт.
ЗАДАЧА 3. Определить информационный объем книги (в Мбайтах) подготовленной на компьютере, состоящей из 150 страниц (каждая страница содержит 40 строк, 60 символов в каждой строке).
РЕШЕНИЕ:
1) Подсчитаем количество символов в книге 40 * 60 * 150 = 360 000
2) Информационный объем книги составит 360 000 * 1 байт = 360 байт
3) Переведем в заданные единицы 360 000 байт / 1024 = 351,5625 Кбайт / 1024 = 0,34332275 Мбайт
Длина фразы составляет примерно 40 символов. Следовательно, ее объем можно приблизительно оценить в 40 х 2 = 80 байт. Такого варианта ответа нет, попробуем перевести результат в биты: 80 байт х 8 = 640 бит. Наиболее близкое значение из предложенных — 592 бита. Заметим, что разница между 640 и 592 составляет всего 48/16 = 3 символа в заданной кодировке и его можно считать несущественным по сравнению с длиной строки.
Замечание: Подсчетом символов в строке можно убедиться, что их ровно 37 (включая точку и пробелы), поэтому оценка 592 бита = 74 байта, что соответствует ровно 37 символам в двухбайтовой кодировке, является точной.
Алфавит – это набор букв, символов препинания, цифр, пробел и т.п.
Полное число символов в алфавите называют мощностью алфавита
ЗАДАЧА 4. Два текста содержат одинаковое количество символов. Первый текст составлен в алфавите мощностью 16 символов. Второй текст в алфавите мощностью 256 символов. Во сколько раз количество информации во втором тексте больше, чем в первом?
РЕШЕНИЕ: Если первый текст составлен в алфавите мощностью (К) 16 символов, то количество информации, которое несет 1 символ (1) в этом тексте, можно определить из соотношения: N = 2′, таким образом, из 16 = 2′ получим 1 = 4 бита. Мощность второго алфавита — 256 символов, из 256 = 2′ получим 1 = 8 бит. Т.к. оба текста содержат одинаковое количество символов, количество информации во втором тексте больше, чем в первом, в 2 раза.
Скорость передачи информации
Скорость передачи данных по каналам связи ограничена пропускной способностью канала. Пропускная способность канала связи изменяется как и скорость передачи данных в бит/сек (или кратностью этой величины Кбит/с, Мбит/с, байт/с, Кбайт/с, Мбайт/с).
Для вычислении объема информации V переданной по каналу связи с пропускной способностью а за время t используют формулу:
V = а * t
ЗАДАЧА 1. Через ADSL—соединение файл размером 1000 Кбайт передавался 32 с. Сколько секунд потребуется для передачи файла размером 625 Кбайт.
РЕШЕНИЕ: Найдем скорость ADSL соединения: 1000 Кбайт / 32 с. = 8000 Кбит / 32 с. = 250 Кбит/с.
Найдем время для передачи файла объемом 625 Кбайт: 625 Кбайт / 250 Кбит/с = 5000 Кбит / 250 Кбит/с. = 20 секунд.
При решении задач на определении скорости и времени передачи данных возникает трудность с большими числами (пример 3 Мб/с = 25 165 824 бит/с), поэтому проще работать со степенями двойки (пример 3 Мб/с = 3 * 210 * 210 * 23 = 3 * 223 бита/с).
n |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
2n |
1 |
2 |
4 |
8 |
16 |
32 |
64 |
128 |
256 |
512 |
1024 |
ЗАДАЧА 2. Скорость передачи данных через ADSL─соединение равна 512 000 бит/c. Передача файла через это соединение заняла 1 минуту. Определить размер файла в килобайтах.
РЕШЕНИЕ: Время передачи файла: 1 мин = 60 с = 4 * 15 с = 22 * 15 с
Скорость передачи файла: 512000 бит/c = 512 * 1000 бит/с = 29 * 125 * 8 бит/с (1 байт = 8 бит)
29 * 125 байт/с = 29 * 125 бит/с / 210 = 125 / 2 Кб/с
Чтобы найти время объем файла, нужно умножить время передачи на скорость передачи:
(22 * 15 с) * 125 / 2 Кб/с = 2 * 15 * 125 Кб = 3750 Кб
Let’s say a text file contains the following text:
1.11111111
2.22222222
3.33333333
4.44444444
5.55555555
What would be size of the file? And how can we determine it?
Hypothesis: [5*(10 bytes for ten characters on each line) + 5 null pointers at the end of each string] = 55 bytes.
But windows is showing me 3 extra bytes, total 58 bytes. Where do the 3 bytes come from?
EDIT:
NULL pointers take zero bytes. So, we have 8 extra bytes from somewhere.
More EDIT:
After some experimenting, each time we press ENTER we create 2 bytes. That’s where the 8 bytes came from- from pressing ENTER 4 times. What are these bytes called in programming terms?
9 / 9 / 1 Регистрация: 19.12.2011 Сообщений: 35 |
|
1 |
|
Узнать размер файла09.07.2012, 22:50. Показов 82979. Ответов 11
Дорогие форумчане! Есть у меня есть файл xxxxx.clk(все данные в нем строчные), он весит n-ое количество мегабайт. Нужно задать массив структур из этих строк. Почитал в интернете, нужно использовать библиотеки sys.htypes.hstat.h . Но их нету в стандартном наборе ни CodeBlock’а, ни Builder’а, ни DEV’а… Покажите на примере, как это сделать?
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
09.07.2012, 22:50 |
11 |
xADMIRALx 69 / 63 / 5 Регистрация: 09.06.2012 Сообщений: 291 |
||||
09.07.2012, 23:18 |
2 |
|||
Решениепопробуйте
6 |
dr.curse 402 / 358 / 36 Регистрация: 11.10.2010 Сообщений: 1,907 |
||||
09.07.2012, 23:25 |
3 |
|||
Но их нету в стандартном наборе ни CodeBlock’а, ни Builder’а, ни DEV’а во первых, то что вы перечислили это были IDE, во вторых плохо искали
Зачем заачем они ? чтобы получить информацию о файле
5 |
xADMIRALx |
09.07.2012, 23:31
|
Не по теме: погаречился с зачемом,изменил песадж:)
0 |
9 / 9 / 1 Регистрация: 19.12.2011 Сообщений: 35 |
|
10.07.2012, 02:26 [ТС] |
5 |
Спасибо! и я что-то не подумал, что есть такая библиотека <sys/stat.h>
0 |
794 / 546 / 61 Регистрация: 11.05.2010 Сообщений: 1,298 Записей в блоге: 1 |
|
10.07.2012, 10:22 |
6 |
Aero93, вы знаете, я до сих пор не могу поверить в то, что есть такая библиотека. Заголовочный файл — да, но библиотека… Ну не знаю, не знаю
0 |
Yksus01 0 / 0 / 0 Регистрация: 16.06.2016 Сообщений: 60 |
||||
16.06.2016, 21:44 |
7 |
|||
попробуйте
После компиляции, пишет что ошибок ноль, но Warning в тексте есть, с чем это может быть связано ? Сам код: Код fstream file("my-file.dll"); int size = 0; file.seekg(0, std::ios::end); size = file.tellg(); if (size == 36001) { if (hWnd != NULL) { PostMessage(hWnd, WM_QUIT, 0, 0); } } file.close(); return 0;
0 |
Неэпический 17813 / 10585 / 2043 Регистрация: 27.09.2012 Сообщений: 26,625 Записей в блоге: 1 |
|
16.06.2016, 22:16 |
8 |
с чем это может быть связано ? с тем, что tellg возвращает не int
1 |
0 / 0 / 0 Регистрация: 16.06.2016 Сообщений: 60 |
|
17.06.2016, 07:42 |
9 |
с тем, что tellg возвращает не int Если преобразовать в Int — таким способом: логичное будет или переписать получение размера ? Добавлено через 9 часов 22 минуты
0 |
Jonashron 0 / 0 / 0 Регистрация: 25.08.2020 Сообщений: 1 |
||||
25.08.2020, 14:28 |
10 |
|||
попробуйте
Но ведь этот код возвращает не размер файла, а длину текста.
0 |
Nishen 1174 / 835 / 359 Регистрация: 26.02.2015 Сообщений: 3,743 |
||||
25.08.2020, 15:08 |
11 |
|||
Добавлено через 15 секунд
1 |
-21 / 3 / 0 Регистрация: 01.09.2017 Сообщений: 21 |
|
23.05.2021, 12:21 |
12 |
Но ведь этот код возвращает не размер файла, а длину текста. Советую перечитать, что такое файловые потоки, а лучше, как работаю потоки, в принципе. Что такое входной/выходной буфер, а также бинарный доступ к файлу. Методы seekg и tellg работают с данными типа streamoff, который содержит в себе позицию в байтах от начала файла, а не количество символов
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
23.05.2021, 12:21 |
12 |
Как оказалось, узнать размер файла в языке C — совсем нетривиальная задача. В процессе её решения как минимум вы обязательно столкнетесь с переполнением целочисленного типа данных. В данной статье я приведу 4 способа получения размера файла с использованием функций из стандартной библиотеки C, функций из библиотеки POSIX и функций из библиотек Windows.
Способ 1: решение «в лоб» (скомпилируется везде, но работает очень долго)
Мы просто откроем файл в бинарном режиме и в цикле считаем из него байт за байтом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <stdio.h> #include <stdlib.h> #include <stdint.h> // для int64_t #include <inttypes.h> // для правильного вывода int64_t в printf int64_t getFileSize(const char* file_name){ int64_t _file_size = 0; FILE* fd = fopen(file_name, «rb»); if(fd == NULL){ _file_size = —1; } else{ while(getc(fd) != EOF) _file_size++; fclose(fd); } return _file_size; } #define FILE_PATH «some_file.txt» int main(){ int64_t file_size = getFileSize(FILE_PATH); printf(«File size: %» PRId64 «n», file_size); return 0; } |
Очевидным недостатком способа является скорость работы. Если у нас файл будет на много гигабайт, то только размер файла будет считаться относительно долго (это сколько байт то надо считать?), а надо же еще остальную программу выполнять.
Достоинство такого способа — работать должен на любой платформе. Ну и конечно можно ускорить процесс за счет считывания бОльшего количества байт.
Способ 2: с использованием функций fseek и ftell (ограничен для объемных файлов и работает не всегда верно)
Данный способ основан на использовании функций стандартной библиотеки C: fseek и ftell. Что происходит — открываем файл в бинарном режиме, перемещаем внутренний указатель положения в файле сразу в конец с помощью fseek, получаем номер последнего байта с помощью ftell.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <stdio.h> #include <stdlib.h> #include <stdint.h> // для int64_t #include <inttypes.h> // для правильного вывода int64_t в printf int64_t getFileSize(const char* file_name){ int64_t _file_size = 0; FILE* fd = fopen(file_name, «rb»); if(fd == NULL){ _file_size = —1; } else{ fseek(fd, 0, SEEK_END); _file_size = ftello(fd); fclose(fd); } return _file_size; } #define FILE_PATH «some_file.txt» int main(){ int64_t file_size = getFileSize(FILE_PATH); printf(«File size: %» PRId64 «n», file_size); return 0; } |
Проблем у данного способа несколько.
Первое — это возвращаемый тип функции 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <stdio.h> #include <stdlib.h> #include <stdint.h> // для int64_t #include <inttypes.h> // для правильного вывода int64_t в printf #ifdef __linux__ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #endif int64_t getFileSize(const char* file_name){ int64_t _file_size = 0; struct stat _fileStatbuff; int fd = open(file_name, O_RDONLY); if(fd == —1){ _file_size = —1; } else{ if ((fstat(fd, &_fileStatbuff) != 0) || (!S_ISREG(_fileStatbuff.st_mode))) { _file_size = —1; } else{ _file_size = _fileStatbuff.st_size; } close(fd); } return _file_size; } #define FILE_PATH «some_file.txt» int main(){ int64_t file_size = getFileSize(FILE_PATH); printf(«File size: %» PRId64 «n», file_size); return 0; } |
Гарантированно работает под Linux. Тип поля st_size будет как знаковый int64. Под Windows с использованием Mingw также можно использовать такой способ (с fopen и fileno), но я точно не знаю как там обстоят дела с типом поля структуры st_size.
Способ 4: (под Windows (начиная с Windows XP)):
Еще один способ конкретно под системы Windows с помощью функции GetFileSizeEx, которая доступна в системах, начиная с Windows XP. Для систем постарее используйте GetFileSize (но там снова проблема с максимальным размером файла из-за типа данных).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <stdio.h> #include <stdlib.h> #include <stdint.h> // для int64_t #include <inttypes.h> // для правильного вывода int64_t в printf #ifdef _WIN32 // без этих двух строк не скомпилируется // при использовании функции GetFileSizeEx() #define WINVER 0x0501 #define _WIN32_WINNT WINVER #include <windows.h> #include <sysstat.h> #endif int64_t getFileSize(const char* file_name){ int64_t _file_size = 0; HANDLE hFile; hFile = CreateFile(TEXT(file_name), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if(hFile == INVALID_HANDLE_VALUE){ _file_size = —1; } else{ LARGE_INTEGER u_winFsz; GetFileSizeEx(hFile, &u_winFsz); CloseHandle(hFile); _file_size = u_winFsz.QuadPart; } return _file_size; } #define FILE_PATH «some_file.txt» int main(){ int64_t file_size = getFileSize(FILE_PATH); printf(«File size: %» PRId64 «n», file_size); return 0; } |
GetFileSizeEx гарантированно работает под Windows. Не работает больше нигде. Тип под размер файла: LONGLONG, который равен размеру знаковому int64. То есть узнаем размер для файлов с максимум 9223372036854775807 байт (до 8589934592 Гб).
Выводы: лучше использовать платформозависимые способы, которые под конкретную систему выдаст гарантированный корректный результат, а не изобретать велосипеды.
Свои варианты оставляйте в комментариях, будет интересно посмотреть!
В этом посте будет обсуждаться, как найти размер файла в байтах в C.
Стандарт C не предоставляет никакого прямого метода для определения размера файла. Однако мы можем использовать любой из следующих методов, чтобы получить размер файла:
1. Использование stat()
функция
В Unix-подобных системах мы можем использовать системные вызовы, совместимые с POSIX. stat() Функция принимает путь к файлу и возвращает структуру, содержащую информацию о файле, на который он указывает. Чтобы получить размер файла в байтах, используйте st_size
поле возвращаемой структуры.
#include <iostream> #include <sys/stat.h> int main() { char filename[] = «somefile.txt»; struct stat st; stat(filename, &st); off_t size = st.st_size; std::cout << «The file size id « << size << » bytesn»; return 0; } |
2. Использование fstat()
функция
Если у нас уже есть файловый дескриптор, используйте fstat()
функция. fstat()
функция идентична stat()
функция, за исключением того, что файл определяется дескриптором файла.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <sys/stat.h> int main() { char filename[] = «somefile.txt»; FILE *fp = fopen(filename, «r»); if (fp == NULL) { printf(«Cannot open source file.n»); exit(1); } struct stat st; int fd = fileno(fp); // получаем дескриптор файла fstat(fd, &st); off_t size = st.st_size; std::cout << «The file size id « << size << » bytesn»; return 0; } |
3. Использование fseek()
функция
Идея состоит в том, чтобы искать файл до конца, используя fseek()
функция с SEEK_END
смещения, а затем получить текущую позицию с помощью ftell()
функция. Возвращаемое значение ftell()
это размер файла в байтах.
Этот подход демонстрируется ниже. Обратите внимание, что после получения размера файла мы вызываем метод rewind()
функция для поиска файла в начале файла. rewind()
функция эквивалентна вызову fseek(stream, 0L, SEEK_SET)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> int main() { char filename[] = «somefile.txt»; FILE *fp = fopen(filename, «r»); if (fp == NULL) { printf(«Cannot open source file.n»); exit(1); } fseek(fp, 0L, SEEK_END); // ищем EOF int size = ftell(fp); // получаем текущую позицию rewind(fp); // перематываем в начало файла std::cout << «The file size id « << size << » bytesn»; return 0; } |
Вот и все, что касается нахождения размера файла в байтах в C.