python os.read () не читает правильное количество байтов - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь прочитать блоки из двоичного файла (oracle redo log), но у меня возникла проблема, когда при попытке прочитать 512-байтовый блок с помощью os.read (fd, 512) я получаю меньшечем 512 байт. (количество зависит от блока)

документация гласит, что "не более n байт", поэтому имеет смысл получить меньше, чем ожидалось. Как я могу заставить его продолжать читать, пока я не получу правильное количество байтов обратно?

Я попытался адаптировать метод, описанный здесь Python f.read не читает правильное количество байтов Но у меня все еще есть проблема

def read_exactly(fd, size):
    data = b''
    remaining = size
    while remaining:  # or simply "while remaining", if you'd like
        newdata = read(fd, remaining)
        if len(newdata) == 0:  # problem
            raise IOError("Failed to read enough data")
        data += newdata
        remaining -= len(newdata)
    return data


def get_one_block(fd, start, blocksize):
    lseek(fd, start, 0)
    blocksize = blocksize

    print('Blocksize: ' + str(blocksize))
    block = read_exactly(fd, blocksize)
    print('Actual Blocksize: ' + str(block.__sizeof__()))
    return block

, которая затемвозвращает ошибку: OSError: Failed to read enough data

Мой код:

from os import open, close, O_RDONLY, lseek, read, write, O_BINARY, O_CREAT, O_RDWR

def get_one_block(fd, start, blocksize):
    lseek(fd, start, 0)
    blocksize = blocksize

    print('Blocksize: ' + str(blocksize))
    block = read(fd, blocksize)
    print('Actual Blocksize: ' + str(block.__sizeof__()))

    return block

def main():
    filename = "redo_logs/redo03.log"
    fd = open(filename, O_RDONLY, O_BINARY)
    b = get_one_block(fd, 512, 512)

Выход

Blocksize: 512
Actual Blocksize: 502

, в этом случае последний прочитанный байт - 0xB3, за которым следует 0x1A, чтоЯ считаю, что это проблема.

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
EF 42 B8 5A DC D1 63 1B A3 31 C7 5E 9F 4A B7 F4 
4E 04 6B E8 B3<<-- stops here -->>1A 4F 3C BF C9 3C F6 9F C3 08 02 
05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Любая помощь будет принята с благодарностью:)

1 Ответ

0 голосов
/ 06 ноября 2019

Вам нужно прочитать внутри цикла while и проверить истинное количество байтов, которое у вас есть.

Если у вас меньше, вы снова читаете с левой дельтой.

, когда выходкогда вы получили то, что ожидали или достигли EOF.

...