Информация об изменениях

Сообщение Re[5]: Как в одну строку кода прочитать содержимое файла в м от 07.01.2024 17:07

Изменено 07.01.2024 18:48 rg45

Re[5]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, Kluev, Вы писали:

R>>>>
R>>>>std::vector<uint8_t> read_all_bytes(const std::string& path)
R>>>>{
R>>>>   std::basic_ifstream<uint8_t> input(path.c_str(), std::ios_base::binary);
R>>>>   std::vector<uint8_t> bytes(std::filesystem::file_size(path));
R>>>>   input.read(bytes.data(), bytes.size());
R>>>>   return bytes;
R>>>>}
R>>>>


K>В этой лапше одна часть библиотеки не знает о существовании другой, через костыль c_str работает. О какой вообще читаемости может идти речь?


Ну это не так. Начиная с C++11 c_str можно не писать. Я это написал просто по привычке. Даже не предполагал, что это может кого-то напрячь.

K>Здесь, же черт, возьми живого места нет. Зачем к uint8 _t? в basic_ifstream, зачем этот basic, там что advanced есть?


Ну просто потому что я хотел подчеркнуть, что для описания массива байт можно использовать беззнаковый тип, только и всего. Пожалуйста, можно с тем же успехом работать и с обычным char (который используется по умолчанию). И тогда вместо std::basic_ifstream<uint8_t> можно написать просто std::ifstream. Я же не знаю требований программы, поэтому демонстрировал возможности. Хотел как лучше, получилось как всегда.

K>ifstream — это от оператора if или от чего? почему лишнее basic_ важнее input и file, что на него аж 5 букв, а на файл инпут по одной в if? Почему basic через сепаратор _, а i и f нет?


Ну, во-первых потому, что было рассчитано, что чаше будет использоваться алиас std::ifstream, а basic_isteream — реже и по мере необходимости. А во-вторых, это просто придирки к именам. Тут на вкус и цвет все фломастеры разные и, наверное, в любом языке можно докопаться до столба. Меня, например, очень раздражают вебрблюжьи горбы в C#, так что теперь — всех расстрелять, потом разогнать?

K>зачем здесь при file_size(path) filesystem, что есть какой-то другой file_size не в файловой системе, а в солнечной?


Ну ты сейчас обсуждаешь мой личный стиль и мои личные предпочтения, а не особенности языка С++. Да, я не вижу никакой трагедии в использовании полно-квалифицированных имен. Но если для кого-то это так важно, пожалуйста — в C++, так же как и в C# есть using директивы. А еще есть и using — объявления и алиасы пространств имен — пожалуйста, делайте себе синтаксический сахар сколько влезет.

K>Все это кошмарная халтура за которую комитет давно пора разогнать.


Да прям уж. Какая, нафиг, разница, что там внутри функции, главное же, чтоб работала правильно. Тебе часто приходится заглядывать внутрь File.ReadAllBytes?

R>>Ну и главное — это пишется один раз, в использовании же это не сложнее, чем File.ReadAllBytes. И даже чуть проще, потому что "File." писать не нужно:


K>Хде оно пишется один раз? Разве что в посте на rsdn и забывается как страшный сон. А в реальной жизни под это дело надо где-то создать хедер, подключить каталог к каждому проекту. Это повезло, что исходника нет, иначе обеспечены танцы с бубном с библиотеками. Ведь поддержки библиотек в с++ нет. Есть только бесконечный зоопарк костылей.

K>В С++ нет такого места где можно написать один раз. Наш добрый гений старуструп еще не в курсе что существуют такие технологии.

А в чем проблемы-то? Всю жизнь писали и пишем общие библиотеки на самых разных уровнях. И при чем тут Страуструп?

K>Да легко. В input.read размер streamsize — знаковый, а vector.size() который туда передается беззнаковый. на 32 бит платформе тип возвращаемый file_size и размер в конструкторе вектора имеют разную размерность. Т.е. данный говнокод может легко рыгнуть уже на целочисленном переполнении, не говоря уже о других проблемах озвученных другими собеседниками выше.


Ну это опять же сугубо мой косяк, который я там дальше по ходу обсуждения и поправил: http://rsdn.org/forum/cpp/8662776.1
Автор: rg45
Дата: 06.01 01:24
.

А с учетом сказанного выше по тексту, можно сделать еще и покомпактнее:

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


Здесь, конечно же, vector.size() беззнаковый, но размер вектора инициализируется по значению, возвращаемому tellg(), которое имеет тип std::streamsize и переполнение невозможно.

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

