Re: Как в одну строку кода прочитать содержимое файла в массив?
От: tryAnother  
Дата: 05.01.24 21:08
Оценка:
В далеком 5 году обсуждали разные варианты чтения, вроде не заметил тут ссылки на тот пост.

Там 7 вариантов
Автор: eao197
Дата: 24.05.05
, а потом еще 2
Автор: eao197
Дата: 24.05.05
.
Re[2]: Как в одну строку кода прочитать содержимое файла в м
От: · Великобритания  
Дата: 05.01.24 21:53
Оценка: +1
Здравствуйте, rg45, Вы писали:

r> std::vector<uint8_t> bytes(std::filesystem::file_size(path));

r> input.read(bytes.data(), bytes.size());
Как я понял, в случае если файл обрежется или перезапишется другим файлом конкурентно, то в хвосте массива будут нули. Happy debugging.
По уму надо ещё читать gcount и обрезать.
В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 05.01.2024 21:54 · . Предыдущая версия .
Re[3]: Как в одну строку кода прочитать содержимое файла в масс
От: rg45 СССР  
Дата: 05.01.24 21:56
Оценка:
Здравствуйте, ·, Вы писали:

·>Как я понял, в случае если файл обрежется конкурентно, то в хвосте массива будут нули. Happy debugging.

·>По уму надо ещё читать gcount и обрезать.
·>В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.

На библиотечную функцию общего применения это не тянет, конечно, и я об этом уже упоминал. Но как частное решение, когда заведомо известно, что файлы не изменяются в реальном времени — вполне. Преимущество этого решения — простота (но не универсальность).
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Как в одну строку кода прочитать содержимое файла в масс
От: · Великобритания  
Дата: 05.01.24 22:08
Оценка:
Здравствуйте, rg45, Вы писали:

R>·>Как я понял, в случае если файл обрежется конкурентно, то в хвосте массива будут нули. Happy debugging.

R>·>По уму надо ещё читать gcount и обрезать.
R>·>В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.
R>На библиотечную функцию общего применения это не тянет, конечно, и я об этом уже упоминал. Но как частное решение, когда заведомо известно, что файлы не изменяются в реальном времени — вполне. Преимущество этого решения — простота (но не универсальность).
Именно. Поэтому я считаю, что это вполне возможно и достаточно оправдано сделать универсальное и надёжное решение в стандартной библиотеке. Т.к. частное решение в две строчки может иметь очень тонкие баги.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Как в одну строку кода прочитать содержимое файла в м
От: rg45 СССР  
Дата: 05.01.24 22:24
Оценка:
Здравствуйте, ·, Вы писали:

R>>·>Как я понял, в случае если файл обрежется конкурентно, то в хвосте массива будут нули. Happy debugging.

R>>·>По уму надо ещё читать gcount и обрезать.
R>>·>В общем, если писать надёжное, работающее решение во всяких экзотических случаях, то хитро всё становится, в две строчки не уложишься.

Хотя, эта проблема закрывается ценой еще одного небольшого усложнения, всего в одну строчку, но функция по-прежнему выглядит достаточно простой:

std::vector<uint8_t> read_all_bytes(const std::string& path)
{
   std::basic_ifstream<uint8_t> input(path.c_str(), std::ios_base::binary | std::ios_base::ate);
   std::vector<uint8_t> bytes(input.tellg());
   input.seekg(0);
   input.read(bytes.data(), bytes.size());
   return bytes;
}


·>Именно. Поэтому я считаю, что это вполне возможно и достаточно оправдано сделать универсальное и надёжное решение в стандартной библиотеке. Т.к. частное решение в две строчки может иметь очень тонкие баги.


