python 3 文件操作
一、文件读出写入操作
open 函数中的参数值
open(file, mode='r', buffering=-1,
encoding=None, errors=None,
newline=None , closefd=True, opener=None)
在使用该函数的时候,除了file参数必填外,其他参数可以选用。在本代码中对其他参数使用了默认值。
在使用open()函数时的时候,如果文件不存在,那么将会返回IOError。
参数说明:
file:文件名称;
- mode:制定了文件打开的方式,函数提供了如下方式,其中,'rt’为默认方式。
‘r’ : open for reading (default)——只读,默认方式
‘w’ : open for writing, truncating the file first——写入,会覆盖源文件内容
‘x’ : create a new file and open it for writing——创建新文件,并写入内容,如果文件已存在,将会报错:FileExistsError
‘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)——更新磁盘文件,读写
- buffering:用于设置缓存策略
在二进制模式下,使用0来切换缓冲;在文本模式下,通过1表示行缓冲(固定大小的缓冲区)。
在不给参数的时候,二进制文件的缓冲区大小由底层设备决定,可以通过io.DEFAULT_BUFFER_SIZE获取,通常为4096 或 8192字节
文本文件则采用行缓冲。
- encoding:编码或者解码方式。默认编码方式依赖平台,如果需要特殊设置,可以参考codecs模块,获取编码列表。
- errors:可选,并且不能用于二进制模式,指定了编码错误的处理方式,可以通过codecs.Codec获得编码错误字符串
- newline:换行控制,参数有:None,’\n’,’\r’,’\r\n’。
输入时,如果参数为None,那么行结束的标志可以是:’\n’,’\r’,’\r\n’任意一个,并且三个控制符都首先会被转化 为:’\n’,然后才会被调用;
如果参数为’’,所有的通用的换行结束标志都可以用,但是行结束标识符返回调用不会被编码。
输出时,如果参数为None,那么行结束的标志可以是:’\n’被转换为系统默认的分隔符;如果是’’,’\n’则不会被编码。
- closefd:false:文件关闭时,底层文件描述符仍然为打开状态,这是不被允许的,所以,需要设置为ture
- opener:可以通过调用opener方式,使用自定义的开启器。底层文件描述符是通过调用opener或者file, flags获得的。
- opener必须返回一个打开的文件描述。将os.open作为opener的结果,在功能上,类似于通过None。
打开文件的方式:r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b默认使用的是r(只读)模式
读取文件文件时,文件时一定要存在在的,用‘w’方式,写入文件时,文件可以不存在,若文件不存在,则新建文件,若文件存在覆盖里面的内容,若用‘a’的方式写入内容,则在文件末尾追加内容,如下例子
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# author:chenhui
# datetime:2019/5/16 19:57
# software: PyCharm
#!/usr/bin/python
with open('D:/pythonpra/pa1.txt',mode = 'r') as f: # f 为文本 默认为读.可直接读出中文
s = f.read() #调用文本函数,读取f文本中的内容,读取后内容为字符串形式
for i in s.split():
print(i)
with open("D:/pythonpra/pa2.txt",mode = 'w') as f: #写入文件,可以中文
text1 = input() #write函数写入的是一个字符串
f.write(text1)
with open("D:/pythonpra/pa2.txt",mode = 'a') as f:
text1 = input()
f.write(text1)
一般我们要操作一个文件时,一般要先打开文件,然后在最后关闭文件。有时还的控制当读取文件时出错,抛出异常。但是使用了with....as......函数就不用那么麻烦了
若用with.....as...的控制的话,当执行完文件后,自动关闭文件。当跳出with....as...这个区域时,文件自动关闭。
很显然,也可以手动打开和关闭文件
f = open('somefile.txt', 'rt')
data = f.read()
f.close()
二、打印输出至文件中,若open文件时,用的‘wt’,则覆盖,若用的‘at’则在末尾追加。在输出函数中,file是print的一个参数。
with open('D:/pythonpra/pa1.txt',mode = 'wt',newline='\n') as f: # 把打印输出内容写入文件中,覆盖
print("hello world!",file = f)
with open('D:/pythonpra/pa1.txt', mode='at', newline='\n') as f: # 把打印输出内容写入文件中,追加
print(" 陈辉", file = f)
结果:
三、其实print输出函数中,还有两个参数,一个分隔符sep,一个结束符end;
如下:
print('ABC',123,99.0,sep=' ',end = '!!!')
结果:
关于分割符,其实还有写人喜欢这么用join函数,下面说一下join函数的用法
str = '-'
l = ['123','456','ABC']
print(str.join(l))
print(' '.join(l))
结果:
但是join仅仅适用于字符串 ,如下
l = ['123','456',567]
print(' '.join(l))
结果:
意味着join只能适用于字符串,但是可以强制转化为字符型
l = ['123','456',567]
print(' '.join([str(x) for x in l]))
当然你也不用那么麻烦,如下
l = ['123','456',567]
print(l)
print(*l,sep=' ')
结果:
四、读写字节数据
读写二进制文件,比如读写 图片(.jpg文件),声音文件等等
下面若读写二进制模式的文件中文本数据时,必须确保要进行解码和编码操作。如:
with open('D:/pythonpra/pa1.bin',mode = 'rb') as f:
ss = f.read() # 从硬盘中读取,二进制字节流字符串,进行解码decode(),变成文本字符串,
text = ss.decode(encoding='utf-8',errors='ignore')
with open('D:/pythonpra/222.bin',mode = 'wb') as f:
tt = 'hello wrold!' #文本字符串 文本字符串本身就是unicode,只能编码,写入硬盘
f.write(tt.encode('utf-8'))
五、字符串的I/O操作
使用操作类文件对象的程序来操作文本或二进制字符串
使用 io.StringIO()
和 io.BytesIO()
类来创建类文件对象操作字符串数据
StringIO的行为与file对象非常像,但它不是磁盘上文件,而是一个内存里的“文件”,我们可以像操作磁盘文件那样来操作StringIO。此模块主要用于在内存缓冲区中读写数据。模块中只有一个StringIO类,所以它的可用方法都在类中,此类中的大部分函数都与对文件的操作方法类似。
我自己认为的:好像要读取一个StringIO的类,必须要初始化的才行如:
s1 = io.StringIO('Hello\nWorld\n')
ss = s1.read(4)
print(ss)
这样就读不出来,哪位大佬解释一下:
import io
s = io.StringIO()
s.write("hello\n")
print("chenhui",file=s)
print(s.getvalue())
ss = s.read(4)
print(ss)
结果:
没有读出想要的ss的内容
方法详情请参考博客二:https://blog.csdn.net/u013210620/article/details/79276280
六、处理压缩文件
详情请看:https://blog.csdn.net/Rozol/article/details/72672703
七、读取固定大小的文件 迭代
你想在一个固定长度记录或者数据块的集合上迭代,而不是在一个文件中一行一行的迭代。
通过下面这个小技巧使用 iter
和 functools.partial()
函数:
代码:
from functools import partial
Size = 32
with open("D:/pythonpra/pa2.txt",'r') as f:
records = iter(partial(f.read,Size),b'') # iter为迭代器,partial 规定多长自节读取
for i in records:
print(i)
iter()
函数,如果你给它传递一个可调用对象和一个标记值,它会创建一个迭代器。 这个迭代器会一直调用传入的可调用对象直到它返回标记值为止,这时候迭代终止。
iter(object[, sentinel)]方法有两个参数。
第一种 iter(object) 这种情况,object必须是序列对象,且支持迭代协议(iteration protocol)或者支持序列协议(sequence protocol)。
list = [1,2,3]
for i in iter(list):
print(i)
第二种 iter(object, sentinel)
如果传递了第二个参数,则object必须是一个可调用的对象。此时,iter创建了一个迭代器对象,每次调用这个迭代器对象的__next__()方法时,都会调用object。如果__next__的返回值等于sentinel,则抛出StopIteration异常,否则返回下一个值。
functools.partial
用来创建一个每次被调用时从文件中读取固定数目字节的可调用对象。
最后再提一点,上面的例子中的文件时以二进制模式打开的。 如果是读取固定大小的记录,这通常是最普遍的情况。 而对于文本文件,一行一行的读取(默认的迭代行为)更普遍点