open 打開
read 讀取
write 寫入
close 關閉
readline 行讀取
readlines 多行讀取
seek 文件指針操做
tell 指針位置
其餘python
基本使用:
建立一個文件test,而後打開它,用完關閉linux
f = open("test") #file對象 # windows <_io.TextIOWrapper name='test' mode='r' encoding='cp935'> # linux <_io.TextIOWrapper name='test' mode='r' encoding='UTF-8'> print(f.read()) #讀取文件 f.close() #關閉文件
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-1-f14d31593ce4> in <module> ----> 1 f = open("test") #file對象 2 # windows <_io.TextIOWrapper name='test' mode='r' encoding='cp935'> 3 # linux <_io.TextIOWrapper name='test' mode='r' encoding='UTF-8'> 4 print(f.read()) #讀取文件 5 f.close() #關閉文件 FileNotFoundError: [Errno 2] No such file or directory: 'test'
文件操做中,最經常使用的操做就是讀和寫。
文件訪問的模式由兩種:文本模式和二進制模式。不一樣模式下,操做函數不盡相同,表現的結果也不同。# open的參數vim
打開或建立的文件名。若是不指定路徑,默認時當前路徑windows
r 缺省的,表示只讀打開
w 只寫打開
x 建立並寫入一個新文件
a 寫入打開,若是文件存在,則追加
b 二進制模式
t 缺省的,文本模式
+ 讀寫打開一個文件。給原來只讀,只寫方式打開提供缺失的讀或者寫能力
在上面的例子中,能夠看到默認時文本打開模式,且是隻讀的例子:
bash
#r模式 f = open('test') f.read() f.write('abc') f.close() #默認是隻讀的,打開文件不可寫
--------------------------------------------------------------------------- UnsupportedOperation Traceback (most recent call last) <ipython-input-2-6a7832c033e1> in <module> 2 f = open('test') 3 f.read() ----> 4 f.write('abc') 5 f.close() UnsupportedOperation: not writable
#w模式 f = open('test','w') f.write('好') f.close() f = open('test') f.read() #寫模式打開文件,寫入數據後關閉(寫入方式默認會覆蓋原來數據),在使用默認讀模式打開,讀取文件,
'好'
open默認是隻讀模式r打開已存在的文件
r
只讀打開文件,若是使用write方式,會拋出異常
若是文件不存在,拋出FlieNotFoundError異常
w
表示只讀方式打開,若是讀取則拋出異常
若是文件不存在,則直接建立文件
若是文件存在,則清空文件內容app
f = open('test2','x') f.write('abc') f.close() f = open('test2') f.read()
'abc'
f = open('test2','x')
--------------------------------------------------------------------------- FileExistsError Traceback (most recent call last) <ipython-input-10-ba6940455994> in <module> ----> 1 f = open('test2','x') FileExistsError: [Errno 17] File exists: 'test2'
x
文件不存在,建立文件,並只寫方式打開
文件存在,拋出FileExistsError異常less
f = open('test','a') f.write('def') f.close() f = open('test') f.read()
'好def'
文件存在,只寫打開,追加內容
文件不存在,則建立後,只寫打開,追加內容ssh
r是隻讀,wxa都是隻寫
wxa均可以產生新文件,w無論文件存在與否,都會生成全新內容的文件;a無論文件是否存在都能在打開文件尾部追加;x必需要求文件事先不存在,本身造一個新文件socket
f = open('test','rb') #二進制只讀 s = f.read() print(type(s)) #bytes print(s) f.close() #關閉文件 f = open('test','wb') #IO對象 s = f.write('啊哈呵'.encode()) print(s) f.close()
<class 'bytes'> b'\xe5\xa5\xbddef' 9
# f = open('test','r_') # s = f.read() # f.write('馬哥教育1') # print(f.read()) # f.close() # !cat test f = open('test','a') f.write('123') print(f.read()) f.close()
--------------------------------------------------------------------------- UnsupportedOperation Traceback (most recent call last) <ipython-input-53-72f745833071> in <module> 8 f = open('test','a') 9 f.write('123') ---> 10 print(f.read()) 11 f.close() UnsupportedOperation: not readable
上面的例子中,已經說明了有一個指針文件指針,指向當前字節位置
mode = r ,指針起始在0
mode = a ,指針起始在EOF函數
tell() 顯示指針當前位置
seek(offset[,whence])移動文件指針位置
offset偏移多少字節,whence從哪裏開發。
文本模式下
whence 0 缺省值,表示從頭開始,offset只能正整數
whence 1 表示從當前位置,offset只接受0
whence 2 表示從EOF位置,offset只接受0
文本模式支持從開頭向後偏移的方式。
二進制模式下
whence 0 缺省值,表示從頭開始,offset只能正整數
whence 1 表示從當前位置,offset可正可負
whence 2 表示從EOF位置,offset可正可負示例:
f = open('test')
f.tell() #默認讀模式打開文件,指針在文件起始
0
f.read(1) #讀取第一個文字
'馬'
f.tell() #指針在第三個字節上,默認爲下一個讀取的起始位,中文UTF-8編碼佔三個字節
3
f.read(1) #讀取第一個文字
'哥'
f.tell() #中文UTF-8編碼佔三個字節
6
f.close()
f = open('test','a+') #追加寫入
f.tell() #指針默認在文件尾
26
!cat test
馬哥1123123123123123123
f.write('你好') #添加
2
f.tell()
32
!cat test #這就是指針,注意儘可能不要使用讀模式寫,指針在文件頭部,會覆蓋數據
你好1123123123123123123
!echo "馬哥1123123123123123123" > test
f = open('test','r+')
f.tell()
0
!cat test
馬哥1123123123123123123
f.write('你好')
2
f.tell()
6
!cat test
你好1123123123123123123
#文本模式 !echo "abcdefg" > test f = open('test','r+')
f.tell() #起始
0
f.read()
'abcdefg\n'
f.tell() #EOF
8
f.seek(0) #起始
0
f.read()
'abcdefg\n'
f.seek(2,0)
2
f.read()
'cdefg\n'
f.seek(2,0) #offset必須爲0
2
f.seek(2,1) #offset必須爲0
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-227-8e4bcc97d95f> in <module> ----> 1 f.seek(2,1) #offset必須爲0 ValueError: I/O operation on closed file.
f.seek(2,2) #offset必須爲0
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-226-8025d2a83e5a> in <module> ----> 1 f.seek(2,2) #offset必須爲0 ValueError: I/O operation on closed file.
f.close()
#中文 f = open('test','w+')
f.write('你好世界')
4
f.tell()
12
!cat test
你好世界
f.close()
f = open('test','r+')
f.read(3)
'你好世'
f.seek(1)
1
f.tell()
1
f.read()
--------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-297-571e9fb02258> in <module> ----> 1 f.read() /usr/lib64/python3.6/codecs.py in decode(self, input, final) 319 # decode input (taking the buffer into account) 320 data = self.buffer + input --> 321 (result, consumed) = self._buffer_decode(data, self.errors, final) 322 # keep undecoded input until the next call 323 self.buffer = data[consumed:] UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbd in position 0: invalid start byte
f.seek(2)
2
f.read()
--------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-300-571e9fb02258> in <module> ----> 1 f.read() /usr/lib64/python3.6/codecs.py in decode(self, input, final) 319 # decode input (taking the buffer into account) 320 data = self.buffer + input --> 321 (result, consumed) = self._buffer_decode(data, self.errors, final) 322 # keep undecoded input until the next call 323 self.buffer = data[consumed:] UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 0: invalid start byte
f.seek(3)
3
f.read()
'好世界'
f.close()
read(size=-1)
size表示讀取的多少個字符或字節;負數或者None表示讀取到EOF
f = open('test','r+',1)
f.write('hello,world')
11
f.write('\n')
1
f.write('你好世界')
4
f.seek(0)
0
f.read()
'hello,world\n你好世界'
f.close()
#二進制 f = open('test','rb+')
f.read(7)
b'hello,w'
f.read(1)
b''
f.close()
readline(size=-1)
一行行讀取文件內容。size設置一次能讀取行內幾個字符或字節
readlines(hint=-1)
讀取全部行的列表。指定hint則返回指定的行數
f = open('test','r+')
f.readline() #一行一行讀取,\n爲換行符
'hello,world\n'
f.readline() #一行一行讀取,\n爲換行符
'你好世界'
f.readlines()
['hello,world\n', '你好世界']
write(s),把字符串s寫入到文件種並返回字符的個數
lst = [] #列表生成式 for _ in range(2000): #python range() 函數可建立一個整數列表,通常用在 for 循環中 lst.append(open('test')) #在列表中執行打開test文件
--------------------------------------------------------------------------- OSError Traceback (most recent call last) <ipython-input-387-e2de46ba0013> in <module> 1 lst = [] #列表生成式 2 for _ in range(2000): #python range() 函數可建立一個整數列表,通常用在 for 循環中 ----> 3 lst.append(open('test')) #在列表中執行打開test文件 OSError: [Errno 24] Too many open files: 'test'
print(len(lst)) #Python len() 方法返回對象(字符、列表、元組等)長度或項目個數。
959
lsof列出打開的文件。沒有就#yum install lsof
$ lsof -p 1399 | grep test | wc -l
!lsof -p 959 | grep test | wc -l
0
ulimit -a 查看全部限制。其中open files就是打開文件數的限制,默認1024
for x in lst: x.close()
將文件一次關閉,而後就能夠繼續打開了。在看一次lsof。如何解決?
一、異常處理
當出現異常的時候,攔截異常。可是,應爲不少代碼均可能出現OSError異常,還很差判斷異常就是由於資源限制產生的。
f = open('test') try: f.write('abc') #文件只讀。寫入失敗 finally: f.close()#這樣才行 print(f.closed)
True --------------------------------------------------------------------------- UnsupportedOperation Traceback (most recent call last) <ipython-input-8-5115e18cccb3> in <module> 1 f = open('test') 2 try: ----> 3 f.write('abc') #文件只讀。寫入失敗 4 finally: 5 f.close()#這樣才行 UnsupportedOperation: not writable
使用finally能夠保證打開的文件能夠被關閉二、python上下文管理一種特殊的語法,交給解釋器去釋放文件對象
del f with open('test') as f: f.write('abc') #文件只讀,寫入失敗
--------------------------------------------------------------------------- UnsupportedOperation Traceback (most recent call last) <ipython-input-15-db017c97c470> in <module> 1 del f 2 with open('test') as f: ----> 3 f.write('abc') #文件只讀,寫入失敗 4 5 #測試f是否關閉 UnsupportedOperation: not writable
#測試f是否關閉 f.closed #f的做用域
True
一、使用with ... as 關鍵字
二、上下文管理的語句塊並不會開啓新的做用域
三、with語句執行完的時候,會自動關閉文件對象另外一種寫法
f1 = open('test') with f1: f1.write('abc') #文件只讀,寫入失敗
--------------------------------------------------------------------------- UnsupportedOperation Traceback (most recent call last) <ipython-input-17-3ef7ddf3fe9b> in <module> 1 f1 = open('test') 2 with f1: ----> 3 f1.write('abc') #文件只讀,寫入失敗 UnsupportedOperation: not writable
f1.closed
True
對於相似於文件對象的IO對象,通常來講都須要在不使用的時候關閉,註銷,以釋放資源。
IO被打開的時候,會得到一個文件描述符。計算機資源是有限的,因此操做系統都會作限制。就是爲了保護計算機的資源不要被徹底耗盡,計算資源是共享的,不是獨佔的。
通常狀況下,除非特別明確的知道資源狀況,不然不要提升資源的限制值來解決問題。
3.4版本開始
建議使用pathlib模塊,提供Path對象來操做,包括目錄和文件。
pathlib模塊
獲取路徑
父路徑
通配符
匹配
文件操做
# pathlib模塊 from pathlib import Path #目錄操做 #初始化 p = Path()#不加參數爲當前路徑 print(p) p = Path('a','b','c/d') #當前路徑下的a/b/c/d print(p) p = Path('/etc') #根下的etc目錄 print(p)
. a/b/c/d /etc
路徑拼接和分解
操做符/
Path對象/Path對象
Path對象/字符串 或者 字符串/Path對象
分解
parts屬性,能夠返回路徑中的每個部分
joinpath
joinpath(*other)鏈接多個字符串到Path對象中
p = Path() p = p / 'a' print(p) p1 = 'b' / p print(p1) p2 = Path('c') p3 = p2 / p1 print(p3.parts) p3.joinpath('etc','init.d','Path(httpd)')
a b/a ('c', 'b', 'a') ('c', 'b', 'a') PosixPath('c/b/a/etc/init.d/Path(httpd)')
str獲取路徑字符串
bytes獲取路徑字符串的bytes
p = Path('/etc') print(str(p),bytes(p))
/etc b'/etc'
parent目錄的邏輯父目錄
parents父目錄序列,索引0是直接的父
p = Path('a/b/c/d') print(p.parent.parent.parent) print(p.parent.parent) for x in p.parents: print(x)
a a/b a/b/c a/b a .
name,stem,suffix,suffixes,with_suffix(suffix),with_name(name)
name 目錄的最後一個部分
suffix 目錄中最後一個部分的擴展名
stem 目錄最後一個部分,沒有後綴
suffixes 返回多個擴展名列表
with_suffix(suffix) 補充擴展名到路徑的尾部,返回新的路徑,擴展名存在則無效
with_name(name)替換目錄最後一個部分並返回一個新的路徑
p = Path('/etc/sysconfig/network-scripts/ifcfg.enp0s3') print(p.stem) print(p.name) p1 = Path(str(p) + '.gz') print(p1) print(p1.suffix) print(p1.suffixes) print(p1.with_suffix('.zig')) print(p1.with_name('nihao')) # 另外一種方法 print(p1.parent / 'test') #拼接
ifcfg ifcfg.enp0s3 /etc/sysconfig/network-scripts/ifcfg.enp0s3.gz .gz ['.enp0s3', '.gz'] /etc/sysconfig/network-scripts/ifcfg.enp0s3.zig /etc/sysconfig/network-scripts/nihao /etc/sysconfig/network-scripts/test
cwd() 返回當前系統工做路徑
home() 返回當前家目錄
print(p) print(p.cwd()) print(p.home())
/etc/sysconfig/network-scripts/ifcfg.enp0s3 /root /root
is_dir() 是不是目錄
is_file() 是不是普通文件
is_symlink() 是不是軟連接
is_socket() 是不是socket文件
is_block_device 是不是塊設備
is_char_device() 是不是字符設備
is_absolute() 是不是絕對路徑resolve() 返回一個新路徑,這個新路徑就是當前Path對象的絕對路徑,若是是軟連接則直接被解析
absolute() 也能夠獲取據對路徑,可是推薦使用resolve()exists() 目錄或文件是否存在
rmdir() 刪除空目錄。沒有提供判斷目錄爲空的方法
touch(mode=0o666,exist_ok=True)建立一個文件
as_uri()將路徑返回成URI,例如"file:///etc/passwd"mkdir(mode=0o777,parents=False,exist_ok=False)
parents,是否建立父目錄,True等同於mkdir -p; False時,父目錄不存在,則拋出FileNotFoundError
exist_ok參數,在3.5版本加入。False時,路徑存在,拋出FileNotFoundError;True時,FileNotFoundError被忽略
iterdir() 迭代當前目錄
from pathlib import Path p = Path() print(p) print(p.cwd()) p /= 'a/b/c/d' print(p) p.exists() #True
. /root a/b/c/d False
#建立目錄 # p.mkdir() #直接建立會拋出異常FileNotFoundError # print(p) #沒有父目錄 p.mkdir(parents=True) # p.exists() #True # p.mkdir(parents=True) # p.mkdir(parents=True,exist_ok=True) # p /= 'readme.txt' # p.parent.rmdir() # p.parent.exists() #False '/a/b/c' # p.mkdir() #FileNotFoundError
True
#遍歷,並判斷文件類型,若是是目錄是否能夠判斷其是否爲空 for x in p.parents[len(p.parents)-1].iterdir(): print(x,end='/t') if x.is_dir(): flag = False for _ in x.iterdir(): flag = True break #for 循環是否可使用else子句 print('dir','Not Empty' if flag else 'Empyt',sep='/t') elif x.is_file(): print('file') else: print('other file')
.bash_logout/tfile .bash_profile/tfile .bashrc/tfile .cshrc/tfile .tcshrc/tfile anaconda-ks.cfg/tfile .lesshst/tfile .viminfo/tfile .cache/tdir/tNot Empty .bash_history/tfile .python_history/tfile .local/tdir/tNot Empty 未命名.ipynb/tfile .ipynb_checkpoints/tdir/tNot Empty .ipython/tdir/tNot Empty 未命名1.ipynb/tfile test2/tfile test/tfile .jupyter/tdir/tNot Empty a/tdir/tNot Empty
glob(pattern)通配給定的模式
rglob(pattern)通配給定的模式,遞歸目錄
返回一個生成器
p = Path('/root') print(p) # list(p.golb('test*')) #返回當前目錄對象下的test開頭的文件 list(p.glob('**/*.py')) #遞歸全部目錄,等同rglob
/root [PosixPath('/root/1.py'), PosixPath('/root/a/2.py')]
g = p.rglob('*.py') next(g)
PosixPath('1.py')
match(pattern)
模式匹配,成功返回True
Path('a/b.py').match('*.py') #True Path('a/b/c.py').match('b/*.py') #False Path('a/b/c.py').match('a/*.py') #True Path('a/b/c.py').match('a/*/*.py') #True Path('a/b/c.py').match('a/**/*.py') #True Path('a/b/c.py').match('**/*.py') #True
stat()至關與stat命令
lstat()同stat(),但若是是符號連接,則顯示符號連接自己的文件信息
!ln -s test t from pathlib import Path p = Path('test') p.stat() p1 = Path('t') p1.stat() p1.lstst()
open(mode='r',buffering=-1,encoding=None,errors=None,newline=None)
使用方法相似內建函數open。返回一個文件對象3.5增長的新函數
read_bytes()
以'rb'讀取路徑對應的文件,並返回二進制流。看源碼read_text(encoding= None,errors=None)
以'rt'方式讀取路徑對應的文件,返回文本。
Path.write_bytes(data)
以'wb'方式寫入數據到路徑對應的文件
write_text(data,encoding=None,errors=None)
以'wt'方式寫入字符串到路徑對應的文件
p = Path('my_binary_file') p.write_bytes(b'Binary file contents') p.read_bytes() #b'Binary file contents'
p = Path('my_text_file') p.write_text('Text file contents') p.read_text() #'Text file contents'
from pathlib import Path p = Path('o:/test.py') p.write_text('hello python') print(p.read_text()) with p.open() as f: print(f.read(5))