2.1Kпросмотров
16 октября 2024 г.
statsScore: 2.3K
Питон, файлы, AWS, ч. 2
Не забываем смывать Изначально я пофиксил код с помощью file.seek(0), ведь по опыту, именно из-за его отсутствия обычно возникают проблемы неконсистентности файла при записи и последующем чтении. Правда, это справедливо в случае, когда записываешь и читаешь через один файловый объект, а в примере выше файл читается разными файловыми объектами (s3 открывает файл самостоятельно и отдельно). Поэтому меня удивило, что такой фикс сработал: ... file.write(data) filename = file.name file.seek(0) s3.upload_file(filename, "some_bucket", "some_path") ... Однако ж, как верно подметил Михаил в комментах, более прямолинейная причина была в не вызванном file.flush(). Почему file.seek(0) из моего исправления также фиксит проблему — непонятно. Возможно, он неявным образом продуцирует flush со стороны ОС, но это выше моих познаний питона и линукса, и полагаться на такой «артефакт» точно не стоит. Конечно же, предыдущий пост задумывался исключительно ради тупого каламбура в заголовке поста: «Не забываем посикать». Но так как мой изначальный фикс с вызовом file.seek(0) после записи оказался хоть и рабочим, но неточным, — заголовок пришлось изменить 🥲. Впрочем, трудно переоценить символизм трансформации заголовка из «Не забываем посикать» в «Не забываем смывать» 🤪. База
Всё дело в том, что когда питон пишет в файл, запись проходит несколько буферов-прослоек, часть из которых находится вне его контроля (например, буфер операционки). Поэтому, перед тем, как читать этот файл из другого места, нужно сделать .flush(), чтобы данные из буфера были записаны («смыты») на диск и могли быть целостно прочитаны другим куском кода или процессом (в данном случае, библиотекой AWS).