鐵樂學Python_day08_文件操作

来源:https://www.cnblogs.com/tielemao/archive/2018/04/02/8698478.html
-Advertisement-
Play Games

【基本的文件操作】 參數: 1、文件路徑; 2、編碼方式; 3、執行動作;(打開方式)只讀,只寫,追加,讀寫,寫讀! ...


一、【基本的文件操作】

參數:
1、文件路徑;
2、編碼方式;
3、執行動作;(打開方式)只讀,只寫,追加,讀寫,寫讀!

#1. 打開文件,得到文件句柄並賦值給一個變數
f = open('E:/Python/file/文件操作測試.txt', encoding='utf-8', mode='r')
content = f.read()
print(content)
f.close()

E:\Python\venv\Scripts\python.exe E:/Python/day08/文件操作.py
文件操作測試讀取,2018-3-27
read

f:變數,f_obj,file,f_handler,...文件句柄。
open --- windows的系統功能,
windows預設編碼方式:gbk,
linux預設編碼方式:utf-8。
f.close() --- 關閉文件(保存退出)

流程:
1、打開一個文件,產生一個文件句柄,
2、通過句柄對文件進行操作,
3、關閉文件。

二、【關閉文件的註意事項】

打開一個文件包含兩部分資源:操作系統級打開的文件+應用程式的變數。
在操作完畢一個文件時,必須把與該文件的這兩部分資源一個不落地回收,回收方法為:
1、f.close() #回收操作系統級打開的文件
2、del f #回收應用程式級的變數

其中del f一定要發生在f.close()之後,
否則就會導致操作系統打開的文件還沒有關閉,白白占用資源,
python自動的垃圾回收機制決定了無需考慮del f,在操作完畢文件後,記住f.close()就可以了。

推薦傻瓜式操作方式:使用with關鍵字來幫我們管理上下文的同時自動關閉文件。

【with】
功能一:自動關閉文件句柄
功能二:一次性操作多個文件句柄

例:

with open('a.txt', encoding='utf-8', 'w') as f:
    pass

with open('a.txt', encondig='utf-8', 'w') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)

三、【文件的打開模式】

文件句柄 = open(‘文件路徑’,‘模式’)

1、文件以什麼編碼方式存儲的,就以什麼編碼方式打開;
2、文件路徑:
絕對路徑:從根目錄開始
相對路徑:從打開軟體所在的路徑開始(比如pycharm就是在pycharm的工作目錄起)

1. 打開文件的模式有(預設為文本模式):

r, 只讀模式【預設模式,文件必須存在,不存在則拋出異常】
w, 只寫模式【不可讀;文件不存在則創建文件;存在則清空內容】
a, 只追加寫模式【不可讀;文件不存在則創建;存在則只追加內容】

2. 對於非文本文件,(例如圖片)可以使用b模式,"b"表示以位元組的方式操作(而所有文件也都是以位元組的形式存儲的,使用這種模式無需考慮文本文件的字元編碼、圖片文件的jgp格式、視頻文件的avi格式)

rb
wb
ab
具體同上,只是後面加了個b表示是b模式。
註:以b方式打開時,讀取到的內容是位元組類型,寫入時也需要提供位元組類型,不能指定編碼。

3,‘+’模式(就是增加了一個功能)

r+, 讀寫【可讀,可寫】
w+, 寫讀【可寫,可讀】
a+, 追加方式的寫讀【可寫,可讀】

4,以bytes類型操作的讀寫,寫讀,寫讀模式

r+b, 讀寫【可讀,可寫】
w+b, 寫讀【可寫,可讀】
a+b, 追加寫讀【可寫,可讀】

四、【文件操作方式】

【讀模式操作方式】
read()
全部一次性讀取(有缺點:要是一次性讀取超大文件會爆記憶體,例如linux上的日誌文件。)

readline()
每次讀取一行(並且文件內游標隨之移動到第二行頭部)

readlines()
將原文件的每一行作為一個元素放在列表當中(包括\n換行符)可加.strip去掉換行符

read(n)
在r模式下,按字元去讀取n個字元
在rb模式下,按位元組去讀取n個位元組

適合讀取超大文件的方法:
迴圈讀取,全部能讀取出來而且在記憶體當中永遠只占一行。
因為每次都是讀取一行清除一行的記憶體在去讀取下一行。

例:迴圈讀取。

# f = open('log',encoding='utf-8')
# for i in f:
#     print(i.strip())
# f.close()

【游標】
文件內游標移動都是以位元組為單位的如:seek,tell,truncate
f.tell() # 按位元組去讀取游標位置
f.seek() # 按位元組調整游標位置

file.seek()方法格式:
seek(offset,whence=0)
移動文件讀取指針(移動游標)到指定位置。

