[PY3]——IO——檔案讀寫

Jelly_lyj發表於2017-03-18

檔案開啟和關閉

# 使用open 開啟檔案,返回時值是一個 File-like物件
f.open('/test/file')

# 使用read讀取檔案
f.read( )

# 使用close關閉檔案
f.close( )

 

讀寫檔案

1. 檔案的操作(f.read/f.write)和檔案開啟方式(f.open)強相關

2. 字元意義:

  • 'r'   open for reading (default)

  • 'w'  open for writing, truncating the file first

  • 'x'   create a new file and open it for writing

  • 'a'   open for writing, appending to the end of the file if it exists

  • 'b'   binary mode

  • 't'    text mode (default)

  • '+'   open a disk file for updating (reading and writing)

  • 'U'  universal newline mode (deprecated)

'r' open for reading (default)

f=open('/test/passwd',mode='r')

# mode=r:可讀
f.read()


# mode=r:不可寫
f.write('test write')
#io.UnsupportedOperation: not writable


# mode=r: 檔案不存在丟擲FileNotFoundError
f=open('/test/not_exist.txt',mode='r')
#FileNotFoundError: [Errno 2] No such file or directory: '/test/not_exist.txt'

'w' open for writing, truncating the file first

# 只要以mode=w方式開啟檔案,就會清空原檔案!
f=open('/test/passwd',mode='w')
#[root@centos1 test]# test -s /test/passwd ;echo $?
#1


# mode=w 不可讀f.read()
#io.UnsupportedOperation: not readable


# mode=w 可寫( 覆蓋 > 寫 )
f.write('test write\n')
#[root@centos1 test]# cat /test/passwd
#test write


# mode=w 開啟一個不存在的檔案,會建立該檔案
f=open('/test/not_exist.txt',mode='w')
#[root@centos1 test]# ls /test/ |grep not_exist.txt
#not_exist.txt

'x' create a new file and open it for writing

# 不能以mode=x開啟一個已存在的檔案
f=open('/test/passwd',mode='x')
#FileExistsError: [Errno 17] File exists: '/test/passwd' # mode=x 總是建立新檔案 f=open('/test/not_exist.txt',mode='x') # mode=x 可寫 f.write('test write') #[root@centos1 test]# cat not_exist.txt #test write # mode=x 不可讀 f.read() #io.UnsupportedOperation: not readable

'a' open for writing, appending to the end of the file if it exists

f=open('/test/passwd',mode='a')

# mode=a 不可讀
f.read()
#io.UnsupportedOperation: not readable # mode=a 可寫,且是以追加到文件末尾(>>)的方式,而不是(>) f.write("zhuijia write") #[root@centos1 test]# cat passwd #test write #zhuijia write # mode=a 不存在的檔案就新建 f=open('/test/not_exist.txt',mode='a') f.write('abc') #[root@centos1 test]# cat not_exist.txt #abc

't' text mode (default)   按字元操作

'b' binary mode           按位元組操作

# mode=rt,以str方式讀取
f=open('/test/passwd',mode='rt')
print(f.read())
#test content
print(type(f.read()))
#<class 'str'>

# mode=rb,以bytes方式讀取
f=open('/test/passwd',mode='rb')
print(f.read())
#b'test content\n'
print(type(f.read()))
#<class 'bytes'>

# mode=wt,以字元方式寫入 f=open('/test/passwd',mode='wt') print(f.write('測試')) #2 ——>輸出的是字元個數 #[root@centos1 test]# cat passwd #測試 # mode=wb,必須以bytes方式寫入 f=open('/test/passwd',mode='wb') print(f.write('測試')) #TypeError: a bytes-like object is required, not 'str' print(f.write('測試'.encode())) #6 ——>按位元組寫入是12個位元組

'+' open a disk file for updating (reading and writing)

當mode包含+時, 會增加額外的讀寫操作, 也就說原來是隻讀的,會增加可寫的操作, 原來是隻寫的,會增加可讀的操作,但是+不改變其他行為

單獨的+不能工作, mode裡必須有且僅有rwxa中的一個

# 我們可以發現以上的“rwxa”四種開啟方式,讀和寫都不能同時進行
# 且“rwxa”是兩兩之間是不能同時使用的
f=open("/test/passwd",mode="rw")
#ValueError: must have exactly one of create/read/write/append mode


f=open("/test/passwd",mode="r+")
# mode="r+" 可讀
print(f.read())
#test content

# mdoe="r+" 可寫( 追加 >> )
f.write("test2")
print(f.read())
#test content
#test2


f=open("/test/passwd",mode="w+")
# mode="w+" 可讀
print(f.read())
#test content

# mode="w+" 可寫( 覆蓋 > )f.write('test2')
print(f.read())
#test2

f=open("/test/passwd",mode="a+")
# mode="a+" 讀不報錯,但內容為空
print(f.read()) #' '

# mode="a+" 可寫
print(f.write('hhh')) #3

 

有特定需求的讀取操作

#開啟二進位制檔案
with open("/Users/michael/test.jpg",'rb') as f:
  print(f.read())

#指定編碼開啟檔案
with open("/Users/gbk.txt",'r',encoding='gbk') as f:
  print(f.read())

#含編碼不規範的檔案開啟
with open("/Users/gbk.txt",'r',encoding='gbk',errors='ignore') as f:
  print(f.read())

#每次最多讀取size()位元組內容(常見於大檔案讀取防止記憶體爆的情況)
read(size)

#按行讀取(常用於配置檔案)
readlines()

 

基本的寫檔案操作

with open('/Users/michael/test.txt', 'w') as f:
  f.write('Hello, world!')

 

讀寫時的指標

當開啟檔案的時候, 直譯器會持有一個指標, 指向檔案的某個位置

當我們讀寫檔案的時候,總是從指標處開始向後操作,並且移動指標

f=open("/test/aa")  #預設mode="rt"
print(f.tell())
#0                  #當mode=r時,指標指向0(檔案開始)
f.read()
print(f.tell())
#13


f=open("/test/aa",mode="a")
print(f.tell())
#13                #當mode=a,指標指向EOF(檔案末尾)
# seek(cookie, whence=0, /)
  cookie:偏移量
  whence:可選引數,有3個value可選
          *0:從檔案開頭開始算起
          *1:從當前位置開始算起
          *2:從檔案末尾算起

 

StringIO和BytesIO

#StringIO和BytesIO是在記憶體中操作str和bytes的方法,使得和讀寫檔案具有一致的介面
#StringIO寫
from io import StringIO
f=StringIO()
f.write('hello')
f.write(',')
f.write('world')
print(f.getvalue())
# hello,world

#StringIO讀
f=StringIO("hello\nhi\nworld")
while True:
s=f.readline()
if s=='':
break
print(s.strip())
# hello
# hi
# world

#BytesIO寫
from io import BytesIO
f=BytesIO()
f.write('xx'.encode('utf-8'))
print(f.getvalue())
# b'\xe.\xb8\x89\xe.\xb8\x83'

##BytesIO讀
import codecs
f=BytesIO('xx'.encode('utf-8'))
print(f.read())
# b'\xe.\xb8\x89\xe.\xb8\x83'

 

上下文管理

File-like物件

序列化和反序列化

 

相關文章