首页 » 编程 » Python » Python学习 » 正文

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)

发表评论