Python 3.4
读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
读文件def read_1(): file_handle = open('c:/test.txt', 'r') file_handle.read() file_handle.close() # 文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的def read_2(): try: file_handle = open('c:/test.txt', 'r') finally: file_handle.close() # 保证文件句柄能一定得到关闭def read_3(): # read_2方法的简化写法,会自动调用close方法 with open('c:/test.txt', 'r') as file_handle: file_handle.read()read()# 会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容# 如果文件很小,read()一次性读取最方便readline()# 每次读取一行内容# 如果不能确定文件大小,反复调用read(size)比较保险readlines()# 一次读取所有内容并按行返回list# 如果是配置文件,调用readlines()最方便
写文件如读文件中的方法打开文件后,通过file_handle.write('Hello, world!')就可以把内容写入文件了。写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。
很多时候,数据读写不一定是文件,也可以在内存中读写。使用StringIO和BytesIO就可以读写内存。
StringIOfrom io import StringIOdef test_1(): sIO = StringIO() sIO.write('hello') sIO.write(' ') sIO.write('world!') print(sIO.getvalue())def test_2(): sIO = StringIO('hello\nworld') # 要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取 while True: str = sIO.readline() if str == '': break print(str)
BytesIO与StringIO操作一样,只是BytesIO操作的是二进制数据。from io import BytesIObIO = BytesIO()bIO.write('中文'.encode('utf-8'))bIO = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')bIO.read()
操作文件和目录的函数一部分放在os模块中,一部分放在os.path模块中。
# 查看当前目录的绝对路径os.path.abspath('.')# 把test设置为当前路径的子目录os.path.join(os.path.abspath('.'), 'test')# 创建这个test目录os.mkdir(os.path.join(os.path.abspath('.'), 'test'))# 删除这个test目录os.rmdir(os.path.join(os.path.abspath('.'), 'test'))# 拆分文件路径和文件名返回一个元组os.path.split('c:/a.txt') # ('c:/', 'a.txt')# 拆分文件路径和文件名返回一个元组os.path.splitext('c:/a.txt') # ('c:/a', '.txt')
# 文件重命名os.rename('test.txt', 'test.py')# 删除文件os.remove('test.py')# 拷贝文件shutil.copyfile()# 拷贝目录shutil.copy()# 列出当前文件夹下所有目录[x for x in os.listdir('.') if os.path.isdir(x)]# 列出当前文件夹下所有py文件[x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling。例如把以下字典保存到磁盘上的过程:d = dict(name='keynes', age=20, score=88)
保存对象import pickledict = {'name': 'keynes', 'sex': 'male'}pickle.dumps(dict) # 把dict转成字节码with open('c:/test.txt', 'wb') as file_handle: pickle.dump(dict, file_handle) # 把dict转成字节码并写入到file_handle所指向的文件中
读入对象import pickledict = {'name': 'keynes', 'sex': 'male'}pickle.dumps(dict) # 把dict转成字节码pickle.loads(dict) # 把字节码转成dictwith open('c:/test.txt', 'rb') as file_handle: pickle.load(file_handle) # file_handle所指向的文件中的字节码转成对象
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。关于序列化,更好的方式是使用JSON格式进行互换。