Ну, не знаю, как по мне, борьбу эффективности и универсальности никто не отменял и никогда не отменит. Всегда возникали и будут возникать ситуации, когда частное специальное решение будет более предпочтительным, чем общее универсальное. Часто стремление получить общее универсальное решение приводит к созданию ужасных монстров. Взять ту же File.ReadAllBytes — вы уверены, что в ней учтены все возможные нюансы на все случаи жизни? Я ничего не утверждаю, я интересуюсь. Что если окажется, что эта функция работает плохо или вообще не работает при каких-то экзотических условиях и не удовлетворяет каким-то очень специальным требованиям?
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 05.01.2024 22:39 rg45 . Предыдущая версия . Еще …
Отредактировано 05.01.2024 22:26 rg45 . Предыдущая версия .
Отредактировано 05.01.2024 22:25 rg45 . Предыдущая версия .
Отредактировано 05.01.2024 22:24 rg45 . Предыдущая версия .
Отредактировано 05.01.2024 22:24 rg45 . Предыдущая версия .
Re[6]: Как в одну строку кода прочитать содержимое файла в м
От: · Великобритания  
Дата: 05.01.24 22:38
Оценка:
Здравствуйте, rg45, Вы писали:

r> input.read(bytes.data(), bytes.size());

Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. Да, могут быть реаллокации в экзотических случаях, но хотя бы результат будет точным всегда.

r> Ну, не знаю, как по мне, то борьбу эффективности и универсальности никто не отменял и никогда не отменит. Всегда возникали и будут возникать ситуации, когда частное решение будет более предпочтительным, чем общее универсальное. Очень часто стремление получить общее универсальное решение приводит к созданию ужасных монстров.

Если хорошо почесать голову, то, мне кажется, общее универсальное решение для readall вполне возможно.
А так боясь монстров можно и str.empty() запретить. Есть же size() == 0.

r>Программист C++ в этом случает сядет и напишет-таки то, что ему будет нужно, а что будет делать программист C#?

Да то же самое. Низкоуровневое api никто же не отменял.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[7]: Как в одну строку кода прочитать содержимое файла в м
От: rg45 СССР  
Дата: 05.01.24 23:27
Оценка: +1
Здравствуйте, ·, Вы писали:

·>Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. Да, могут быть реаллокации в экзотических случаях, но хотя бы результат будет точным всегда.


File.GetAllBytes именно так и ведет себя, вы проверяли? А если изменился не размер, а содержимое? Как вообще можно быть уверенным в том, что та последовательность байт, которую мы загрузили в буфер, когда-либо существовала в реальном времени?

Лично я склоняюсь к тому, что потребнось в загрузке файлов, изменяющихся в реальном времени — это как раз-таки котраргумент против существования такой функции общего применения. Ибо спектр потребностей и хотелок в этой области может оказаться просто необъятным. Так или иначе придется идти на какие-то мутные компромисы и в результате получить монстра с неясным поведением. Тут, по-хорошему, уже файл маппинг нужен, а не read_all_bytes.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 06.01.2024 0:00 rg45 . Предыдущая версия . Еще …
Отредактировано 05.01.2024 23:35 rg45 . Предыдущая версия .
Отредактировано 05.01.2024 23:34 rg45 . Предыдущая версия .
Отредактировано 05.01.2024 23:28 rg45 . Предыдущая версия .
Re[7]: Как в одну строку кода прочитать содержимое файла в м
От: rudzuk  
Дата: 06.01.24 00:20
Оценка:
Здравствуйте, ·, Вы писали:

·> Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать.


Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
avalon/3.0.2
Re[8]: Как в одну строку кода прочитать содержимое файла в м
От: rg45 СССР  
Дата: 06.01.24 00:37
Оценка:
Здравствуйте, rudzuk, Вы писали:

R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.


О как! read возвращает количество байт, оказывается? Ну-ну.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[9]: Как в одну строку кода прочитать содержимое файла в м
От: rudzuk  
Дата: 06.01.24 06:38
Оценка:
Здравствуйте, rg45, Вы писали:

r> R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.


r> О как! read возвращает количество байт, оказывается? Ну-ну.


man read, clown...
avalon/3.0.2
Re[10]: Как в одну строку кода прочитать содержимое файла в
От: rg45 СССР  
Дата: 06.01.24 09:42
Оценка:
Здравствуйте, rudzuk, Вы писали:

R>man read, clown...