offset:開始的偏移量,也就是代表需要移動偏移的位元組數。

whence(移動模式): 給offset參數一個定義,表示要從哪個位置開始偏移;
0代表從文件開頭算起,
1代表開始從當前位置開始算起,
2代表從文件末尾開始算起。當有換行時,會被換行截斷。

seek的三種移動方式0,1,2,其中1和2必須在b模式下進行,但無論哪種模式,都是以bytes為單位移動的。
seek()無返回值,故值為None

file.truncate():
truncate(),對文字內容進行截取。
truncate是截斷文件,所以文件的打開方式必須可寫,但是不能用w或w+等方式打開,
因為那樣直接清空文件了,所以truncate要在r+或a或a+等模式下測試效果。

【官方源碼參考】

class file(object)
    def close(self): # real signature unknown; restored from __doc__
        關閉文件
        """
        close() -> None or (perhaps) an integer.  Close the file.

        Sets data attribute .closed to True.  A closed file cannot be used for
        further I/O operations.  close() may be called more than once without
        error.  Some kinds of file objects (for example, opened by popen())
        may return an exit status upon closing.
        """

    def fileno(self): # real signature unknown; restored from __doc__
        文件描述符  
         """
        fileno() -> integer "file descriptor".

        This is needed for lower-level file interfaces, such os.read().
        """
        return 0    

    def flush(self): # real signature unknown; restored from __doc__
        刷新文件內部緩衝區(類似於文件-保存的效果)
        """ flush() -> None.  Flush the internal I/O buffer. """
        pass

    def isatty(self): # real signature unknown; restored from __doc__
        判斷文件是否是同意tty設備
        """ isatty() -> true or false.  True if the file is connected to a tty device. """
        return False

    def next(self): # real signature unknown; restored from __doc__
        獲取下一行數據,不存在,則報錯
        """ x.next() -> the next value, or raise StopIteration """
        pass

    def read(self, size=None): # real signature unknown; restored from __doc__
        讀取指定位元組數據
        """
        read([size]) -> read at most size bytes, returned as a string.

        If the size argument is negative or omitted, read until EOF is reached.
        Notice that when in non-blocking mode, less data than what was requested
        may be returned, even if no size parameter was given.
        """
        pass

    def readinto(self): # real signature unknown; restored from __doc__
        讀取到緩衝區,不要用,將被遺棄
        """ readinto() -> Undocumented.  Don't use this; it may go away. """
        pass

    def readline(self, size=None): # real signature unknown; restored from __doc__
        僅讀取一行數據
        """
        readline([size]) -> next line from the file, as a string.

        Retain newline.  A non-negative size argument limits the maximum
        number of bytes to return (an incomplete line may be returned then).
        Return an empty string at EOF.
        """
        pass

    def readlines(self, size=None): # real signature unknown; restored from __doc__
        讀取所有數據,並根據換行保存值到列表
        """
        readlines([size]) -> list of strings, each a line from the file.

        Call readline() repeatedly and return a list of the lines so read.
        The optional size argument, if given, is an approximate bound on the
        total number of bytes in the lines returned.
        """
        return []

    def seek(self, offset, whence=None): # real signature unknown; restored from __doc__
        指定文件中指針位置
        """
        seek(offset[, whence]) -> None.  Move to new file position.

        Argument offset is a byte count.  Optional argument whence defaults to
(offset from start of file, offset should be >= 0); other values are 1
        (move relative to current position, positive or negative), and 2 (move
        relative to end of file, usually negative, although many platforms allow
        seeking beyond the end of a file).  If the file is opened in text mode,
        only offsets returned by tell() are legal.  Use of other offsets causes
        undefined behavior.
        Note that not all file objects are seekable.
        """
        pass

    def tell(self): # real signature unknown; restored from __doc__
        獲取當前指針位置
        """ tell() -> current file position, an integer (may be a long integer). """
        pass

    def truncate(self, size=None): # real signature unknown; restored from __doc__
        截斷數據,僅保留指定之前數據
        """
        truncate([size]) -> None.  Truncate the file to at most size bytes.

        Size defaults to the current file position, as returned by tell().
        """
        pass

    def write(self, p_str): # real signature unknown; restored from __doc__
        寫內容
        """
        write(str) -> None.  Write string str to file.

        Note that due to buffering, flush() or close() may be needed before
        the file on disk reflects the data written.
        """
        pass

    def writelines(self, sequence_of_strings): # real signature unknown; restored from __doc__
        將一個字元串列表寫入文件
        """
        writelines(sequence_of_strings) -> None.  Write the strings to the file.

        Note that newlines are not added.  The sequence can be any iterable object
        producing strings. This is equivalent to calling write() for each string.
        """
        pass

    def xreadlines(self): # real signature unknown; restored from __doc__
        可用於逐行讀取文件,非全部
        """
        xreadlines() -> returns self.

        For backward compatibility. File objects now include the performance
        optimizations previously implemented in the xreadlines module.
        """
        pass

