文件操作

文件操作

馮諾依曼體系架構

CPU由運算器和控制器組成

運算器,完成各種算數的運算,邏輯運算,數據傳輸等數據加工處理

控制器,控制程序的執行

存儲器,用于記憶程序的數據,列如內存

輸入設備,將數據或者程序輸入到計算機中列如鍵盤 鼠標

輸出設備,將數據或者程序的處理結果展示給用戶,列如顯示器,打印機等等

?

一般說的IO操作,指的是文件的IO,如果是指網絡的IO都會直接說網絡IO

文件的IO常操作

open—-打開 ??read—-讀取 ???寫入—-write ?close—–關閉

readline—行讀取 ??readlines—-多行讀取 ??seek—-文件指針操作 ??tell—指針位置

打開操作

open(file,mode=’r’,buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)

打開一個文件,返回一個文件對象和文件的描述符。打開文件失敗,則返回異常

基本使用:

創建一個文件test,然后打開它,用完關閉

f = open(‘test’)
print(f.read())
f.close()

文件操作中,最常用的操作就是讀寫

文件的訪問操作的模式有兩種:文本模式和二進制模式。不同的模式下,函數的操作不盡相同。表現結果也不一樣

open的參數

file 打開或者要創建的文件名,如果指定路徑。默認是當前路徑

Mode模式

r 缺省的,表示只讀打開

w ??只寫打開

x 創建并寫入一個新的文件

a 寫入打開,如果文件存在,則追加

b 二進制模式
t 缺省的文本模式

+ 讀寫打開一個文件,給原來只讀只寫方式打開提供缺失的讀或者寫的能力

練習:

#r模式
f = open(‘test’,’r+’)
f.read()
f.write(‘abc’)
f.close()
print(f)

?

f = open(‘test’,’w+’)
f.read()
f.write(‘123’)
f.close()

open默認是只讀模式r打開已經存在的文件

R

只讀打開文件,則用write方法會拋異常

如果文件不存在,拋出FileNotFoundError異常

?

W

如果只寫方式打開,如果讀則拋出異常

如果文件不存在,則直接創建文件

如果文件存在,則清空文件內容

f = open(‘test1′,’x’)
f.write(‘abc’)
f.close()

X

文件不存在則創建文件,并以只讀方式打開

文件存在,拋出FileExisError異常

A

文件存在。只寫打開,追加內容

文件不存在,則創建后,只寫打開,追加內容

r是只讀,wxa都是只寫

Wxa都可以產生新的文件w不管文件存在與否,都會生成全新內容得文件,a不管文件是否存在,都能在打開的文件內部追加,x必須要求文件事先不存在,自己創造一個新的文件

文本模式t

字符流,將文件的的字節按照某種字符編碼理解,按照字符操作,open的默認mode就是rt

二進制模式b

字節流,將文件就按照字節理解,與字符編碼無關,二進制模式操作時,字節操作使用bytes類型

f = open(“test”,’rb’)
s = f.read()
print(type(s))
print(s)
f.close()
f = open(‘test’,’wb’)
s = f.write(“馬哥教育”.encode())
print(s)
f.close()

?

f = open(“test”,’r+’)
s = f.read()
f.write(“馬哥教育”)
print(f.read())
f.close()

?

+

r,wa,x提供缺失的讀寫功能,但是,獲取的文件對象依舊按照r,wa,x自己的特征。+不能單獨使用,可以認為他是為前面的模式字符做增強功能的

文件指針

上面的例子中,已經說明了有一個指針

文件指針,指向當前字節位置

mode=r 指針的起始位置在0

mode=a 指針的起始位置在EOF

tell()顯示指針當前的位置

seek(offset[,whence])

移動文件指針位置,offest偏移多少字節,只能是正整數

文本模式下

whence 0 缺省值,表示從頭開始,offest只能是正整數

whence 1 表示從當前位置,offest只接受0

whence 2 表示從EOF開始,offest只接受0

文本模式支持從頭開始向后偏移的方式

Whence1表示從當前位置開始偏移,但是只支持偏移0,相當于原地不動,所以沒什么用

Whence2表示從EOF開始,只支持偏移0,相當于移動文件指針到EOF

Seek是按照字節偏移的

二進制模式下

Whence 0 缺省值,表示從開頭開始,offest只能說正整數

Whence 1 表示從當前位置,offest可正可負

Whence 2 表示從EOF開始,offes可正可負

二進制模式支持任意起點的偏移,從頭,叢尾,從中間位置開始

向后seek可以超界,但是向前seek的時候不能超界,不能超界,否則拋異常

Buffering:緩沖區

-1 表示使用缺省大小的buffer,如果是二進制模式,使用io.DEFAULT_BUFFER_SIZE值,默認是4096或者8192.如果是文本模式,如果是文本模式,如果是終端設備,是行緩寸模式,如果不是,則使用二進制模式策略