Да-да, именно про этот read ты и говорил. При обсуждении кросс-платформенной реализации чтения содержимого файла. Ты там животик свой желтенький не стер еще, ужик?
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 06.01.2024 10:09 rg45 . Предыдущая версия . Еще …
Отредактировано 06.01.2024 9:51 rg45 . Предыдущая версия .
Отредактировано 06.01.2024 9:51 rg45 . Предыдущая версия .
Отредактировано 06.01.2024 9:48 rg45 . Предыдущая версия .
Re[11]: Как в одну строку кода прочитать содержимое файла в
От: rudzuk  
Дата: 06.01.24 10:31
Оценка:
Здравствуйте, rg45, Вы писали:

r> R>man read, clown...


r> Да-да, именно про этот read ты и говорил. При обсуждении кросс-платформенной реализации чтения содержимого файла. Ты там животик свой желтенький не стер еще, ужик?


Засохни уже, клоун.
avalon/3.0.2
Re[8]: Как в одну строку кода прочитать содержимое файла в м
От: · Великобритания  
Дата: 06.01.24 10:37
Оценка:
Здравствуйте, rudzuk, Вы писали:

R>·> Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать.

R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.
Ты уверен? Где об этом можно почитать?
Наверняка какие-нибудь стандартные cat/grep такое не делают, читают блоками, и всё как-то работает.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 06.01.2024 10:44 · . Предыдущая версия .
Re[12]: Как в одну строку кода прочитать содержимое файла в
От: rg45 СССР  
Дата: 06.01.24 10:38
Оценка:
Здравствуйте, rudzuk, Вы писали:

R>Засохни уже, клоун.


Вафельницу свою захлопни, чепушило.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[8]: Как в одну строку кода прочитать содержимое файла в м
От: · Великобритания  
Дата: 06.01.24 10:42
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>·>Да та же проблема. Надо резервировать массив, читать файл до конца и обрезать хвост. А если размер файла внезапно вырос (как /proc/self/status), то реаллоцировать. Да, могут быть реаллокации в экзотических случаях, но хотя бы результат будет точным всегда.

R>File.GetAllBytes именно так и ведет себя, вы проверяли? А если изменился не размер, а содержимое? Как вообще можно быть уверенным в том, что та последовательность байт, которую мы загрузили в буфер, когда-либо существовала в реальном времени?
Конечно, данные могут бы неконсистентными при конкурентной модификации, но по крайней мере не должен появляться мусор в виде нулей.

R>Лично я склоняюсь к тому, что потребнось в загрузке файлов, изменяющихся в реальном времени — это как раз-таки котраргумент против существования такой функции общего применения. Ибо спектр потребностей и хотелок в этой области может оказаться просто необъятным. Так или иначе придется идти на какие-то мутные компромисы и в результате получить монстра с неясным поведением. Тут, по-хорошему, уже файл маппинг нужен, а не read_all_bytes.

Сам не искал, но мне кажется, что есть какие-то ожидания о том как должны читаться файлы, и это даже должно быть документировано. По крайней мере, всякие стандартные тулзы типа cat/grep/awk работают вполне ожидаемым способом.
Уверен, что появление случайных нулей никто не ожидает.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Как в одну строку кода прочитать содержимое файла в м
От: rg45 СССР  
Дата: 06.01.24 10:52
Оценка:
Здравствуйте, ·, Вы писали:

·>Конечно, данные могут бы неконсистентными при конкурентной модификации, но по крайней мере не должен появляться мусор в виде нулей.


Да обрезать-то буфер по gcount — дело не хитрое, только что это решает, по большому счету? Ну будет мусор не в виде нулей, а просто последовательность байт, которая никогда не существовала — голова соответствует одному состоянию, хвтост другому, середина третьему — чем это лучше? Возможно, для какого частного случая это и будет приемлемо, но требования к общей реализаци все равно под вопросом. Так или иначе, это будет какой-то компромиссный вариант, который будет иметь какие-то ограничения по применению. Вопрос лишь в том, где будет проходить граница этих ограничений.

Ну и все-таки, интересно, как работает метод ReadAllBytes для файлов, изменяющихся в реальном времени. В документации я не нахожу никаких гарантий относительно этого.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 06.01.2024 10:56 rg45 . Предыдущая версия .
Re[10]: Как в одну строку кода прочитать содержимое файла в м
От: · Великобритания  
Дата: 06.01.24 11:20
Оценка:
Здравствуйте, rg45, Вы писали:

