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

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

Изменено 07.01.2024 17:26 rg45

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

K>Здравствуйте, rg45, Вы писали:


R>>Здравствуйте, 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>>>Нечитаемая мелкобуква


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 — реже и по мере необходимости. А во-вторых, это просто придирки к именам. Тут на вкус и цвет все фломастеры разные и, наверное, в любом языке можно докопаться до столба. Ну и главное, повторюсь, это все написано в реализации функции, а не в использовании. Тебе часто приходится заглядывать в реализацию File.GetAllBytes?

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


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

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


Да прям уж. Это все кошмарные эмоции.

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 и переполнение невозможно.

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

K>Здравствуйте, rg45, Вы писали:


R>>Здравствуйте, 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>>>Нечитаемая мелкобуква


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 — реже и по мере необходимости. А во-вторых, это просто придирки к именам. Тут на вкус и цвет все фломастеры разные и, наверное, в любом языке можно докопаться до столба. Ну и главное, повторюсь, это все написано в реализации функции, а не в использовании. Тебе часто приходится заглядывать в реализацию File.GetAllBytes?

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


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

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


Да прям уж. Это все кошмарные эмоции.

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 и переполнение невозможно.

Ну, один косяк исправили. Что-то еще? Ты там про триллион говорил.