python文件读写总结
昨天晚上导师考核,一上来就被两道文件读写的题给懵逼了,看来文件读写的某些方面还是欠练。来看看这两道题。
文件操作的笔记:https://www.cnblogs.com/alexchenx/p/9035535.html
前提:
有一个文件 test.txt 内容如下:
日照香炉生紫烟,
遥看瀑布挂前川。
飞流直下三千尺,
疑是银河落九天。
第一题:读取诗的第13个汉字。
此题一出,有点懵逼,好像之前没练过这种的呀,马上想 几种办法混于脑中:
a) 先全部读出来,再去取第13个汉字,怎么取 没想到;
b) 使用seek先将光标移到指定位置,再read()出来,由于汉字在utf-8中是3个字节,那就是seek(13*3) ,但是移到第13个字符的后面再read那第13个字符就读不到了,所以是就移到前一个seek(12*3),这时问题又来了,由于第13个字符在第2行,有换行符,在window中换行符是 \r\n 这个要占2个字节,由于seek(12*3) 已经包含了\r\n的2个字节,实际上seek(12*3) 就是多读了1个字节,这时只需减掉多余的1个字节即可读到,然后取第一个字符就得到了结果“步”。
f = open("test.txt", "r", encoding="utf-8")
f.seek(12 * 3 - 1)
data = f.read()[0]
print(data) # 输出结果为:布
f.close()
这种方式在这里固然可以得到想要的结果,但是计算方式很死,假如不知道文件内容,不知道有多少行,假如文件内容还包括字母,数字,特殊字符等等,运行起来肯定要报错的,因为他们在utf-8中占用的字节是不一样的,这种方式是行不通的。
关于换行符:
在PyCharm里可以设置,在PyCharm的右下角有3个模式可以选择:CRLF(\r\n),CR(\r),LF(\n)
最后的解决办法:
用read读取指定的字符数,然后取最后一位,即 f.read(13)[-1]
f = open("test.txt", "r", encoding="utf-8")
data = f.read(13)[-1]
print(data) # 输出结果为:布
f.close()
这种采用读取字符的方式,就不会考虑到字节的问题,每一个字母/数字/特殊字符就是一个字符,所以很轻松的就可以拿到结果。
总结:
read 是读的字符。read(13) ,是读指定个数字符,即从头开始读13个字符,包含第13个。
seek 是读的字节。seek(6),是光标移到到指定字节之后,即光标移到第6个字节之后,读的时候是读从第7个字节开始读。
第二题:删除第3行
这个题其实很简单,但当时一紧张就懵逼了,在判断行的时候没有搞对。
答案如下:
import os
f = open("test.txt", "r", encoding="utf-8")
f2 = open("new_test.txt", "w", encoding="utf-8")
for index, line in enumerate(f):
if index == 2: # 当索引为2,也就是第3个元素的时候 不进行任何操作
continue
f2.write(line) # 但索引不为2的时候将行写入到新文件
f.close()
f2.close()
os.remove("test.txt") # 删除老文件
os.rename("new_test.txt", "test.txt") # 将新文件重命名为老文件
遍历时也可以使用 f.readlines() , 即 for index, line in enumerate(f.readlines()) 不建议使用,这里牵涉到效率问题,可看下面总结。
总结:
f 是一个文件对象,支持for循环,取数据的时候是一行一行的取,节省内存。
f.read() 将文件一次性读取,返回的是字符串。
f.readline() 只读取文件一行内容,返回的是字符串。
f.readlines() 是将文件的每一行作为一个元素,一次性将整个文件存到列表中,返回的是list ,文件内容很大的时候,就会很耗内存。
共有 0 条评论