Что-то еще? Ты там про триллион багов говорил.
Re[5]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, Kluev, Вы писали:

R>>>>
R>>>>std::vector<uint8_t> read_all_bytes(const std::string& path)
R>>>>{
R>>>>   std::basic_ifstream<uint8_t> input(path.c_str(), std::ios_base::binary);
R>>>>   std::vector<uint8_t> bytes(std::filesystem::file_size(path));
R>>>>   input.read(bytes.data(), bytes.size());
R>>>>   return bytes;
R>>>>}
R>>>>


K>В этой лапше одна часть библиотеки не знает о существовании другой, через костыль c_str работает. О какой вообще читаемости может идти речь?


Ну это не так. Начиная с C++11 c_str можно не писать. Я это написал просто по привычке. Даже не предполагал, что это может кого-то напрячь.

K>Здесь, же черт, возьми живого места нет. Зачем к uint8 _t? в basic_ifstream, зачем этот basic, там что advanced есть?


Ну просто потому что я хотел подчеркнуть, что для описания массива байт можно использовать беззнаковый тип, только и всего. Пожалуйста, можно с тем же успехом работать и с обычным char (который используется по умолчанию). И тогда вместо std::basic_ifstream<uint8_t> можно написать просто std::ifstream. Я же не знаю требований программы, поэтому демонстрировал возможности. Хотел как лучше, получилось как всегда.

K>ifstream — это от оператора if или от чего? почему лишнее basic_ важнее input и file, что на него аж 5 букв, а на файл инпут по одной в if? Почему basic через сепаратор _, а i и f нет?


Ну, во-первых потому, что было рассчитано, что чаше будет использоваться алиас std::ifstream, а basic_isteream — реже и по мере необходимости. А во-вторых, это просто придирки к именам. Тут на вкус и цвет все фломастеры разные и, наверное, в любом языке можно докопаться до столба. Меня, например, очень раздражают вебрблюжьи горбы в C#, так что теперь — всех расстрелять, потом разогнать?

K>зачем здесь при file_size(path) filesystem, что есть какой-то другой file_size не в файловой системе, а в солнечной?


Ну ты сейчас обсуждаешь мой личный стиль и мои личные предпочтения, а не особенности языка С++. Да, я не вижу никакой трагедии в использовании полно-квалифицированных имен. Но если для кого-то это так важно, пожалуйста — в C++, так же как и в C# есть using директивы. А еще есть и using — объявления и алиасы пространств имен — пожалуйста, делайте себе синтаксический сахар сколько влезет.

K>Все это кошмарная халтура за которую комитет давно пора разогнать.


Да прям уж. Какая, нафиг, разница, что там внутри функции, главное же, чтоб работала правильно. Тебе часто приходится заглядывать внутрь File.ReadAllBytes?

R>>Ну и главное — это пишется один раз, в использовании же это не сложнее, чем File.ReadAllBytes. И даже чуть проще, потому что "File." писать не нужно:


K>Хде оно пишется один раз? Разве что в посте на rsdn и забывается как страшный сон. А в реальной жизни под это дело надо где-то создать хедер, подключить каталог к каждому проекту. Это повезло, что исходника нет, иначе обеспечены танцы с бубном с библиотеками. Ведь поддержки библиотек в с++ нет. Есть только бесконечный зоопарк костылей.

K>В С++ нет такого места где можно написать один раз. Наш добрый гений старуструп еще не в курсе что существуют такие технологии.

А в чем проблемы-то? Всю жизнь писали и пишем общие библиотеки на самых разных уровнях. И при чем тут Страуструп?

K>Да легко. В input.read размер streamsize — знаковый, а vector.size() который туда передается беззнаковый. на 32 бит платформе тип возвращаемый file_size и размер в конструкторе вектора имеют разную размерность. Т.е. данный говнокод может легко рыгнуть уже на целочисленном переполнении, не говоря уже о других проблемах озвученных другими собеседниками выше.


Ну это опять же сугубо мой косяк, который я там дальше по ходу обсуждения и поправил: http://rsdn.org/forum/cpp/8662776.1
Автор: rg45
Дата: 06.01 01:24
.

А с учетом сказанного выше по тексту, можно сделать еще и покомпактнее:

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


Здесь, конечно же, vector.size() беззнаковый, но размер вектора инициализируется по значению, возвращаемому tellg(), которое имеет тип std::streamsize и переполнение невозможно.

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

Что-то еще? Ты там про триллион багов говорил.