r> Да обрезать-то буфер по gcount — дело не хитрое, только что это решает, по большому счету? Ну будет мусор не в виде нулей, а просто последовательность байт, которая никогда не существовала — голова соответствует одному состоянию, хвтост другому, середина третьему — чем это лучше?

Как минимум лучше тем, что поведение — консистентно с другими средствами чтения файлов, таких как cat/grep/cp/etc. Я бы не хотел чтобы grep находил \0 в текстовых файлах ни при каких условиях.

r> Возможно, для какого частного случая это и будет приемлемо, но требования к общей реализаци все равно под вопросом. Так или иначе, это будет какой-то компромиссный вариант, который будет иметь какие-то ограничения по применению. Вопрос лишь в том, где будет проходить граница этих ограничений.

Естественно. Для этого и нужна _стандартная_ библиотека, чтобы обеспечивать общепринятыми компромисами. Ради принципа наименьшего удивления. А для частных случаев есть низкоуровневое api и программист волен подпиливать решение, если чем-то общепринятое не устраивает.

r> Ну и все-таки, интересно, как работает метод ReadAllBytes для файлов, изменяющихся в реальном времени. В документации я не нахожу никаких гарантий относительно этого.

Тут полагаю надо исходники читать.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[11]: Как в одну строку кода прочитать содержимое файла в м
От: rg45 СССР  
Дата: 06.01.24 11:41
Оценка:
Здравствуйте, ·, Вы писали:

r>> Ну и все-таки, интересно, как работает метод ReadAllBytes для файлов, изменяющихся в реальном времени. В документации я не нахожу никаких гарантий относительно этого.

·>Тут полагаю надо исходники читать.

Так что, выходит, что никто из присутствующих точно не знает, как работает ReadAllBytes для файлов, изменяющихся в реальном времени? В таком случае, может мне кто-нибудь объяснить, откуда могло появиться требовани поддрежки чтения файлов "с учетом фолбека для спец. файлов в некоторых ОС" вот в этот момент обсуждения: http://rsdn.org/forum/cpp/8662389.1
Автор: rudzuk
Дата: 05.01 16:13
?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[9]: Как в одну строку кода прочитать содержимое файла в м
От: rudzuk  
Дата: 06.01.24 12:11
Оценка:
Здравствуйте, ·, Вы писали:

·> R>Такие спец. файлы нужно читать полностью за один прием т.к. они консистентны только в рамках одного вызова read(); Если read() вернула количество байт равное размеру буфера, то буфер нужно увеличивать, а файл перечитывать.


·> Ты уверен? Где об этом можно почитать?


Не помню, где читал доку, но помню, что консистентность таких файлов при последовательном чтении не гарантируется. Сходу гуглится вот это: https://stackoverflow.com/a/5880485

·> Наверняка какие-нибудь стандартные cat/grep такое не делают, читают блоками, и всё как-то работает.


Как-то оно будет работать
avalon/3.0.2
Re[10]: Как в одну строку кода прочитать содержимое файла в м
От: · Великобритания  
Дата: 06.01.24 13:08
Оценка: +1
Здравствуйте, rudzuk, Вы писали:

R>·> Ты уверен? Где об этом можно почитать?

R>Не помню, где читал доку, но помню, что консистентность таких файлов при последовательном чтении не гарантируется. Сходу гуглится вот это: https://stackoverflow.com/a/5880485
Да, весёлое обсуждение. Но как я вижу, есть тенденция к исправлению багов, продумыванию дизайна, все хотят иметь атомарность и консистентность.

R>·> Наверняка какие-нибудь стандартные cat/grep такое не делают, читают блоками, и всё как-то работает.

R>Как-то оно будет работать
Тем более это — аргумент в пользу того, что это должно быть в стандартной либе, чтобы хоть как-то более менее согласовано было. И если обнаруживают баги, то они правятся централизовано, а не каждый правит свой двухстрочник.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.