1. 程式人生 > >Python學習—文件操作

Python學習—文件操作

like import false 不能 pfile 返回 unicode 支持 zip

1.文件基礎知識

1.文件是存儲在外部介質上的數據的集合,文件的基本單位是字節,文件所含的字節數就是文件的長度。每個字節都有一個默認的位置,位置從0開始,文件頭的位置就是0,文件尾的位置是文件內容結束後的後一個位置,該位置上沒有文件內容,為空。文件的讀寫操作從文件指針所在的位置開始,即讀會從文件指針所在的位置開始讀取,寫會從文件指針所在的位置開始寫,如有內容,則會被覆蓋。
2.按文件中數據的組織形式把文件分為文本文件和二進制文件兩類。文本文件存儲的是常規字符串,由文本行組成,通常以換行符‘\n‘結尾,只能讀寫常規字符串。文本文件可以用字處理軟件如gedit、記事本等進行查看編輯。常規字符串是指文本編輯器能正常顯示、編輯的字符串,如英文字母串、漢字串、數字串。二進制文件

把對象在內存中的內容以字節串(bytes)的形式進行存儲。不能用字處理軟件進行編輯。

2.文件的打開或創建

格式:文件變量名 = open(文件名[,打開方式[,緩沖區]])

文件名指定被打開文件對象
打開方式指定文件打開後能進行的處理方式
緩沖區制定了讀寫文件的緩存模式。0表示不緩存,1表示緩存,如大余1則表示緩沖區的大小。默認值為1
open()函數返回一個文件對象,通過該對象可以對文件進行各種操作

1.普通文本文件

r:
    - 只能讀,不能寫
    - 讀取的文件不存在, 報錯 
    - 報錯信息:FileNotFoundError: [Errno 2] No such file or directory:xxxxxx
r+:
    - 可以執行讀寫操作
    - 文件不存在,報錯
    - 默認情況下,從文件指針所在位置開始寫入

w:
    - 只能寫,不能讀
    - 文件不存在,不報錯,自動創建文件並打開
    - 會清空文件內容
w+:
    - 可以執行讀寫操作
    - 文件不存在,不報錯,自動創建文件並打開
    - 會清空文件內容

a:
    - 只能寫,不能讀
    - 文件不存在,不報錯,自動創建文件並打開
    - 不會清空文件內容
a+:
    - 可以執行讀寫操作
    - 文件不存在,不報錯,自動創建文件並打開
    - 不會清空文件內容

2.二進制文件:打開方式在普通文本文件上加‘b‘

rb:
    - 只能讀,不能寫
    - 讀取的文件不存在,報錯
rb+:
    - 可以執行讀寫操作
    - 文件不存在,報錯
    - 默認情況下,從文件指針所在位置開始寫入

wb:
    - 只能寫,不能讀
    - 文件不存在,不報錯,自動創建文件並打開
    - 會清空文件內容
wb+:
    - 可以執行讀寫操作
    - 文件不存在,不報錯,自動創建文件並打開
    - 會清空文件內容

ab:
    - 只能寫,不能讀
    - 文件不存在,不報錯,自動創建文件並打開
    - 不會清空文件內容
ab+:
    - 可以執行讀寫操作
    - 文件不存在,不報錯,自動創建文件並打開
    - 不會清空文件內容

3.文件常用方法

一、讀
f.next()    #在文件使用叠代器時會使用到,在循環中,next()方法會在每次循環中調用,該方法返回文件的下一行,如果到達結尾(EOF),則觸發 StopIteration
f.read([size])    #方法用於從文件讀取指定的字節數,如果未給定或為負則讀取所有。
f.readline([size])    #從文件讀取整行,包括 "\n" 字符。如果指定了一個非負數的參數,則返回指定大小的字節數,包括 "\n" 字符。
f.readlines([size])    #讀取所有行(直到結束符 EOF)並返回列表,該列表可以由 Python 的 for... in ... 結構進行處理。如果碰到結束符 EOF 則返回空字符串。,若給定sizeint>0,則是設置一次讀多少字節,這是為了減輕讀取壓力

二、寫
f.write([str])    #用於向文件中寫入指定字符串
f.writelines(sequence_of_strings)    #向文件中寫入一序列的字符串

三、其他操作
f.flush()    #用來刷新緩沖區的,即將緩沖區中的數據立刻寫入文件,同時清空緩沖區,不需要是被動的等待輸出緩沖區寫入  
f.seek(offset[, whence])    #於移動文件讀取指針到指定位置
       offset -- 開始的偏移量,也就是代表需要移動偏移的字節數
       whence -- 可選,默認值為 0。給offset參數一個定義,表示要從哪個位置開始偏移;0代表從文件開頭開始算起,1代表從當前位開始算起,2代表從文件末尾算起。 
f.tell()    #返回文件指針當前位置
f.truncate([ size ])    #截斷文件,如果指定了可選參數 size,則表示截斷文件為 size 個字符。 如果沒有指定 size,則從當前位置起截斷;截斷之後 size 後面的所有字符被刪除。
f.close()    #用於關閉一個已打開的文件          
f.closed    #返回true如果文件已被關閉,否則返回false。
f.fileno()    #方法返回一個整型的文件描述符(file descriptor FD 整型),可用於底層操作系統的 I/O 操作。
f.isatty()    #檢測文件是否連接到一個終端設備,如果是返回 True,否則返回 False

四、以下兩個屬性在python2中有,在python3中已經被刪除了
f.mode    #返回被打開文件的訪問模式。
f.name    # 返回文件的名稱。

4.安全上下文with

上下文管理器:打開文件, 執行完with語句內容之後, 自動關閉文件對象

 with open(‘/tmp/passwd‘) as f:
     print("with語句裏面:", f.closed)
     print(f.read())
 print("after with語句:", f.closed)

同時打開兩個文件對象( python2中不支持)

with    open(‘/tmp/passwd‘) as f1, open(‘/tmp/passwdBack‘, ‘w+‘) as f2:
    # 將第一個文件的內容寫入第二個文件中,文件復制即使如此。
    f2.write(f1.read())
    # 移動指針移動到文件最開始
    f2.seek(0,0)
    # 讀取指針內容
    print(f2.read())

python2中只能這麽實現

with open(‘/tmp/passwd‘) as f1:
    content = f1.read()
with open(‘/tmp/passwdBack‘, ‘w+‘):
    f2.write(content)

5.yield實現讀取大文件

# 1. 文件操作
   1). 創建文件data.txt, 文件共100000行, 每行存放一個1~100之間的整數.
   2). 找出文件中數字出現次數最多的10個數字, 寫入文件mostNum.txt;
 import random
 with open(‘data.txt‘, mode=‘a+‘) as f:
     for i in range(1000000):
         f.write(str(random.randint(1,100))+‘\n‘)

# 通過yield, 每次讀取一行進行處理
 def byLineReader(filename):
     with open(filename) as f:
         line = f.readline()
         # 如果可以讀取到內容, 返回該行信息
         while line:
             yield  line
             line = f.readline()

# read是一個生成器對象,
 read = byLineReader(‘data.txt‘)
 print(read)

# #1). next 讀取生成器的內容
 print(next(read))
 print(next(read))
 ...

# #2). 通過for循環
 for item in read:
     print(item)

# ******** 文件對象是可以for循環遍歷的, 默認遍歷的內容為每一行的內容.是節省內存空間的。
from collections import Iterable

f = open(‘data.txt‘)
print(isinstance(f, Iterable))
for i, item in enumerate(f):
    if i == 10:
        break
    print(i, item)

6.os模塊

os 模塊提供了非常豐富的方法用來處理文件和目錄。

import os
# 1). 返回操作系統類型, 值為posix,是Linux操作系統, 值為nt, 是windows操作系統
print(os.name)
print(‘Linux‘ if os.name==‘posix‘ else ‘Windows‘)

# 2). 操作系統的詳細信息
info = os.uname()
print(info)
print(info.sysname)
print(info.nodename)

# 3). 系統環境變量
print(os.environ)

# 4). 通過key值獲取環境變量對應的value值
print(os.environ.get(‘PATH‘))
print(os.getenv(‘PATH‘))

遍歷指定目錄下所有內容

import os
from os.path import join

for root, dirs, files in os.walk(‘/var/log‘):
    #print(root, dirs, files)
    for name in files:
        print(join(root, name))

os模塊常用方法大全:

os.access(path, mode)
檢驗權限模式

os.chdir(path)
改變當前工作目錄

os.chflags(path, flags)
設置路徑的標記為數字標記。

os.chmod(path, mode)
更改權限

os.chown(path, uid, gid)
更改文件所有者

os.chroot(path)
改變當前進程的根目錄

os.close(fd)
關閉文件描述符 fd

os.closerange(fd_low, fd_high)
關閉所有文件描述符,從 fd_low (包含) 到 fd_high (不包含), 錯誤會忽略

os.dup(fd)
復制文件描述符 fd

os.dup2(fd, fd2)
將一個文件描述符 fd 復制到另一個 fd2

os.fchdir(fd)
通過文件描述符改變當前工作目錄

os.fchmod(fd, mode)
改變一個文件的訪問權限,該文件由參數fd指定,參數mode是Unix下的文件訪問權限。

os.fchown(fd, uid, gid)
修改一個文件的所有權,這個函數修改一個文件的用戶ID和用戶組ID,該文件由文件描述符fd指定。

os.fdatasync(fd)
強制將文件寫入磁盤,該文件由文件描述符fd指定,但是不強制更新文件的狀態信息。

os.fdopen(fd[, mode[, bufsize]])
通過文件描述符 fd 創建一個文件對象,並返回這個文件對象

os.fpathconf(fd, name)
返回一個打開的文件的系統配置信息。name為檢索的系統配置的值,它也許是一個定義系統值的字符串,這些名字在很多標準中指定(POSIX.1, Unix 95, Unix 98, 和其它)。

os.fstat(fd)
返回文件描述符fd的狀態,像stat()。

os.fstatvfs(fd)
返回包含文件描述符fd的文件的文件系統的信息,像 statvfs()

os.fsync(fd)
強制將文件描述符為fd的文件寫入硬盤。

os.ftruncate(fd, length)
裁剪文件描述符fd對應的文件, 所以它最大不能超過文件大小。

os.getcwd()
返回當前工作目錄

os.getcwdu()
返回一個當前工作目錄的Unicode對象

os.isatty(fd)
如果文件描述符fd是打開的,同時與tty(-like)設備相連,則返回true, 否則False。

os.lchflags(path, flags)
設置路徑的標記為數字標記,類似 chflags(),但是沒有軟鏈接

os.lchmod(path, mode)
修改連接文件權限

os.lchown(path, uid, gid)
更改文件所有者,類似 chown,但是不追蹤鏈接。

os.link(src, dst)
創建硬鏈接,名為參數 dst,指向參數 src

os.listdir(path)
返回path指定的文件夾包含的文件或文件夾的名字的列表。

os.lseek(fd, pos, how)
設置文件描述符 fd當前位置為pos, how方式修改: SEEK_SET 或者 0 設置從文件開始的計算的pos; SEEK_CUR或者 1 則從當前位置計算; os.SEEK_END或者2則從文件尾部開始. 在unix,Windows中有效

os.lstat(path)
像stat(),但是沒有軟鏈接

os.major(device)
從原始的設備號中提取設備major號碼 (使用stat中的st_dev或者st_rdev field)。

os.makedev(major, minor)
以major和minor設備號組成一個原始設備號

os.makedirs(path[, mode])
遞歸文件夾創建函數。像mkdir(), 但創建的所有intermediate-level文件夾需要包含子文件夾。

os.minor(device)
從原始的設備號中提取設備minor號碼 (使用stat中的st_dev或者st_rdev field )。

os.mkdir(path[, mode])
以數字mode的mode創建一個名為path的文件夾.默認的 mode 是 0777 (八進制)。

os.mkfifo(path[, mode])
創建命名管道,mode 為數字,默認為 0666 (八進制)

os.mknod(filename[, mode=0600, device])
創建一個名為filename文件系統節點(文件,設備特別文件或者命名pipe)。

os.open(file, flags[, mode])
打開一個文件,並且設置需要的打開選項,mode參數是可選的

os.openpty()
打開一個新的偽終端對。返回 pty 和 tty的文件描述符。

