不少時候,數據讀寫不必定是文件,也能夠在內存中讀寫。python
要把str寫入StringIO,咱們須要先建立一個StringIO,而後像文件同樣寫入便可函數
>>> from io import StringIO >>> f=StringIO() >>> f.write('hello') 5 >>> f.write(' ') 1 >>> f.write('world!') 6 >>> f <_io.StringIO object at 0x7f6bbc76e318> >>> f.getvalue() 'hello world!'
getvalue()方法用於得到寫入後的str編碼
要讀取StringIO,能夠用一個str初始化StringIO,而後像讀文件同樣讀取指針
>>> f=StringIO('Hello!\nHi!\nGoodbye!') >>> while True: ... s=f.readline() ... if s=='': ... break ... print(s.strip()) ... Hello! Hi! Goodbye!
StringIO操做的只能是str,若是要操做二進制數據,就須要使用BytesIO。code
BytesIO實現了在內存中讀寫bytes,咱們建立一個BytesIO,而後寫入一些bytes:blog
>>> from io import BytesIO >>> f=BytesIO() >>> f.write('中文'.encode('utf-8')) 6 >>> f.getvalue() b'\xe4\xb8\xad\xe6\x96\x87'
請注意,寫入的不是str,而是通過UTF-8編碼的bytes。接口
和StringIO相似,能夠用一個bytes初始化BytesIO,而後,像讀文件同樣讀取:ip
>>> from io import BytesIO >>> f=BytesIO(b'\xe4\xb8\xad\xe6\x96\x87') >>> f.read() b'\xe4\xb8\xad\xe6\x96\x87'
StringIO和BytesIO是在內存中操做str和bytes的方法,使得和讀寫文件具備一致的接口。內存
用一個列子加深對StringIO和BytesIO的理解utf-8
# StringIO和BytesIO # stringIO 好比說,這時候,你須要對獲取到的數據進行操做,可是你並不想把數據寫到本地硬盤上,這時候你就能夠用stringIO from io import StringIO from io import BytesIO def outputstring(): return 'string \nfrom \noutputstring \nfunction' s = outputstring() #s爲字符串'string \nfrom \noutputstring \nfunction' #將函數返回的數據在內存中讀 sio=StringIO(s) #能夠用StringIO自己的方法 sio.getvalue() #輸出 #'string \nfrom \noutputstring \nfunction' #也能夠用file-like object的方法 s=sio.readlines() #readlines返回的是一個列表 #['string \n', 'from \n', 'outputstring \n', 'function'] for i in s: print(i.strip()) #去除尾部的回車符號輸出 #string #from #outputstring #function #將函數返回的數據在內存中寫 s=outputstring() sio=StringIO() sio.write(s) #若是是在終端會顯示指針位置值36 #能夠用StringIO自己的方法查看 print(sio.getvalue()) #若是你用file-like object的方法查看的時候,你會發現數據爲空 #由於指針位置在尾部36 for i in sio.readlines(): print(i.strip()) #這時候咱們須要修改下文件的指針位置 #就能夠打印內容了 sio.seek(0,0) #打印指針位置 print(sio.tell()) #結果爲0 # 這就涉及到了兩個方法seek 和 tell # tell 方法獲取當前文件讀取指針的位置 # seek 方法,用於移動文件讀寫指針到指定位置,有兩個參數,第一個offset: 偏移量,須要向前或向後的字節數,正爲向後,負爲向前;第二個whence: 可選值,默認爲0,表示文件開頭,1表示相對於當前的位置,2表示文件末尾 # 用seek方法時,需注意,若是你打開的文件沒有用'b'的方式打開,則offset沒法使用負值哦 #在使用file-like object方法能夠打印了 for i in sio.readlines(): print(i.strip()) # stringIO 只能操做str,若是要操做二進制數據,就須要用到BytesIO # 上面的sio沒法用seek從當前位置向前移動,這時候,咱們用'b'的方式寫入數據,就能夠向前移動了 bio=BytesIO() bio.write(s.encode('utf-8')) #使用getvalue()方法quzhi print(bio.getvalue()) #b'string \nfrom \noutputstring \nfunction' #修改指針 #1表明從當前位置,-36表明往前移動36 bio.seek(-36,1) bio.tell() #0 for i in bio.readlines(): print(i.strip())
注意:當使用StringIO去初始化的時候,其指針是指向0的位置,而若是是用write的方法的時候,其指針會移動到最後
舉例以下
>>> sio=StringIO('abc') >>> sio.getvalue() 'abc' >>> sio.tell() 0 #初始化指針指向0 值爲'abc' >>> sio=StringIO('def') >>> sio.tell() 0 >>> sio.getvalue() 'def' #再次初始化會覆蓋原值
對比write方法
>>> a=StringIO() #寫指針加3 >>> a.write('123') 3 #再次寫追加指針再加3 >>> a.write('456') 3 #值爲追加非覆蓋 >>> a.getvalue() '123456' #最後指針爲6 >>> a.tell() 6