Здравствуйте, rg45, Вы писали:
r> std::vector<uint8_t> bytes(std::filesystem::file_size(path)); r> input.read(bytes.data(), bytes.size());
Как я понял, в случае если файл обрежется или перезапишется другим файлом конкурентно, то в хвосте массива будут нули. Happy debugging.
По уму надо ещё читать gcount и обрезать.
В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.
Здравствуйте, ·, Вы писали:
·>Как я понял, в случае если файл обрежется конкурентно, то в хвосте массива будут нули. Happy debugging. ·>По уму надо ещё читать gcount и обрезать. ·>В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.
На библиотечную функцию общего применения это не тянет, конечно, и я об этом уже упоминал. Но как частное решение, когда заведомо известно, что файлы не изменяются в реальном времени — вполне. Преимущество этого решения — простота (но не универсальность).
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Как в одну строку кода прочитать содержимое файла в масс
Здравствуйте, rg45, Вы писали:
R>·>Как я понял, в случае если файл обрежется конкурентно, то в хвосте массива будут нули. Happy debugging. R>·>По уму надо ещё читать gcount и обрезать. R>·>В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься. R>На библиотечную функцию общего применения это не тянет, конечно, и я об этом уже упоминал. Но как частное решение, когда заведомо известно, что файлы не изменяются в реальном времени — вполне. Преимущество этого решения — простота (но не универсальность).
Именно. Поэтому я считаю, что это вполне возможно и достаточно оправдано сделать универсальное и надёжное решение в стандартной библиотеке. Т.к. частное решение в две строчки может иметь очень тонкие баги.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, ·, Вы писали:
R>>·>Как я понял, в случае если файл обрежется конкурентно, то в хвосте массива будут нули. Happy debugging. R>>·>По уму надо ещё читать gcount и обрезать. R>>·>В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.
Хотя, эта проблема закрывается ценой еще одного небольшого усложнения, всего в одну строчку, но функция по-прежнему выглядит достаточно простой:
·>Именно. Поэтому я считаю, что это вполне возможно и достаточно оправдано сделать универсальное и надёжное решение в стандартной библиотеке. Т.к. частное решение в две строчки может иметь очень тонкие баги.
Ну, не знаю, как по мне, борьбу эффективности и универсальности никто не отменял и никогда не отменит. Всегда возникали и будут возникать ситуации, когда частное специальное решение будет более предпочтительным, чем общее универсальное. Часто стремление получить общее универсальное решение приводит к созданию ужасных монстров. Взять ту же File.ReadAllBytes — вы уверены, что в ней учтены все возможные нюансы на все случаи жизни? Я ничего не утверждаю, я интересуюсь. Что если окажется, что эта функция работает плохо или вообще не работает при каких-то экзотических условиях и не удовлетворяет каким-то очень специальным требованиям?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
r> input.read(bytes.data(), bytes.size());
Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. Да, могут быть реаллокации в экзотических случаях, но хотя бы результат будет точным всегда.
r> Ну, не знаю, как по мне, то борьбу эффективности и универсальности никто не отменял и никогда не отменит. Всегда возникали и будут возникать ситуации, когда частное решение будет более предпочтительным, чем общее универсальное. Очень часто стремление получить общее универсальное решение приводит к созданию ужасных монстров.
Если хорошо почесать голову, то, мне кажется, общее универсальное решение для readall вполне возможно.
А так боясь монстров можно и str.empty() запретить. Есть же size() == 0.
r>Программист C++ в этом случает сядет и напишет-таки то, что ему будет нужно, а что будет делать программист C#?
Да то же самое. Низкоуровневое api никто же не отменял.
Здравствуйте, ·, Вы писали:
·>Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. Да, могут быть реаллокации в экзотических случаях, но хотя бы результат будет точным всегда.
File.GetAllBytes именно так и ведет себя, вы проверяли? А если изменился не размер, а содержимое? Как вообще можно быть уверенным в том, что та последовательность байт, которую мы загрузили в буфер, когда-либо существовала в реальном времени?
Лично я склоняюсь к тому, что потребнось в загрузке файлов, изменяющихся в реальном времени — это как раз-таки котраргумент против существования такой функции общего применения. Ибо спектр потребностей и хотелок в этой области может оказаться просто необъятным. Так или иначе придется идти на какие-то мутные компромисы и в результате получить монстра с неясным поведением. Тут, по-хорошему, уже файл маппинг нужен, а не read_all_bytes.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, ·, Вы писали:
·> Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать.
Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
Здравствуйте, rudzuk, Вы писали:
R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
О как! read возвращает количество байт, оказывается? Ну-ну.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[9]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, rg45, Вы писали:
r> R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
r> О как! read возвращает количество байт, оказывается? Ну-ну.
Здравствуйте, rudzuk, Вы писали:
R>man read, clown...
Да-да, именно про этот read ты и говорил. При обсуждении кросс-платформенной реализации чтения содержимого файла. Ты там животик свой желтенький не стер еще, ужик?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
r> R>man read, clown...
r> Да-да, именно про этот read ты и говорил. При обсуждении кросс-платформенной реализации чтения содержимого файла. Ты там животик свой желтенький не стер еще, ужик?
Здравствуйте, rudzuk, Вы писали:
R>·> Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
Ты уверен? Где об этом можно почитать?
Наверняка какие-нибудь стандартные cat/grep такое не делают, читают блоками, и всё как-то работает.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, rg45, Вы писали:
R>·>Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. Да, могут быть реаллокации в экзотических случаях, но хотя бы результат будет точным всегда. R>File.GetAllBytes именно так и ведет себя, вы проверяли? А если изменился не размер, а содержимое? Как вообще можно быть уверенным в том, что та последовательность байт, которую мы загрузили в буфер, когда-либо существовала в реальном времени?
Конечно, данные могут бы неконсистентными при конкурентной модификации, но по крайней мере не должен появляться мусор в виде нулей.
R>Лично я склоняюсь к тому, что потребнось в загрузке файлов, изменяющихся в реальном времени — это как раз-таки котраргумент против существования такой функции общего применения. Ибо спектр потребностей и хотелок в этой области может оказаться просто необъятным. Так или иначе придется идти на какие-то мутные компромисы и в результате получить монстра с неясным поведением. Тут, по-хорошему, уже файл маппинг нужен, а не read_all_bytes.
Сам не искал, но мне кажется, что есть какие-то ожидания о том как должны читаться файлы, и это даже должно быть документировано. По крайней мере, всякие стандартные тулзы типа cat/grep/awk работают вполне ожидаемым способом.
Уверен, что появление случайных нулей никто не ожидает.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, ·, Вы писали:
·>Конечно, данные могут бы неконсистентными при конкурентной модификации, но по крайней мере не должен появляться мусор в виде нулей.
Да обрезать-то буфер по gcount — дело не хитрое, только что это решает, по большому счету? Ну будет мусор не в виде нулей, а просто последовательность байт, которая никогда не существовала — голова соответствует одному состоянию, хвтост другому, середина третьему — чем это лучше? Возможно, для какого частного случая это и будет приемлемо, но требования к общей реализаци все равно под вопросом. Так или иначе, это будет какой-то компромиссный вариант, который будет иметь какие-то ограничения по применению. Вопрос лишь в том, где будет проходить граница этих ограничений.
Ну и все-таки, интересно, как работает метод ReadAllBytes для файлов, изменяющихся в реальном времени. В документации я не нахожу никаких гарантий относительно этого.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
r> Да обрезать-то буфер по gcount — дело не хитрое, только что это решает, по большому счету? Ну будет мусор не в виде нулей, а просто последовательность байт, которая никогда не существовала — голова соответствует одному состоянию, хвтост другому, середина третьему — чем это лучше?
Как минимум лучше тем, что поведение — консистентно с другими средствами чтения файлов, таких как cat/grep/cp/etc. Я бы не хотел чтобы grep находил \0 в текстовых файлах ни при каких условиях.
r> Возможно, для какого частного случая это и будет приемлемо, но требования к общей реализаци все равно под вопросом. Так или иначе, это будет какой-то компромиссный вариант, который будет иметь какие-то ограничения по применению. Вопрос лишь в том, где будет проходить граница этих ограничений.
Естественно. Для этого и нужна _стандартная_ библиотека, чтобы обеспечивать общепринятыми компромисами. Ради принципа наименьшего удивления. А для частных случаев есть низкоуровневое api и программист волен подпиливать решение, если чем-то общепринятое не устраивает.
r> Ну и все-таки, интересно, как работает метод ReadAllBytes для файлов, изменяющихся в реальном времени. В документации я не нахожу никаких гарантий относительно этого.
Тут полагаю надо исходники читать.
Здравствуйте, ·, Вы писали:
r>> Ну и все-таки, интересно, как работает метод ReadAllBytes для файлов, изменяющихся в реальном времени. В документации я не нахожу никаких гарантий относительно этого. ·>Тут полагаю надо исходники читать.
Так что, выходит, что никто из присутствующих точно не знает, как работает ReadAllBytes для файлов, изменяющихся в реальном времени? В таком случае, может мне кто-нибудь объяснить, откуда могло появиться требовани поддрежки чтения файлов "с учетом фолбека для спец. файлов в некоторых ОС" вот в этот момент обсуждения: http://rsdn.org/forum/cpp/8662389.1
Здравствуйте, ·, Вы писали:
·> R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
·> Ты уверен? Где об этом можно почитать?
Не помню, где читал доку, но помню, что консистентность таких файлов при последовательном чтении не гарантируется. Сходу гуглится вот это: https://stackoverflow.com/a/5880485
·> Наверняка какие-нибудь стандартные cat/grep такое не делают, читают блоками, и всё как-то работает.
Здравствуйте, rudzuk, Вы писали:
R>·> Ты уверен? Где об этом можно почитать? R>Не помню, где читал доку, но помню, что консистентность таких файлов при последовательном чтении не гарантируется. Сходу гуглится вот это: https://stackoverflow.com/a/5880485
Да, весёлое обсуждение. Но как я вижу, есть тенденция к исправлению багов, продумыванию дизайна, все хотят иметь атомарность и консистентность.
R>·> Наверняка какие-нибудь стандартные cat/grep такое не делают, читают блоками, и всё как-то работает. R>Как-то оно будет работать
Тем более это — аргумент в пользу того, что это должно быть в стандартной либе, чтобы хоть как-то более менее согласовано было. И если обнаруживают баги, то они правятся централизовано, а не каждый правит свой двухстрочник.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай