偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

想要高效讀寫文件嗎?Python的Mmap()函數(shù)或許可以解決你的問題

開發(fā) 后端
本篇博客將詳細介紹Python中文本文件的追加和截斷、with語句原理、seek和tell方法、內(nèi)存映射文件(mmap)以及大文件分塊讀取等方面的知識點,幫助讀者深入了解Python文件IO操作的實現(xiàn)原理和高級應(yīng)用。

文本文件的追加和截斷

文件追加的概念和應(yīng)用

在某些場景下,我們需要對已有的文件進行修改,常見的方式是打開文件后將新的內(nèi)容寫入,這會覆蓋掉原來的內(nèi)容。但如果想保留原文件的內(nèi)容并在其末尾添加新的內(nèi)容,就需要用到文件追加操作。文件追加是指向一個已存在的文件末尾添加新的內(nèi)容,并且不影響原先的內(nèi)容。

使用 a 模式打開文本文件進行追加操作

Python中使用 open() 函數(shù)打開文件時,可以通過設(shè)置文件模式參數(shù)來指定文件的操作方式。其中,a 模式表示以追加的方式打開文件,即將新的內(nèi)容添加到文件末尾。

with open('file.txt', 'a') as f:
    f.write('Hello, world!\n')

在上述代碼中,我們打開了一個名為 file.txt 的文件,并使用 a 模式將字符串 'Hello, world!\n' 寫入文件末尾。需要注意的是,在使用 a 模式時,如果文件不存在,則會自動創(chuàng)建新文件。

truncate 方法實現(xiàn)文本文件截斷

除了在文件末尾追加新內(nèi)容之外,我們有時還需要對文件進行截斷操作,即只保留文件前幾行或前幾個字符,而舍棄文件中后面的內(nèi)容。Python中提供了 truncate() 方法來實現(xiàn)這一功能。truncate() 方法可以指定文件的長度(以字節(jié)為單位),使文件中多余的部分被刪除掉,從而實現(xiàn)文件截斷。

with open('file.txt', 'r+') as f:
    f.seek(0)           # 將文件指針移到文件開頭位置
    f.truncate(10)      # 截斷文件,保留前10個字符

在上述代碼中,我們首先使用 r+ 模式打開文件,并將文件指針移到文件開頭位置,然后使用 truncate() 方法截斷文件,并指定保留文件前10個字符。需要注意的是,在使用 truncate() 方法時,必須以讀寫模式打開文件,否則會拋出異常。

示例代碼

下面是一個完整的示例代碼,演示了如何使用 a 模式打開文件追加內(nèi)容,并使用 truncate() 方法截斷文件。

def append_and_truncate():
    with open('file.txt', 'a') as f:
        f.write('Hello, world!\n')

    with open('file.txt', 'r+') as f:
        f.seek(0)
        f.truncate(10)

    with open('file.txt', 'r') as f:
        print(f.read())

在上述代碼中,我們首先使用 a 模式打開文件 file.txt 并寫入一行文本,然后再以 r+ 模式打開同一文件進行截斷操作,保留前10個字符。最后,我們以只讀模式打開文件并打印其內(nèi)容,結(jié)果應(yīng)該如下所示:

Hello, worl

with 語句原理

with 語句的作用和優(yōu)勢

with語句是Python提供的一種簡化文件操作的語法結(jié)構(gòu),其作用是在文件使用完后自動關(guān)閉文件,避免了手動關(guān)閉文件時可能出現(xiàn)的錯誤。除了文件操作之外,with語句還可以用于其他資源的管理,例如網(wǎng)絡(luò)連接、數(shù)據(jù)庫連接等。

with open('file.txt', 'r') as f:
    data = f.read()

在上述代碼中,我們使用 with 語句打開文件 file.txt 并讀取其中的內(nèi)容,這樣即使在處理文件過程中出現(xiàn)異常,Python也會自動關(guān)閉文件,避免了文件資源泄露的問題??梢钥吹?,使用 with 語句可以讓代碼更加簡潔和優(yōu)雅。

with 語句原理及其底層實現(xiàn)

with語句的實現(xiàn)原理是基于上下文管理器(context manager)的概念。上下文管理器是一個對象,它定義了進入和退出某個上下文時要執(zhí)行的操作。使用 with 語句時,必須將一個支持上下文管理器協(xié)議的對象傳遞給它,然后 with 語句會在進入和退出上下文時自動調(diào)用該對象的 enter() 和 exit() 方法。

class File:
    def __init__(self, filename):
        self.filename = filename
    
    def __enter__(self):
        print('Enter')
        self.file = open(self.filename, 'r')
        return self.file
    
    def __exit__(self, exc_type, exc_value, traceback):
        print('Exit')
        self.file.close()

