Я видел немного довольно уродливого кода для этого, но не так уж много того, что я хотел бы использовать.
универсальная поддержка новых строк работает только для файлов с открытым(), а не StringIO и т. д., и не похоже, что он обрабатывает нетрадиционные символы новой строки. Кроме того, если бы это сработало, это привело бы к появлению строк с добавлением \n, что нежелательно.
struct не выглядит так, как будто она вообще поддерживает чтение строк C произвольной длины, требуя длину как часть формата.
ctypes имеет c_buffer, который может быть создан из байтовой строки и будет возвращать первую строку с нулевым завершением в качестве своего значения. Опять же, для этого необходимо заранее определить, какой объем необходимо прочитать, и при этом не делается различий между строками с нулевым завершением и незавершенными строками. То же самое относится и к c_char_p. Так что, похоже, это не особо помогает, так как вы уже должны знать, что прочитали достаточно строки и должны справиться с разделением буфера.
Обычный способ сделать это в C — прочитать фрагменты в буфер, скопировать и изменить размер буфера, если это необходимо, а затем проверить, содержит ли самый новый прочитанный фрагмент нулевой байт. Если это так, верните все до нулевого байта и либо перевыровняйте буфер, либо, если вам хочется, продолжайте читать и используйте его как кольцевой буфер. (Это работает только в том случае, если вы можете передать избыточные данные, прочитанные обратно вызывающему абоненту, или если ungetc вашей платформы, конечно, позволяет помещать большую часть обратно в файл.)
Нужно ли писать аналогичный код на Python? Я был удивлен, не найдя ничего стандартного в io, ctypes или struct.
Файловые объекты, похоже, не имеют способа обратного перемещения в свой буфер, например ungetc, а также буферизованные потоки ввода-вывода в модуле io.
Мне кажется, что я здесь упускаю очевидное. Я бы предпочел избегать побайтового чтения:
Код: Выделить всё
def readcstr(f):
buf = bytearray()
while True:
b = f.read(1)
if b is None or b == '\0':
return str(buf)
else:
buf.append(b)
Подробнее здесь: https://stackoverflow.com/questions/327 ... rom-a-file
Мобильная версия