鱼C论坛

 找回密码
 立即注册
查看: 1066|回复: 5

[已解决]为什么仅仅加上了f.tell()两个程序的输出结果完全不同?

[复制链接]
发表于 2020-3-27 00:14:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#test.txt内容
123
456
789
代码如下:
  1. f = open('test.txt', 'r+')
  2. print(f.tell(), end = ' ')
  3. f.write('000\n')
  4. print(f.tell(), end = ' ')
  5. f.readline()
  6. print(f.tell(), end = ' ')
  7. f.write('999')
  8. print(f.tell(), end = ' ')

  9. f.close()
复制代码
输出结果是

0 5 10 16
而test.txt也被修改为了
000
456
789999
但是代码如果改成(仅仅是把write和readline之间的f.tell()去掉了,结果就大相径庭
  1. f = open('test.txt', 'r+')
  2. print(f.tell(), end = ' ')
  3. f.write('000\n')
  4. f.readline()
  5. print(f.tell(), end = ' ')
  6. f.write('999')
  7. print(f.tell(), end = ' ')

  8. f.close()
复制代码
输出结果是0 10 21

而text.txt居然被修改成了
123
456
789000
999
请问各位大神这是什么情况?为什么连第一个write()写的内容都被添加到文件末尾了?



最佳答案
2020-3-27 10:13:54
风风魔王 发表于 2020-3-27 08:47
大佬太强了!!我还发现如果一开始使用seek的话,那么紧接着的写入也会写到最后面,readline()操作之后使 ...

可能在改写文件的时候读取会导致一些未知的问题(估计和指针有关系),所以建议改写文本文件用只读方式打开文件读取内容,改写之后写入到新建的文件里,然后删除老文件,把新文件改名为老文件名这种方式。如果只需要新增内容,用a模式打开文件,在文件尾写入新内容,象日志文件、记录文件可以用这种方式。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-27 06:49:53 | 显示全部楼层
我来说说我花了两个小时发现的规律:
r+方式打开的文本文件是覆写模式,write会在当前指针位置写入指定字符串;就象代码1前半部分做的一样,'000\n'取代了'123\n',因为一开始指针在起始位置0;
但使用readline()或read()后,就进入了追加模式,此时wirte会在文件尾追加方式写入,就是后面的'999',如果去掉readline()那一行,结果会是这样的:
000
999
789
完全是覆写模式。所以如果在write之前readline()或read(),后面所有的wirte就会追加到文件尾部,就象代码2的结果一样,你可以试试把readline()放到第一个write之前看看。
但问题是代码2的readline()是在第一个write后面,这又怎么解释?我也不知道,也许是bug。我发现的规律是如果readline()紧接着write,就会将上面紧接的若干write都使用追加模式,除非中间有涉及指针的操作,seek()和tell()都行,这就是代码1的第一个write为什么没有受到下面的readline()的影响的原因,把print(f.tell(), end = ' ')改成seek(0)也是一样的效果。
最后发现readline()开启的追加模式可以用seek()来结束而恢复到覆写模式。
不知道有没有大神知道这个到底是怎么回事?

评分

参与人数 1荣誉 +2 收起 理由
永恒的蓝色梦想 + 2 无条件支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2020-3-27 08:15:03 | 显示全部楼层
txxcat 发表于 2020-3-27 06:49
我来说说我花了两个小时发现的规律:
r+方式打开的文本文件是覆写模式,write会在当前指针位置写入指定字 ...

老哥太强了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-27 08:47:42 | 显示全部楼层
本帖最后由 风风魔王 于 2020-3-27 09:24 编辑
txxcat 发表于 2020-3-27 06:49
我来说说我花了两个小时发现的规律:
r+方式打开的文本文件是覆写模式,write会在当前指针位置写入指定字 ...

大佬太强了!!我还发现如果一开始使用seek的话,那么紧接着的写入也会写到最后面,readline()操作之后使用seek 又可以随意插入了,神奇

  1. f = open('test.txt', 'r+')
  2. print(f.tell(), end = ' ')
  3. f.seek(0)
  4. print(f.tell(), end = ' ')
  5. f.write('000\n')
  6. f.readline()
  7. print(f.tell(), end = ' ')
  8. f.seek(1)
  9. print(f.tell(), end = ' ')
  10. f.write('999')
  11. print(f.tell(), end = ' ')

  12. f.close()
复制代码
输出结果是 0 0 10 1 4

修改后的文件是
1999456
789000


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-27 10:13:54 | 显示全部楼层    本楼为最佳答案   
风风魔王 发表于 2020-3-27 08:47
大佬太强了!!我还发现如果一开始使用seek的话,那么紧接着的写入也会写到最后面,readline()操作之后使 ...

可能在改写文件的时候读取会导致一些未知的问题(估计和指针有关系),所以建议改写文本文件用只读方式打开文件读取内容,改写之后写入到新建的文件里,然后删除老文件,把新文件改名为老文件名这种方式。如果只需要新增内容,用a模式打开文件,在文件尾写入新内容,象日志文件、记录文件可以用这种方式。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-27 10:20:59 | 显示全部楼层
txxcat 发表于 2020-3-27 10:13
可能在改写文件的时候读取会导致一些未知的问题(估计和指针有关系),所以建议改写文本文件用只读方式打 ...

谢谢大佬,越发觉得能实现word这种可以随意插入功能是在是太强了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 01:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表