with File('file.txt') as f:
    data = f.read()

在上述代碼中,我們定義了一個名為 File 的上下文管理器,并實現(xiàn)了其 enter() 和 exit() 方法。在 with 語句中使用 File 對象時,Python會自動調(diào)用其 enter() 方法打開文件,并在代碼塊執(zhí)行完畢后調(diào)用 exit() 方法關(guān)閉文件。

示例代碼

下面是一個完整的示例代碼,演示了如何使用 with 語句打開文件并讀取其中的內(nèi)容。

class File:
    def __init__(self, filename):
        self.filename = filename
    
    def __enter__(self):
        self.file = open(self.filename, 'r')
        return self.file
    
    def __exit__(self, exc_type, exc_value, traceback):
        self.file.close()

def read_file():
    with File('file.txt') as f:
        data = f.read()
        print(data)

if __name__ == '__main__':
    read_file()

在上述代碼中,我們定義了一個名為 File 的上下文管理器,并在 read_file() 函數(shù)中使用 with 語句打開文件 file.txt 并讀取其中的內(nèi)容,然后自動關(guān)閉文件。需要注意的是,在 with 語句中打開文件時,必須指定文件模式參數(shù),并且不能使用 a 模式進行追加操作。

seek 和 tell 方法

seek 和 tell 方法的作用和區(qū)別

在Python中,文件對象提供了兩個基本方法來控制文件指針的位置:seek() 和 tell()。其中,seek() 方法用于將文件指針移到文件的任意位置,而 tell() 方法則返回當前文件指針的位置。

with open('file.txt', 'r') as f:
    data = f.read(10)   # 讀取前10個字符
    pos = f.tell()      # 獲取當前文件指針位置
    f.seek(0)           # 將文件指針移到文件開頭位置
    data2 = f.read(10)  # 重新讀取前10個字符

print(pos)
print(data2)

在上述代碼中,我們使用 with 語句打開文件 file.txt 并讀取其中的前10個字符,然后獲取當前文件指針的位置,并將文件指針移到文件開頭位置,最后重新讀取前10個字符。需要注意的是,在使用 seek() 方法時,必須以二進制模式打開文件。

文件指針和偏移量的概念和使用方法

文件指針是一個表示當前讀寫位置的指針,它指向文件中下一個要讀取或?qū)懭氲淖止?jié)的位置。在Python中,文件指針的位置可以通過 tell() 方法獲取,并且可以使用 seek() 方法將其設(shè)置為任意位置。seek() 方法接受一個整數(shù)參數(shù),代表相對于文件開頭的偏移量(以字節(jié)為單位),并可指定偏移量的起始位置(0表示文件開頭,1表示當前位置,2表示文件末尾)。

with open('file.txt', 'r') as f:
    f.seek(5)       # 將文件指針移到第6個字符處
    data = f.read() # 從第6個字符開始讀取文件內(nèi)容

在上述代碼中,我們使用 seek() 方法將文件指針移到第6個字符處,然后讀取從該位置開始的文件內(nèi)容。

實現(xiàn)隨機訪問和修改文件內(nèi)容

由于可以通過 seek() 方法將文件指針移到文件的任意位置,因此可以實現(xiàn)隨機訪問文件內(nèi)容。例如,我們可以通過 seek() 方法將文件指針移到某一行的開頭位置,然后讀取該行的內(nèi)容。類似地,我們也可以使用 seek() 和 write() 方法來修改文件的特定位置。

with open('file.txt', 'r+') as f:
    f.seek(5)           # 將文件指針移到第6個字符處
    f.write('WORLD')    # 將字符 WORLD 插入到文件中
    f.seek(0)           # 將文件指針移到文件開頭位置
    data = f.read()     # 重新讀取文件內(nèi)容

print(data)

在上述代碼中,我們使用 r+ 模式打開文件 file.txt,并將文件指針移到第6個字符處,然后使用 write() 方法向文件中插入字符串 'WORLD'。最后,我們再次將文件指針移到文件開頭位置并讀取文件的全部內(nèi)容,輸出結(jié)果應(yīng)該為:

HelloWORLD, how are you?

示例代碼

下面是一個完整的示例代碼,演示了如何使用 seek() 和 tell() 方法實現(xiàn)隨機訪問和修改文件內(nèi)容。

def random_access():
    with open('file.txt', 'r+') as f:
        f.seek(5)
        f.write('WORLD')
        f.seek(0)
        data = f.read()
        print(data)

if __name__ == '__main__':
    random_access()

