[英]“OSError: [Errno 22] Invalid argument” when read()ing a huge file
[英]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-64bit
和os模塊:
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)。 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_t
, ssize_t
和off_t
的定義。 請注意,許多POSIX平台具有單獨的64位類型和相應的功能,而不是將現有類型的含義更改為64位。 Python將使用標准類型,而不是特殊的64位類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.