簡體   English   中英

在Python中從同一文件讀取二進制和文本

[英]Reading binary and text from same file in Python

一個人如何從Python的同一文件中讀取二進制和文本? 我知道如何分別執行每個操作,並且可以想象非常仔細地執行這兩個操作,但是不能直接使用內置的IO庫執行這兩個操作。

因此,我有一個文件,該文件的格式具有大塊UTF-8文本,並散布着二進制數據。 文本前沒有寫長度,也沒有特殊字符(例如“ \\ 0”)從二進制數據中划出它,當解析時,有很大一部分文本接近結尾,表示“我們即將結束”。

最佳解決方案是使內置文件讀取類具有“ read(n)”和“ read_char(n)”方法,但可惜它們沒有。 我什至不能打開文件兩次,一次是文本,一次是二進制文件,因為文本上tell()的返回值不能以任何有意義的方式與二進制文件一起使用。

因此,我的第一個想法是將整個文件作為二進制文件打開,當我看到一段文本時,按字符逐個讀取,直到我意識到文本即將結束,然后再以二進制文件形式讀取。 但是,這意味着我必須逐個字節地讀取並自己解碼UTF-8字符(在執行此操作之前,我是否需要為此字符讀取另一個字節?)。 如果是固定寬度的字符編碼,我每次只會讀取那么多字節。 最后,我還希望Python文本閱讀器支持通用行結尾,但是在逐字節讀取時實現起來會更加困難。

另一個更簡單的解決方案是,如果我可以詢問文本文件對象在文件中的實際偏移量。 僅此一項就可以解決我所有的問題。

一種方法是使用Hachoir定義文件解析協議。

一種簡單的替代方法是以二進制模式打開文件,然后手動初始化其周圍的緩沖區和文本包裝器。 然后,您可以整齊地開關二進制文件:

my_file = io.open("myfile.txt", "rb")
my_file_buffer = io.BufferedReader(my_file, buffer_size=1) # Not as performant but a larger buffer will "eat" into the binary data 
my_file_text_reader = io.TextIOWrapper(my_file_buffer, encoding="utf-8")
string_buffer = ""

while True:
    while "near the end" not in string_buffer:
        string_buffer += my_file_text_reader.read(1) # read one Unicode char at a time

    # binary data must be next. Where do we get the binary length from?
    print string_buffer
    data = my_file_buffer.read(3)

    print data
    string_buffer = ""

一種更快,擴展性較小的方法可能是使用您在問題中建議的方法,方法是智能地解析文本部分,一次讀取每個UTF-8字節序列。 以下代碼(來自http://rosettacode.org/wiki/Read_a_file_character_by_character/UTF8#Python ),似乎是從二進制文件保守地將UTF-8字節讀取為字符的一種好方法:

 def get_next_character(f):
     # note: assumes valid utf-8
     c = f.read(1)
     while c:
         while True:
             try:
                 yield c.decode('utf-8')
             except UnicodeDecodeError:
                 # we've encountered a multibyte character
                 # read another byte and try again
                 c += f.read(1)
             else:
                 # c was a valid char, and was yielded, continue
                 c = f.read(1)
                 break

# Usage:
with open("input.txt","rb") as f:
    my_unicode_str = ""
    for c in get_next_character(f):
        my_unicode_str += c

暫無
暫無

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

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