在上述代碼中,我們首先使用 r+ 模式打開文件 file.txt 并將文件指針移到第6個字符處,然后使用 write() 方法插入字符串 'WORLD'。最后,我們重新將文件指針移到文件開頭位置并讀取文件的全部內(nèi)容,輸出結(jié)果應(yīng)該為:

HelloWORLD, how are you?

內(nèi)存映射文件(mmap)

mmap 的作用和優(yōu)勢

Python中提供了一種特殊的文件操作方式,稱為內(nèi)存映射文件(mmap)。內(nèi)存映射文件是一種將文件內(nèi)容映射到內(nèi)存中的技術(shù),它允許我們通過內(nèi)存來讀寫文件內(nèi)容,從而避免了頻繁訪問磁盤的開銷。同時,內(nèi)存映射文件還可以讓我們像處理數(shù)組一樣高效地對文件進行隨機訪問和修改。在處理大型二進制文件時,內(nèi)存映射文件非常有用。

mmap 原理及其底層實現(xiàn)

在Python中,使用 mmap() 函數(shù)可以將一個文件對象映射到內(nèi)存中,從而生成一個內(nèi)存映射文件對象。內(nèi)存映射文件對象具有文件對象的所有方法,例如 read()、write()、seek() 等,并且也可以像操作數(shù)組一樣進行隨機訪問和修改。

import mmap

with open('file.bin', 'r+b') as f:
    mm = mmap.mmap(f.fileno(), 0)
    
    # 讀取前10個字節(jié)
    data1 = mm[:10]
    print(data1)
    
    # 修改前5個字節(jié)
    mm[:5] = b'Hello'
    
    # 查找字符串
    pos = mm.find(b'world')
    print(pos)
    
    # 替換字符串
    mm[pos:pos+5] = b'WORLD'
    
    # 關(guān)閉內(nèi)存映射文件
    mm.close()

在上述代碼中,我們使用 mmap() 函數(shù)將文件 file.bin 映射到內(nèi)存中,并獲取了一個內(nèi)存映射文件對象 mm。然后,我們可以像處理數(shù)組一樣對內(nèi)存映射文件進行讀寫操作。例如,我們可以使用切片符號 [:] 來讀取文件的前10個字節(jié),使用 find() 方法查找特定字符串的位置,并使用切片符號來替換字符串中的部分內(nèi)容。最后,我們調(diào)用 close() 方法關(guān)閉內(nèi)存映射文件。

注意事項

在使用 mmap() 函數(shù)時,需要注意以下幾點:

  1. 內(nèi)存映射文件只能用于二進制文件的處理,不支持文本模式。
  2. 內(nèi)存映射文件是通過共享內(nèi)存實現(xiàn)的,在修改文件內(nèi)容時需要注意并發(fā)訪問問題,否則可能導(dǎo)致數(shù)據(jù)損壞或進程掛起。
  3. 在某些操作系統(tǒng)上,如果文件長度超過了可用的虛擬內(nèi)存大小,則無法創(chuàng)建內(nèi)存映射文件對象。

由于 Python 的 mmap() 函數(shù)依賴于底層操作系統(tǒng)的 mmap() 系統(tǒng)調(diào)用,因此其行為和性能可能在不同的操作系統(tǒng)上有所不同。在編寫使用 mmap() 函數(shù)的代碼時,通常需要對其進行測試和優(yōu)化,以確保其在特定平臺上的表現(xiàn)符合預(yù)期。

示例代碼

下面是一個完整的示例代碼,演示了如何使用 mmap() 函數(shù)創(chuàng)建內(nèi)存映射文件對象,并對其進行讀寫操作。

import mmap

def memory_map():
    with open('file.bin', 'r+b') as f:
        # 將文件映射到內(nèi)存中
        mm = mmap.mmap(f.fileno(), 0)
        
        # 讀取前10個字節(jié)
        data1 = mm[:10]
        print(data1)
        
        # 修改前5個字節(jié)
        mm[:5] = b'Hello'
        
        # 查找字符串
        pos = mm.find(b'world')
        print(pos)
        
        # 替換字符串
        mm[pos:pos+5] = b'WORLD'
        
        # 關(guān)閉內(nèi)存映射文件
        mm.close()

if __name__ == '__main__':
    memory_map()

在上述代碼中,我們使用 mmap() 函數(shù)將文件 file.bin 映射到內(nèi)存中,并獲取了一個內(nèi)存映射文件對象 mm。然后,我們可以像處理數(shù)組一樣對內(nèi)存映射文件進行讀寫操作。最后,我們調(diào)用 close() 方法關(guān)閉內(nèi)存映射文件。

