Минимальная единица объема информации для записи в файл
Однако следует иметь в виду, что программа, которая реализует запись данных в файл, может буферизировать свои выходные данные. Даже если строки будут добавляться регулярно (с точки зрения логики), они могут стать видимыми только фрагментами объемом 1 или 4 Кбайт (KiB).
И тут я окончательно запутался, то что программа может использовать буферизацию вполне логично и понятно. Всегда считал что программа может записать в файл если информации на запись минимум один байт, но данная цитата с присущими в ней приставками сбили с толку. Поясните русским языком. да-да, стыдно.
Реализация fwrite() пишет сначала в локальный буфер, который сбрасывает на диск когда: 1) буфер закончился; 2) вызыван fclose(); 3) ну и прочие условия, которые нам не суть в рамках вопроса.
Поэтому после вызова fwrite() операционная система еще ничего не знает о том, что ты что-то «писал». (Сискол write() еще не вызван.)
Программы __могут__ буферизировать свой вывод. Это возможность, а не требование.
При этом поведение программы может меняться в зависимости от обстоятельств. Например, при выводе на консоль программа gawk выводит построчно, то есть, как только строка сформировалась, она сразу же выводится. А вот если перенаправить вывод в файл, то будет использоваться буферизация. Таким образом увеличится производительность (и весьма существенно) за счет меньшего количества системных вызовов write (2),
Кстати, спасибо, так удобнее.
И тут я окончательно запутался, то что программа может использовать буферизацию вполне логично и понятно. Всегда считал что программа может записать в файл если информации на запись минимум один байт, но данная цитата с присущими в ней приставками сбили с толку. Поясните русским языком. да-да, стыдно.
речь наверное идёт об отложенной записи, файл на диске пишется не сразу, а только после заполнения буфера (если вы не используете sync(1) (см. man 1 sync), и если вы открыли файл без O_SYNC (см. man 2 open)). Посему файл растёт не по одному байту, а кусками, равными размеру буфера. Размер буфера неопределён и системозависим. Обычно он равен 64Кб (но НЕ обязательно!)
Программы __могут__ буферизировать свой вывод
При этом поведение программы может меняться в зависимости от обстоятельств.
если оно нужно, то можно даже этим управлять. См. например man sed, --unbuffered опцию.
write(2) тоже не пишет обычно по одному байту. AFAIK минимум 512 байт.
Это уже следующий уровень информированности. :)
А вот что реализация fwrite() буферизирует данные, программисту знать нужно с самого начала. (Хотя многие, похоже, не в курсе).
А вот что реализация fwrite() буферизирует данные, программисту знать нужно с самого начала. (Хотя многие, похоже, не в курсе).
ИМХО следует с самого начала понять, чем отличается файл от потока. И не мешать их вместе. Любой поток == файл, но не любой файл — поток.
Потоки обычно буферезерированы, но и файлы обычно тоже. Т.ч. в этом смысле разницы между fwrite(3) и write(2) никакой нет(первая работает с потоками, а вторая с файлами).
А вот ТСу надо курить до просветления man 3 fflush и связанные с ним топики. Если его вопрос в контексте потоков конечно. Если волнуют «просто файлы», курить надо man 2 sync и до кучи man 8 sync.
Неправильный ответ. Первая работает с объектами типа FILE, о которых операционная система ничего не знает, это внутренние структуры данных процесса. Вторая работает с хэндлами, которые есть непосредственный объект операционной системы.
И ты мне это про пятницу говорил?
Я тебя внимательно слушаю.
Не, точно пятница.
Минимальная единица объема информации для записи в файл
Неправильный ответ. Первая работает с объектами типа FILE, о которых операционная система ничего не знает, это внутренние структуры данных процесса. Вторая работает с хэндлами, которые есть непосредственный объект операционной системы.
У нас просто разное понимание термина «операционная система». Я подразумеваю под этим не только ядро, но и всё остальное. Потоки, которые пишет fwrite(3) определены в любой POSIX совместимой операционной системе. В частности в любом GNU/Linux. Потому говорить «ОС ничего не знает о потоках» неправильно. И да, «хэндлы» — тоже неверный термин(ИМХО), ты наверное хотел сказать «дескриптор»? Ну «file descriptor», в оригинале. Именно с ними и работает write(2).
И кстати, я не нашёл упоминания в man'е о совместимости с POSIX про write(2), но вот про fwrite(3) — таки нашёл. Посему fwrite(3) более «правильная» функция, а write(2) это какой-то самопальный велосипед. (:
Также и потоки — stream это более совместимая и ваще Ъ реализация, нежели твоя нетрушная linux-only file descriptor (:
Минимальная единица объема информации для записи в файл
моя EXT4 умеет минимум 4096 байт писать, НЕ менее. Даже если её sync'ать после каждого байта. Ну а потоки у меня минимум по 64К пишутся(если их не fflush'ить конечно). Т.ч. ты заблуждаешься.
И кстати, я не нашёл упоминания в man'е о совместимости с POSIX про write(2)
Потому что смотреть надо было write(3).
Потоки, которые пишет fwrite(3) определены в любой POSIX совместимой операционной системе.
strlen() тоже в любой POSIX-совместимой системе определено, и что? Это не делает строки объектом архитектуры операционной системы, такими как файлы, процессы и так далее.
Господа, мы отдаляемся от дискуссии. Во-первых, сегодня пятница..
Ты это. того. это самое. телепаты не вернулись из отпуска, короче.
Во-вторых, какая разница, объект или нет, если кэширование происходит в обоих случаях
Ты не пиши быстро
Разница, в том, что это за кэширование, и где оно происходит.
Например, убей процесс, который не сбросил буфер FILE-а, и почувствуй разницу.
Минимальная единица объема информации для записи в файл
моя EXT4 умеет минимум 4096 байт писать
А еще она умеет читать. В отличие от тебя.
очень познавательно, а зачем мне это?
Потому что смотреть надо было write(3).
Патрег такого мануала мне не дал. Следовательно его не существует. Это ересь и апокриф. (:
strlen() тоже в любой POSIX-совместимой системе определено, и что? Это не делает строки объектом архитектуры операционной системы, такими как файлы, процессы и так далее.
У нас просто разные точки зрения на одни и те же факты. С моей т.з. строки ASCIIZ являются объектом OS. Например имена файлов, и это не просто ASCIIZ, а ASCIIZ размером не более 256 байт.
Продолжим спорить о том, что _считать_ объектом, а что не считать? Я не против, но разъясни окружающим, что независимо от результата этой СО, ASCIIZ ну никак не изменятся. Как и потоки с файлами.
Во-вторых, какая разница, объект или нет, если кэширование происходит в обоих случаях
ну оно действительно по разному происходит. В struct FILE есть свой буфер (точнее даже два буфера, для чтения и для записи). А в том, на что указывает file descriptor тоже есть свой буфер(обычно). ТС, как я понял, спрашивал про второй буфер, а geekless рассказал нам про первый. Я так понимаю.
Например, убей процесс, который не сбросил буфер FILE-а, и почувствуй разницу.
в отличие от тебя, я умею читать первый пост целиком, а не только subject. Что-бы тебе было проще научится, я процитирую:
Однако следует иметь в виду, что программа, которая реализует запись данных в файл, может буферизировать свои выходные данные. Даже если строки будут добавляться регулярно (с точки зрения логики), они могут стать видимыми только фрагментами объемом 1 или 4 Кбайт (KiB).
И тут я окончательно запутался, то что программа может использовать буферизацию вполне логично и понятно. Всегда считал что программа может записать в файл если информации на запись минимум один байт, но данная цитата с присущими в ней приставками сбили с толку. Поясните русским языком. да-да, стыдно.
И если ты внимательно рассмотришь практически любой процесс записи в практически любое блочное устройство, ты осознаешь, что действительно, запись происходит не по одному байту.
Товарищи, а может не будем так сильно вдаваться в саму реализацию. В любом случаи на данный момент у меня сложилось следующие впечатление: минимальная единица объема информации для записи в файл может зависит от реализации данной функции в самом приложении/OC, а так же от файловой системы на которую будет производиться запись.
Но мне остается до сих пор не понятно почему в книжке стоит «1 или 4 Кбайт (KiB)», а не 1 байт. 1 килобайт!=1 байт.
минимальная единица объема информации для записи в файл может зависит от реализации данной функции в самом приложении/O
В POSIX, минимальная единица записи в файл ОС - 1 байт. Поверх этого могут быть любые объемы буферизации, снизу могут быть любые размеры блоков В/В, но ОС гарантирует, что ты можешь записать 1 байт.
В книжке приведены наиболее частые значения потокового буфера (допустим функция fprintf()) по умолчанию в разных системах. Как я понял, всё что хотел скзать автор, что если делается конвеер их всяких там:
tail | grep | sed > FILE
то вот этот файл скорее всего будет меняться в размере по 1 или 4 кБайта и это нужно знать.
Но программа, если захочет, может не буферизировать свои выходные данные и в файле будет сколько она запишет байт.
И здесь речь идёт о файле со стороны пользовательских процессов, то, как файл пишется на жёсткий диск (по секторам или по 4 кБайт) это вобще другое.
Сдаётся мне, что это из-за чувствительного цветовосприятия.
Я думаю, чувствительность цветовосприятия является симптомом каких-то более глубоких проблем.
Но мне остается до сих пор не понятно почему в книжке стоит «1 или 4 Кбайт (KiB)», а не 1 байт. 1 килобайт!=1 байт.
в той части книжки речь идёт о блочном устройстве, оно так называется потому, что умеет писать только БЛОКАМИ. Так понятно? Если речь про FS(файловая система), то размер блока там 4К (для ext4), потому запись в файл на блочном устройстве ВСЕГДА по 4К и никогда не меньше. И ненулевой файл занимает ВСЕГДА 4К или больше(причём размер ВСЕГДА делится на 4К. Конечно сам размер может быть любым, но если он не делится на 4096, остаток забивается мусором или нулями).
А в древности иногда делали и в 1К, если диск маленький, и файлов _очень_ много. Сейчас не делают, просто потому, что диски большие стали. Ещё можно 512 и 2048, но сегодня ненужно. Было-бы круто 8192, но нельзя.
Кстати, размер страницы памяти тоже 4К(сейчас), потому ты не можешь выделить и кусок памяти менее 4К. Конечно ты можешь написать malloc(1), но выделится не один байт, а все 4096. Это такая _конструктивная_ особенность x86, он иначе не умеет (точнее умеет, но страницы ещё больше могут быть, но никак НЕ меньше)
В POSIX, минимальная единица записи в файл ОС - 1 байт. Поверх этого могут быть любые объемы буферизации, снизу могут быть любые размеры блоков В/В, но ОС гарантирует, что ты можешь записать 1 байт.
ну создай мне файл, про который du скажет, что он занимает 1 байт. У меня не получилось. Как не изворачивайся, получается 4К. Хотя размер файла да, может быть 1байт, но это не значит, что записывается именно один. А не 4096.
ЕМНИП он никогда не был равен 1 или 4К. Во всяком случае последние 15 лет он везде не меньше 32К. Т.ч. речь о каком-то другом «буфере».
Но мне остается до сих пор не понятно почему в книжке стоит «1 или 4 Кбайт (KiB)»
Потому что книжка — говно, вероятно.
tail | grep | sed > FILE то вот этот файл скорее всего будет меняться в размере по 1 или 4 кБайта и это нужно знать. Но программа, если захочет, может не буферизировать свои выходные данные и в файле будет сколько она запишет байт.
кстати неправильно ты понимаешь: эти команды в этом случае НЕ МОГУТ управлять буфером. Это не их буфер. И ессно никак не могут отключить буферизацию.
Однако, grep и sed могут сбрасывать буфер в конце каждой строки (см. --line-buffered для grep и --unbuffered для sed), это нужно помнить, что-бы не удивляться, когда top|grep '. '|sed '. ' «не работает». Работает, но нужно упомянутые ключики применить.
я думаю, ТСу будет понятно, кто здесь «говно». (:
кстати неправильно ты понимаешь: эти команды в этом случае НЕ МОГУТ управлять буфером. Это не их буфер. И ессно никак не могут отключить буферизацию.
. гиперактивный генератор бреда выходит на максимальную мощность.
Однако, grep и sed могут сбрасывать буфер в конце каждой строки
tailgunner не прав был выше: читать-то ты может и умеешь. И даже писать. А вот думать — нет.
Слышь парнокопытное, открой для себя размер кластера файловой системы.
Ты давай фекалиями не разбрасывайся. Обезьянка сказала, что книжка говно, и он это правильно в пятницу сделал.
. гиперактивный генератор бреда выходит на максимальную мощность.
Я не уверен, что это предел
Слышь парнокопытное, открой для себя размер кластера файловой системы.
Ты давай фекалиями не разбрасывайся. Обезьянка сказала, что книжка говно, и он это правильно в пятницу сделал.
т.е. обезьянке можно говном кидаться, а парнокопытным в пятницу нельзя? А пернатым?
Книжку не читал, но в моей glibc 4 кБайт это размер буфера по умолчанию для вывода в файл. А 1024 байта (или около того) размер буфера при выводе stdout вывода на терминал (да, он line buffered, но для длинной строки будет несколько write() ).
Если читать название книги, то слово Unix, ИМХО, подразумевает множество ОС, вполне возможно, что где-то и для вывода в файл по умолчанию 1 кБайт.
Да нет, был когда то давно, он вобще определяется разрядностью процессора, это на Intel 4004 были 4 кбайт буфер, а сейчас с нормальными процессорами на 64 бита всё стало больше.
Не знаю зачем, но всё же покажу пример скрипта, может ТС разберётся в нём и поймёт о чём речь:
Если sed'у дать опцию ″-u″, то размер этого файла будет изменяться не по 4 кБайт, а по 1180 байт.
эти команды в этом случае НЕ МОГУТ управлять буфером.
Однако, grep и sed могут сбрасывать буфер в конце каждой строки
То есть сброс буфера это не управление? А вобще, ″man setvbuf″.
man mke2fs, в районе -b block-size
т.е. обезьянке можно говном кидаться, а парнокопытным в пятницу нельзя? А пернатым?