python基础之文件处理总结
读文件:
with open('contacts.txt', 'r', encoding='utf-8') as f: data = f.read()
二进制模式读
使用场景:网络传输(视频、图片或进行网络传输的文本)
with open('contacts.txt', 'rb') as f: data = f.read() print(data) # 打印出16进制的编码格式
检测编码的工具
import chardet with open('contacts.txt', 'rb') as f: data = f.read() print(data) print(chardet.detect(data)) # {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''} confidence是自信程度 print(data.decode('utf-8')) # 文本的内容
循环文件和写模式操作文件
with open('contacts.txt', 'r', encoding='utf-8') as f: for line in f: print(line) # 会多出很多空格 ''' 因为print()打印时默认加了换行,所以加上,如果出现文件输出有空行的情况直接将print的换行取消即可。 给print()加一个取消自动换行的end=""参数即可:print(line,end=""),跟windows,unix没有关系。就是这么简单。 ''' with open('兼职.txt', 'w', encoding='utf-8') as f: # w是创建,会清空以前的内容,慎用。 f.write('好好学编程') with open('兼职.txt', 'wb') as f: f.write('好好学编程'.encode('utf-8'))
追加模式操作文件
with open('contacts.txt', 'a', encoding='utf-8') as f: f.write('\n小胖 河北 182 100 13222222222') with open('contacts.txt', 'ab') as f: f.write('\n小胖 河北 182 100 13222222222'.encode('utf-8')) # 把二进制用utf-8编码
读写混合模式
with open('contacts.txt', 'r+', encoding='utf-8') as f: data = f.read() print('content', data) f.write('\nnewline 1哈哈') f.write('\nnewline 2哈哈') f.write('\nnewline 3哈哈') f.write('\nnewline 4哈哈') # 在后面追加写的内容 print('new content', f.read()) # 不显示新写的内容,因为写完后光标在最后的位置,后面是空的,所以读出来是空的。
写读模式 ---> 先写后读(几乎没有应用场景)
with open('contacts.txt', 'w+', encoding='utf-8') as f: data = f.read() print('content', data) f.write('\nnewline 1哈哈') f.write('\nnewline 2哈哈') f.write('\nnewline 3哈哈') f.write('\nnewline 4哈哈') # 重新创建,把之前的清空掉在写 print('new content', f.read())
其他功能
flush 强制把内容从内存(缓存)刷到硬盘
readable 判断是否可读。在linux上一切皆文件,网卡、硬盘都是文件,这些是不可读的。
with open('f_flush_test.txt', 'w', encoding='utf-8') as f: f.write('\ntest2') f.flush() print(f.readable()) # False
readline 只读一行,遇到\r或\n为止
with open('contacts.txt', 'r', encoding='utf-8') as f: print(f.readline(), end='') # 王心[路飞学城]9 46 13813234424 print(f.readline(), end='') # 马纤羽 深圳 173 50 13744234523 # ......
seek 按字符编码所占字节来跳寻找,比如utf-8跳转3个字节,那么seek(3)往前跳一个字。
tell 返回当前文件操作光标位置
with open('seek_test.txt', 'r', encoding='utf-8') as f: # 文本内容:# 好好学习编程 print(f.read(1)) # 好 # read按字符读 print(f.tell()) # 3 print(f.read(2)) # 好学 print(f.tell()) # 9 # print(f.seek(11)) # print(f.read(1)) # 报错 'utf-8' codec can't decode byte 0xa0 in position 0: invalid start byte print(f.seek(12)) print(f.read(1)) # 编
seekable 判断是否可以进行seek操作,和readable一样主要用在linux上
truncate 按指定长度截断文件
with open('truncate_test.txt', 'r+', encoding='utf-8') as f: # 文本内容:学习编程 # r+ 可读可写,若文件不存在报错。 # print(f.tell()) # 0 # print(f.truncate()) # 0 # 默认截断到末尾 # f.seek(3) # f.truncate() # 文本内容只剩下"学"了,把后面的都截断了。 # 可以自己写参数指定从哪开始截断,并不是依据光标位置截断,而是从头开始截多少。 f.seek(3) f.truncate(9) # 文本内容剩下"学习编"了
文件修改功能
word和vim是把内容全部加载到内存上,当在内存修改完保存后,它们在把所有内容重新写到硬盘上,所以可以实现任意字符的修改。这是用占内存的方式来修改文件
下面是用占硬盘的方式来修改
import os f_name = 'contacts.txt' f_new_name = "%s.new" % f_name old_str = '马纤羽' new_str = 'new马纤羽' f = open(f_name, 'r', encoding='utf-8') f_new = open(f_new_name, 'w', encoding='utf-8') for line in f: if old_str in line: line = line.replace(old_str, new_str) f_new.write(line) with open(f_name, 'r', encoding='utf-8') as f: for line in f: if old_str in line: line = line.replace(old_str, new_str) with open(f_new_name, 'a', encoding='utf-8') as f_new: f_new.write(line) os.rename(f_new_name, f_name) # 把新文件名替换成旧文件名,这样就替换了旧文件 # 完成后contacts.txt文件里之前是马纤羽的都变成了new马纤羽
下面是用占内存的方式来修改
with open('contacts.txt', 'r+', encoding='utf-8') as f: data = f.read() data = data.replace('杜姗姗', 'Alex') f.seek(0) f.write(data) # 如果是减内容的话(比如以前是1个G,改完后就剩800MB了),可以用truncate截取到800MB那个点。