五、【文件的修改】

文件的數據是存放於硬碟上的,因而實際上底層只存在覆蓋、不存在修改這麼一說,
我們平時看到的修改編輯文件,都是模擬出來的效果,具體的說有兩種實現方式:

方式一:將硬碟存放的該文件的內容全部載入到記憶體,在記憶體中是可以修改的,修改完畢後,再由記憶體覆蓋到硬碟(word,vim,nodpad++等編輯器)

---------------------------
import os  # 調用系統模塊

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #全部讀入記憶體,如果文件很大,會很卡
    data=data.replace('old','new') #在記憶體中完成修改,將舊內容替換成新內容

    write_f.write(data) #一次性寫入新文件

os.remove('a.txt')  #刪除原文件
# 因為不刪除將建立不了同名的文件,其實我感覺上先將原文件改名再讓新文件命名成原文件名後確認無誤後再刪除原文件更安全保險。
os.rename('.a.txt.swap','a.txt')   #將新建的文件重命名為原文件
-----------------------------

方式二:將硬碟存放的該文件的內容一行一行地讀入記憶體,修改完畢就寫入新文件,最後用新文件覆蓋源文件。

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('old','new')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 

簡述為以下流程:
1、將源文件讀取到記憶體;
2、在記憶體中時行修改,形成新的字元串(文件);
3、將新的字元串寫入新文件;
3、將原文件刪除;
4、將新文件重命名為原文件。

例:有如下文件:
-------
alex是老男孩python發起人,創建人。
alex其實是人妖。
誰說alex是sb?
你們真逗,alex再牛逼,也掩飾不住資深屌絲的氣質。
----------
將文件中所有的alex都替換成大寫的SB。

答:

with open('log',encoding='utf-8') as f1,\
    open('log.bak',encoding='utf-8',mode='w') as f2:
    content = f1.read()
    new_content = content.replace('alex','SB')
    f2.write(new_content)
os.remove('log')
os.rename('log.bak','log')

import os
with open('log',encoding='utf-8') as f1,\
    open('log.bak',encoding='utf-8',mode='w') as f2:
    for i in f1:
        new_i = i.replace('SB','alex')
        f2.write(new_i)
os.remove('log')
os.rename('log.bak','log')

end
2018-4-2


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 個人總結:望對屏幕對面的您有所幫助 一. 線程概述 進程: 有獨立的記憶體控制項和系統資源 應用程式的執行實例 啟動當前電腦任務管理器:taskmgr 進程是程式(任務)的執行過程,它持有資源(共用記憶體,共用文件)和線程。 線程: 進程中執行運算的最小的單位,可完成一個獨立的順序控制流程(執行路徑) C ...
  • 從標準輸入中讀取數據 1.if語句條件兩邊也不加括弧,但是主體部分需要加{} 2.map存儲了鍵/值(key/value)的集合,對集合元素,提供常數時間的存、取操作,map[string]int ==> key的類型string和value的類型int 3.內置函數make創建空map, coun ...
  • java基礎--程式流程式控制制 【目錄】 一. 順序結構(巨集觀上) 二. 分支結構/選擇結構(if,switch) 2.1 if語句 2.2 switch語句 三. 迴圈結構 3.1 for迴圈 3.2 while迴圈 其他。。。。。。。 一些關鍵瞭解內容 for迴圈中,for( )括弧里定義的變數, ...
  • 嚴重: A child container failed during startjava.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [S ...
  • 學習目的: 掌握爬蟲相關的基本概念 正式步驟 Step1:什麼是爬蟲 請求網站並提取數據的自動化程式 Step2:爬蟲的基本流程 Step3:Request和Response 1.request 2.response Step4:能抓怎樣的數據 Step5:怎麼樣來解析 Step6:怎樣保存數據 學 ...
  • HTML 1、一套規則,瀏覽器認識的規則。 2、開發者: 學習Html規則 開發後臺程式: - 寫Html文件(充當模板的作用) ****** - 資料庫獲取數據,然後替換到html文件的指定位置(Web框架) 3、本地測試 - 找到文件路徑,直接瀏覽器打開 - pycharm打開測試 4、編寫Ht ...
  • 本文主要介紹iReport軟體生成報表模板使用Jasper進行數據填充並生成pdf文檔的實現過程。 ...
  • 練習題 python 1、整理函數相關知識點,寫博客 2、寫函數,檢查獲取傳入列表或元組對象的所有奇數位索引對應的元素, 並將其作為新列表返回給調用者。 def odd_index(l): lis = [] for i in range(len(l)): 通過range設定索引範圍比通過元素找索引要 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...