0只在二進制模式使用,表示關buffer

1 只在文本模式使用,表示行緩沖,意思就是見到換行符就flush

大于1用于指定buffer的大小

Buffer緩沖區

緩沖區一個內存空間,一般來說是一個FIFO隊列,到了緩沖區慢了或者達到閾值,數據才會flush到磁盤

Flush()將緩沖區數據寫入磁盤

Close()關閉前會調用flush()

Io.DEFAULT.BUFFER_SIZE缺省緩沖區大小字節

二進制模式

?

import io
f = open(‘test’,’w+b’)
print(io.DEFAULT_BUFFER_SIZE)
f.write(“magedu.com”.encode())
f.seek(0)
f.write(“www.magedu.com”.encode())
f.flush()
f.close()

f = open(“test4″,’w+b’,4)
f.write(b”mage”)
f.write(b”du”)
f.close()

文本模式

f = open(“test”,’w+’,1)
f.write(“mag”)
f.write(“magedu”*4)
f.write(‘\n’)
f.write(“hello\npython”)
f.close()

?

import io
f = open(‘test’,”w+”,15)
f.write(“mage”)
f.write(“du”)
f.write(‘hello\n’)
f.write(‘\npython’)
f.write(‘a’*(io.DEFAULT_BUFFER_SIZE – 20))
f.write(“\nwww.magedu.com/python”)

?

Buffering = 0

這是一種特殊的二進制模式,不要內存的buffer,可以看做是一個FIFO的文件

f = open(‘test’,”wb+”,0)
f.write(b’m’)
f.write(b’a’)
f.write(b”g”)
#f.write(b.’magedu*4′)
f.write(b’\n’)
#f.write(b.’hello\npython’)
f.close()

?

Buffering = -1 tb,都是io.DEFAULT_BUFFER_SIZE

Buffering = 0 b關閉緩沖區t不支持

Buffering = 1 b就一個字節,t行緩沖,遇到換行符才flush

Buffering > 1 b模式表示行緩沖值的大小,緩沖區的值可以超過io.DEFAULT_BUFFER_SIZE直到設定的值超過后才把緩沖flus。t模式,是io.DEFAULT_BUFFER_SIZE,flush完成后吧當前字符串也寫入磁盤

似乎看起來很麻煩,一般來說,只需要記得:

文本模式,一般都用默認緩沖區大小

二進制模式,是一個個字節的操作,可以指定buffer的大小

一般來說,默認緩沖區大小是個比較好的選擇,除非明確知道,否則不能調整它

一般編程中,明確知道需要寫磁盤了,都會手動調用榆次flush,而不是等到自動flush或者close的時候

Encoding:編碼,僅文本模式使用

None表示缺省編碼,依賴于操作系統,Windows,linux測試如下代碼

f = open(‘test’,’w’)

f.write(‘啊’)
f.close()

?

Windows下缺省GBK(0xB0A1),LINUX下缺省UTF-8(0xE5 95 8A)

其他參數

Error

什么樣的編碼將被捕獲

Nonestrict表示有編碼錯誤將拋出ValueError異常:ignore表示忽略

Newline

文本模式中,換行的轉換,可以轉換為None’’空子串,’\r’?, ‘\n’?, ‘\r\n’

讀時。None表示’\r’?, ‘\n’?, ‘\r\n’都會被轉換為’\n’:表示不會自動轉換通用換行符,其他合法字符表示換行符就是指定字符,就會按照指定字符分行

寫時,None表示’\n’都會被替換為系統缺省行分隔符os.linesep ‘\n’?或表示’\n’不替換:其他合法字符表示’\n’會被替換為指定的字符

f = open(‘test’,’w’)
f.write(‘python\rwww.python.org\nwww.magedu.com\r\npython3′)
f.close()

newline = [None,”,’\n’,’\r\n’]
for nl in newline:
f = open(‘test’,’r+’,newline=nl)
print(f.readline())
f.close()

Closefd

關閉文件描述符,True表示關閉它,False會在文件關閉后保持這個描述符。fileobj.fileno()查看

Read

Size表示讀取的多少個字符的字節,負數或者None表示讀取到EOF

f = open(‘test’,’r+’,0)
f.write(“magedu”)
f.write(‘\n’)
f.write(‘馬哥教育’)
f.seek(0)
f.read(7)
f.close()
f = open(‘test’,’rb+’)
f.read(7)
f.read(1)
f.close()

行讀取

Readline(size = -1)

一行行讀取文件內容。Size設置一次能讀取行內幾個字符或字節。

Readline(hint = -1)

讀取所有行的列表。指定hint則返回指定的行數

f = open(‘test’)
for line in f:
print(line)

f.close()

Write(s),把子串s寫入到文件中并返回字符的個數

Writeline(lines),將字符串列表寫入文件

f = open(‘test’,’w+’)
lines = [‘abc’,’123\n’,’magedu’]
f.writelines(lines)
f.seek(0)
print(f.read())
f.close()

Close

Flush并關閉文件對象

文件已經關閉,再次沒有任何效果

其他

Seekable()是否可seek

Readable()是否可讀

Writeable()是否可寫

Closed 是否已經關閉

上下文管理

問題的引出

?

lst = []
for _ in range(2000):
lst.append(open(‘test’))
print(len(lst))

Lsof列出打開的文件,就沒有#yum install lsof

$ lsof -p 1427 | grep test | wc -l

Lsof -p 進程號

Ulimit -a 查看所有限制,其中openfile就是打開文件的次數,默認1024

for x in lst:
x.close()

1,異常處理

當出現異常的時候,攔截異常,但是因為很多代碼都可能出現OSError異常,還不好判斷就是因為資源限制產生的

f = open(‘test’)
try:
f.write(‘abc’)#文件只讀,寫入失敗
finally:
f.close()#這個可以

使用它finally可以保證打開的文件可以被關閉

2.?上下文管理

一種特殊的語法,交給解釋器去釋放文件對象

del f
with open(‘test’) as f:
f.write(‘abc’)#文件只讀寫入失敗
f.close()

?

使用with ……as 關鍵字

上下文的管理的語句塊并不會開啟新的作用域

With語句塊執行完的時候,會關閉文件對象

f = open(‘test’)
with f:
f.write(“abc”)
f.close()

?

對于類似于文件對象的IO對象,一般來說都需要在不使用的時候關閉注銷,釋放資源

IO被打開的時候,會獲取一個文件描述符,計算機的資源是有限的,所以操作系統都會做限制

練習

指定一個源文件,實現copy到目標目錄。

filename1 = ‘tmp/test.txt’
filename2 = ‘tmp/test1.txt’

f = open(filename1,’w+’)
lines = [‘abc’,’123′,’namgedu’]
f.writelines(‘\n’.join(lines))
f.seek(0)
print(f.read())
f.close()

def copy(src,dest):
with open(src) as f1:
with open(dest, ‘w’) as f2:
f2.writel(f1.read())

copy(filename1,filename2)

?

有一個文件,對其單詞進行統計,不區分大小寫,并顯示單詞重復最多的10個單詞

d = {}
with open(‘sample’,encoding=’utf-8′) as f:
for line in f:
words = line.split()
for word in map(str.lower,words)
d[word] = d.get(word,0)+1

print(sorted(d.items(),key=lambda item:item[1],reverse=True))?

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/97340

(0)
zhangmengzhangmeng
上一篇 2018-05-02
下一篇 2018-05-02

相關推薦

  • Python內置數據結構——字符串

    知識結構圖 學習筆記 字符串 字符組成的有序序列,字符的集合 使用單引號、雙引號、三引號引起來的字符序列 不可變對象 Unicode類型 定義 單引號、雙引號、三引號 r、R:引號內的字符原樣輸出 元素訪問 索引訪問 可迭代 join連接 “string“.join(iteratable) 使用string作為分隔符將可迭代對象連接起…

    2018-03-31
  • 函數執行過程和遞歸函數練習題

    函數執行過程和遞歸函數練習題

    2018-04-16
  • Centtos7搭建ftp服務

    Centtos7搭建ftp服務 下載安裝軟件包 yum -y install vsftpd ? 開啟啟用ftp服務 systemctl start vsftpd ???#設置立即啟用該服務 systemctl status vsftpd ??#查看該服務當前運行狀態 systemctl enable vsftpd ??#設置開機自動啟用該服務 systemc…

    Python筆記 2018-07-07
  • 封裝與解構 集合

    封裝和解構 封裝:將多個值進行分割,結合在一起,本質上返回元組,只是省掉了小括號 ‘==‘意思為內容一致,‘=’意思為內存空間一致 解構:把線性結構的元素解開,并順序的賦值給其他變量,左邊接納的變量數要和左邊解開的元素數量一致 集合不是非線性 解構中使用*變量名接收,但不能單獨使用,被*變量名收集后組成一個列表 第一個下劃線為9,結果被第二個下劃線重新賦值為…

    Python筆記 2018-04-01
  • Python 部分知識點總結(九)

    此篇博客只是記錄第十一周未掌握或不熟悉的知識點,用來加深印象。

    Python筆記 2018-05-21
  • 函數

    函數、參數、參數解構
    返回值、作用域
    遞歸函數
    匿名函數、
    生成器

    2018-04-16
欧美性久久久久