簡體   English   中英

os.read()給出OSError:[Errno 22]讀取大數據時參數無效

[英]os.read() gives OSError: [Errno 22] Invalid argument when reading large data

我使用以下方法從二進制文件中的任何給定偏移量讀取二進制數據。 我擁有的二進制文件很大,為10GB,因此我通常在需要時通過指定應從哪個偏移量start_read以及要讀取的字節數num_to_read讀取它的num_to_read 我使用Python 3.6.4 :: Anaconda, Inc. .平台Darwin-17.6.0-x86_64-i386-64bitos模塊:

def read_from_disk(path, start_read, num_to_read, dim):
    fd = os.open(path, os.O_RDONLY)
    os.lseek(fd, start_read, 0)  # Where to (start_read) from the beginning 0
    raw_data = os.read(fd, num_to_read)  # How many bytes to read
    C = np.frombuffer(raw_data, dtype=np.int64).reshape(-1, dim).astype(np.int8)
    os.close(fd)
    return C

當要讀取的數據塊大約小於2GB時,此方法效果很好。 num_to_read > 2GG ,出現此錯誤:

raw_data = os.read(fd, num_to_read)  # How many to read (num_to_read)
OSError: [Errno 22] Invalid argument

我不確定為什么會出現此問題以及如何解決它。 非常感謝您的幫助。

os.read函數只是平台的read函數的一個瘦包裝。

在某些平台上,這是一個無符號或有符號的32位int, 1表示在這些平台上一次read的最大容量分別為4GB或2GB。

因此,如果您想閱讀更多內容,並且想要跨平台,則必須編寫代碼來處理此問題,並緩沖多個read

這可能會有些麻煩,但是您在這里故意使用最低級別的直接映射到OS-API。 如果您不喜歡這樣:

  • 請改用io模塊對象(Python 3.x)或從open file對象(2.7)。
  • 只需讓NumPy讀取文件即可,這將具有NumPy足夠聰明的優勢,它不會一開始就嘗試將整個內容讀入內存。
  • 或者,對於如此大的文件,您可能需要降低級別並使用mmap (假設您使用的是64位平台)。

在這里要做的正確的事幾乎可以肯定是前兩者的結合。 在Python 3中,它看起來像這樣:

with open(path, 'rb', buffering=0) as f:
    f.seek(start_read)
    count = num_to_read // 8 # how many int64s to read
    return np.fromfile(f, dtype=np.int64, count=count).reshape(-1, dim).astype(np.int8)

1.對於Windows,POSIX仿真庫的_read函數將int用作count參數,該參數是32位帶符號的。 對於每個其他現代平台,請參閱POSIX read ,然后在您的平台上查找size_tssize_toff_t的定義。 請注意,許多POSIX平台具有單獨的64位類型和相應的功能,而不是將現有類型的含義更改為64位。 Python將使用標准類型,而不是特殊的64位類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM