鱼C论坛

 找回密码
 立即注册
查看: 136|回复: 7

[已解决]文件对象方法write和writelines写入字符数量的问题

[复制链接]
回帖奖励 20 鱼币 回复本帖可获得 5 鱼币奖励! 每人限 1 次(中奖概率 60%)
发表于 2025-8-16 16:49:10 | 显示全部楼层 |阅读模式

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

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

x
分别用write、writelines这两种方法向写入相同的字符串,为什么最后字符数量不一样
代码如下
  1. a = open("fish.txt","w+")
  2. f = open("FishC.txt","w+")
  3. a.write("I love FishC.\nI love my wife.")
  4. f.writelines(["I love FishC.\n","I love my wife."])
  5. a.tell()
  6. 29
  7. f.tell()
  8. 30
复制代码

但是每次从头用read()方法读取它俩数据的时候,不论read里面的参数设置成多少,他们读取的数据都一样
求大佬解惑
最佳答案
2025-8-17 19:35:06
在 Python 中,write() 和 writelines() 都用于将数据写入文件,但它们在处理换行符(\n)的方式上有所不同,这导致了你在读取文件时看到的字符数量差异。

write() 方法

write() 方法将整个字符串作为一个整体写入文件,不会自动添加换行符:

  1. a = open("fish.txt", "w+")
  2. a.write("I love FishC.\nI love my wife.")
复制代码

字符串 "I love FishC.\nI love my wife." 被写入文件。换行符 \n 是字符串的一部分,因此文件中包含了换行。


writelines() 方法

writelines() 方法接受一个字符串列表,并将每个字符串依次写入文件。

它不会自动添加换行符,除非你在字符串中明确包含:

  1. f = open("FishC.txt", "w+")
  2. f.writelines(["I love FishC.\n", "I love my wife."])
复制代码

两个字符串被写入文件,每个字符串末尾都有换行符 \n。


字符数量差异的原因

鱼油提到在调用 a.tell() 时返回 29,而 f.tell() 返回 30。

因为 write() 方法在写入字符串时,可能会在字符串末尾添加额外的换行符,导致字符数增加。

当你使用 read() 方法读取文件时,Python 会根据操作系统的默认设置处理换行符。

在 Windows 系统上,换行符通常是 \r\n,而在类 Unix 系统上是 \n。Python 会自动处理这些差异。

  1. with open("fish.txt", "r") as file:
  2.     content = file.read()
  3.     print(repr(content))
复制代码

这将输出文件的内容,包括换行符。

结论:

  • write():将整个字符串写入文件,不会自动添加换行符。
  • writelines():将字符串列表写入文件,不会自动添加换行符,除非字符串中包含。
  • 字符数量差异:可能是由于 write() 方法在写入时添加了额外的换行符。
  • 读取文件:Python 会根据操作系统的默认设置处理换行符。


为了确保一致的换行行为,建议在使用 write() 或 writelines() 时,显式地在字符串中包含换行符。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-8-16 16:53:56 | 显示全部楼层
您的代码中 `writelines()` 没有参数,这会导致错误(实际代码中应有参数)。推测您可能这样调用:

  1. # write 方式
  2. a.write("I love FishC.\nI love my wife.")  # 直接写入整个字符串

  3. # writelines 方式(假设传入列表)
  4. lines = ["I love FishC.\n", "I love my wife."]
  5. f.writelines(lines)
复制代码


### 问题原因:
1. 换行符转换(文本模式特性):
   - 在 w+(文本模式)下,写入 \n 时:
     - Windows 系统自动转换为 \r\n(2字节)
     - Linux/Mac 保持 \n(1字节)
   - 您的 tell() 结果差异源于此转换。

2. 字符串长度计算:
   - 原字符串总长度:29 字符(含1个 \n
   

  1.      "I love FishC.\n"   # 14字符(\n占1位)
  2.      "I love my wife."    # 15字符
  3.      总计:14 + 15 = 29
  4.      
复制代码


3. 关键差异:
   - write() 写入 整个字符串,系统按需转换换行符。
   - writelines() 写入 字符串列表,每个元素独立处理换行符。

### 为什么 `tell()` 结果不同?
假设在 Windows 系统:
- `a.write(...)` 后:
  - 实际写入内容:I love FishC.\r\nI love my wife.
  - 字节数:28普通字符 + \r\n(2字节) + 15字符 = 30字节
  - 但 tell() 返回 29(逻辑位置,非实际物理偏移)。

- `f.writelines(lines)` 后:
  - 实际写入内容:
   

  1.     "I love FishC.\r\n"     # 15字节(\n被转\r\n)
  2.     "I love my wife."       # 15字节
  3.     总计:15 + 15 = [b]30字节[/b]
  4.    
复制代码

  - tell() 返回 30

### 为什么 `read()` 读取内容相同?
- 文本模式下的 read() 会自动将 \r\n 转换回 \n
- 无论实际存储是 \n 还是 \r\n,读回程序后都会变成 \n

### 验证方法:
用二进制模式读取实际存储内容:

  1. # 检查 a 文件(write写入)
  2. with open("fish.txt", "rb") as file:
  3.     print(file.read())  # 输出 b'I love FishC.\r\nI love my wife.'(Windows)

  4. # 检查 f 文件(writelines写入)
  5. with open("FishC.txt", "rb") as file:
  6.     print(file.read())  # 输出 b'I love FishC.\r\nI love my wife.'(Windows)
复制代码


### 总结:
| 方法          | 系统       | 实际存储字节数 | `tell()` 返回值 | 读取后内容          |
|---------------|------------|----------------|-----------------|---------------------|
| `write()`     | Windows    | 30 字节        | 29              | 与原始字符串一致    |
| `writelines()`| Windows    | 30 字节        | 30              | 与原始字符串一致    |
| 两者          | Linux/Mac  | 29 字节        | 29              | 与原始字符串一致    |

结论:  
这是由文本模式的换行符转换导致的物理存储差异,但读取时会自动还原为统一的 \n,因此内容显示一致。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-8-17 19:35:06 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +5 鱼币

在 Python 中,write() 和 writelines() 都用于将数据写入文件,但它们在处理换行符(\n)的方式上有所不同,这导致了你在读取文件时看到的字符数量差异。

write() 方法

write() 方法将整个字符串作为一个整体写入文件,不会自动添加换行符:

  1. a = open("fish.txt", "w+")
  2. a.write("I love FishC.\nI love my wife.")
复制代码

字符串 "I love FishC.\nI love my wife." 被写入文件。换行符 \n 是字符串的一部分,因此文件中包含了换行。


writelines() 方法

writelines() 方法接受一个字符串列表,并将每个字符串依次写入文件。

它不会自动添加换行符,除非你在字符串中明确包含:

  1. f = open("FishC.txt", "w+")
  2. f.writelines(["I love FishC.\n", "I love my wife."])
复制代码

两个字符串被写入文件,每个字符串末尾都有换行符 \n。


字符数量差异的原因

鱼油提到在调用 a.tell() 时返回 29,而 f.tell() 返回 30。

因为 write() 方法在写入字符串时,可能会在字符串末尾添加额外的换行符,导致字符数增加。

当你使用 read() 方法读取文件时,Python 会根据操作系统的默认设置处理换行符。

在 Windows 系统上,换行符通常是 \r\n,而在类 Unix 系统上是 \n。Python 会自动处理这些差异。

  1. with open("fish.txt", "r") as file:
  2.     content = file.read()
  3.     print(repr(content))
复制代码

这将输出文件的内容,包括换行符。

结论:

  • write():将整个字符串写入文件,不会自动添加换行符。
  • writelines():将字符串列表写入文件,不会自动添加换行符,除非字符串中包含。
  • 字符数量差异:可能是由于 write() 方法在写入时添加了额外的换行符。
  • 读取文件:Python 会根据操作系统的默认设置处理换行符。


为了确保一致的换行行为,建议在使用 write() 或 writelines() 时,显式地在字符串中包含换行符。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-8-18 07:07:40 From FishC Mobile | 显示全部楼层

回帖奖励 +5 鱼币

学习
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-8-18 08:20:50 | 显示全部楼层

回帖奖励 +5 鱼币

两个不一样
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-8-18 09:45:53 | 显示全部楼层

回帖奖励 +5 鱼币

是不是 python 版本特性?3.8.5 不能复现。 捕获.JPG
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2025-8-18 14:55:53 | 显示全部楼层
smallwh 发表于 2025-8-18 09:45
是不是 python 版本特性?3.8.5 不能复现。

我又试了一下跟你这一样了,奇怪,之前是不一样的,遇到bug了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-8-19 15:18:56 From FishC Mobile | 显示全部楼层

回帖奖励 +5 鱼币

学习
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-30 22:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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