大文件分塊讀取

當需要處理大型文件時,可能會遇到內(nèi)存不足的問題。為了解決這個問題,我們可以將文件分成多個塊進行讀取和處理。這樣可以避免一次性將整個文件讀入內(nèi)存,從而降低內(nèi)存的使用量。在 Python 中,我們可以使用生成器來實現(xiàn)大文件分塊讀取。

生成器函數(shù)實現(xiàn)大文件分塊讀取

def read_in_chunks(file_obj, chunk_size=1024):
    """生成器函數(shù):分塊讀取文件"""
    while True:
        data = file_obj.read(chunk_size)
        if not data:
            break
        yield data

在上述代碼中,我們定義了一個生成器函數(shù) read_in_chunks(),該函數(shù)接受兩個參數(shù):文件對象和塊大小。在函數(shù)體內(nèi),我們使用 while 循環(huán)從文件中讀取指定大小的數(shù)據(jù)塊,并將其作為生成器對象的返回值。如果讀取完整個文件,則退出循環(huán)并返回最后一塊數(shù)據(jù)。

使用生成器函數(shù)讀取大文件

with open('large_file.txt', 'r') as f:
    for chunk in read_in_chunks(f, chunk_size=1024):
        process_data(chunk)

在上述代碼中,我們使用 with 語句打開文件 large_file.txt,并循環(huán)讀取文件的分塊數(shù)據(jù)。每次循環(huán)迭代時,處理函數(shù) process_data() 將會被調(diào)用,并將當前的數(shù)據(jù)塊作為參數(shù)傳遞進去。這樣,在整個文件讀取完成后,我們可以在 process_data() 函數(shù)內(nèi)部處理所有的數(shù)據(jù)。

注意事項

需要注意以下幾點:

  1. 在使用生成器函數(shù)處理大型文件時,需要根據(jù)實際情況選擇合適的塊大小。如果塊的大小太小,則會增加系統(tǒng)的調(diào)用次數(shù);如果塊的大小太大,則可能會導(dǎo)致內(nèi)存溢出。
  2. 如果在處理文件結(jié)束后沒有顯式地關(guān)閉文件對象,則可能會導(dǎo)致資源泄漏或其他問題。
  3. 在某些操作系統(tǒng)上,如果文件長度超過了可用的虛擬內(nèi)存大小,則可能無法完整讀取文件。

示例代碼

下面是一個完整的示例代碼,演示了如何使用生成器函數(shù)實現(xiàn)大文件分塊讀取。

def read_in_chunks(file_obj, chunk_size=1024):
    """生成器函數(shù):分塊讀取文件"""
    while True:
        data = file_obj.read(chunk_size)
        if not data:
            break
        yield data

def process_data(data):
    """處理函數(shù):輸出數(shù)據(jù)塊的長度"""
    print(len(data))

if __name__ == '__main__':
    with open('large_file.txt', 'r') as f:
        for chunk in read_in_chunks(f, chunk_size=1024):
            process_data(chunk)

在上述代碼中,我們定義了一個生成器函數(shù) read_in_chunks(),用于分塊讀取文件;另外還定義了一個處理函數(shù) process_data(),用于輸出數(shù)據(jù)塊的長度。最后,在主程序中,我們使用 with 語句打開文件 large_file.txt 并循環(huán)讀取文件的分塊數(shù)據(jù),并將其作為參數(shù)傳遞給 process_data() 函數(shù)進行處理。

責任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2010-03-24 12:59:27

無線上網(wǎng)信號

2025-05-06 06:40:16

2019-07-02 13:55:50

蘋果谷歌亞馬遜

2018-05-28 14:38:44

PHPPython應(yīng)用

2015-12-31 10:45:25

云計算風(fēng)險

2018-11-15 19:00:12

人工智能帕金森病醫(yī)學(xué)

2020-08-16 10:58:20

Pandaspython開發(fā)

2024-08-23 09:06:26

2023-09-04 07:54:06

2019-10-15 14:14:26

Linuxshell運維

2022-02-28 19:32:27

I/O磁盤

2022-08-18 09:51:50

Python代碼循環(huán)

2011-10-09 11:08:03

EMCOpenWorld云計算

2016-10-14 09:01:34

2023-12-04 07:09:53

函數(shù)遞歸python

2023-02-28 07:39:18

2020-12-18 07:43:57

csv文件亂碼Python

2014-02-17 06:16:43

產(chǎn)品經(jīng)理思維準備

2021-03-18 18:38:48

邊緣計算云計算數(shù)字化
點贊
收藏

51CTO技術(shù)棧公眾號