os.pathconf(path, name)
返回相關文件的系統配置信息。

os.pipe()
創建一個管道. 返回一對文件描述符(r, w) 分別為讀和寫

os.popen(command[, mode[, bufsize]])
從一個 command 打開一個管道

os.read(fd, n)
從文件描述符 fd 中讀取最多 n 個字節,返回包含讀取字節的字符串,文件描述符 fd對應文件已達到結尾, 返回一個空字符串。

os.readlink(path)
返回軟鏈接所指向的文件

os.remove(path)
刪除路徑為path的文件。如果path 是一個文件夾,將拋出OSError; 查看下面的rmdir()刪除一個 directory。

os.removedirs(path)
遞歸刪除目錄。

os.rename(src, dst)
重命名文件或目錄,從 src 到 dst

os.renames(old, new)
遞歸地對目錄進行更名,也可以對文件進行更名。

os.rmdir(path)
刪除path指定的空目錄,如果目錄非空,則拋出一個OSError異常。

os.stat(path)
獲取path指定的路徑的信息,功能等同於C API中的stat()系統調用。

os.stat_float_times([newvalue])
決定stat_result是否以float對象顯示時間戳

os.statvfs(path)
獲取指定路徑的文件系統統計信息

os.symlink(src, dst)
創建一個軟鏈接

os.tcgetpgrp(fd)
返回與終端fd(一個由os.open()返回的打開的文件描述符)關聯的進程組

os.tcsetpgrp(fd, pg)
設置與終端fd(一個由os.open()返回的打開的文件描述符)關聯的進程組為pg。

os.tempnam([dir[, prefix]])
Python3 中已刪除。返回唯一的路徑名用於創建臨時文件。

os.tmpfile()
Python3 中已刪除。返回一個打開的模式為(w+b)的文件對象 .這文件對象沒有文件夾入口,沒有文件描述符,將會自動刪除。

os.tmpnam()
Python3 中已刪除。為創建一個臨時文件返回一個唯一的路徑

os.ttyname(fd)
返回一個字符串,它表示與文件描述符fd 關聯的終端設備。如果fd 沒有與終端設備關聯,則引發一個異常。

os.unlink(path)
刪除文件路徑

os.utime(path, times)
返回指定的path文件的訪問和修改的時間。

os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
輸出在文件夾中的文件名。通過在樹中遊走,向上或者向下。

os.write(fd, str)
寫入字符串到文件描述符 fd中. 返回實際寫入的字符串長度

來自:http://www.runoob.com/python3/python3-os-file-methods.html

8.sys模塊

import  sys
# 返回一個列表, 第一個元素為當前文件名
print(sys.argv)
print(sys.argv[0])
# 如果獲取腳本傳入的第n個參數, sys.argv[n]

批量更改文件名

# 創建目錄img,在此目錄下隨機生成100個以.png結尾的文件,然後把以.png結尾的文件改成以.jpg結尾
import os,random,string,sys

# 創建目錄並隨機生成.png文件
os.mkdir(‘img‘)
for i in range(100):
    os.mknod(‘img/‘+‘‘.join(random.sample(string.ascii_letters+string.digits,4))+‘.png‘)

def modify_suffix(dirname,old_suffix,new_suffix):
    if not os.path.exists(dirname):
        print(‘目錄不存在!‘)
        exit()
    old_suffix_file_list = list(filter(lambda x:x.endswith(old_suffix),os.listdir(dirname)))

    #字符串方法:
    #new_suffix_file_list = []
    # for i in old_suffix_file_list:
    #     new_suffix_file_list.append(i.replace(old_suffix,new_suffix))
    # print(new_suffix_file_list)
    # for i,j in zip(old_suffix_file_list,new_suffix_file_list):
    #     print(dirname+i,dirname+j)
    #     os.rename(dirname+‘/‘+i,dirname+‘/‘+j)

    #文件操作方法:
    file_name = [os.path.splitext(name)[0] for name in old_suffix_file_list]
    for i in file_name:
        os.rename(dirname+‘/‘+i+old_suffix,dirname+‘/‘+i+new_suffix)
modify_suffix(‘img‘,‘.png‘,‘.jpg‘)

Python學習—文件操作