08 文件操作

Posted zero-zero-zero

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了08 文件操作相关的知识,希望对你有一定的参考价值。

本节主要内容:

1. 初识文件操作

2.只读(r, rb)

3.只写(w, wb)

4.追加(a, ab)

5.r+读写

6.w+写读

7.a+写读(追加写读)

8.其他操作方法(seek(n)光标移动到n位置, tell()获取光标的位置, truncate()截断文件)

9.文件的修改以及另一种打开文件句柄的方式

主要内容:
?一. 初识?文件操作
使?用python来读写?文件是非常简单的操作. 我们使?用open()函数来打开?一个?文件, 获取到?文
件句句柄. 然后通过?文件句句柄就可以进?行行各种各样的操作了了. 根据打开?方式的不同能够执?行行的操
作也会有相应的差异.
打开?文件的?方式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b 默认使?用的是r(只读)模式

read(), read(n)

1. read() 将?文件中的内容全部读取出来. 弊端: 占内存. 如果?文件过?大.容易易导致内存崩溃

2.read(n) 读取n个字符. 需要注意的是. 如果再次读取. 那么会在当前位置继续去读?而不
是从头读, 如果使?用的是rb模式. 则读取出来的是n个字节

f = open("胡辣汤", mode="r", encoding="utf-8")
content = f.read(3)  # read(n) 读取n个字符
content = f.read() # 一次性全都读取出来读取文件中的内容

readline(), readlines()

readline() ?一次读取?一?行行数据, 注意: readline()结尾, 注意每次读取出来的数据都会有?一
个 所以呢. 需要我们使?用strip()?方法来去掉 或者空格

readlines()将每?一?行行形成?一个元素, 放到?一个列列表中. 将所有的内容都读取出来. 所以
也是. 容易易出现内存崩溃的问题.不推荐使?用

line = f.readline() # 读取一行数据
print(line.strip()) # strip()去掉空白。空格, 	 


lst = f.readlines() # 一次性全都读取出来, 返回的是列表
print(lst)
路径的问题
两种:
1. 绝对路径(当文件路径是固定的时候)
从磁盘根目录找文件。 windows下用的就是c,d,e,f, linux: userinxxxx
2. 相对路径(用的多)
相对路径相对于当前程序所在的文件夹
../ 表示上一层文件夹

 	 转义字符。 有固定的含义的。 推荐用r
f = open(r"E:哈哈 啦啦啦.txt", mode="r", encoding="utf-8")
print(f.read())

realine 转换成for循环
循环读取. 这种?方式是组好的. 每次读取?一?行行内容.不会产?生内存溢出的问题.
#一次读取一行
while 1:
    line = f.readline()
    print(line)

#  文件句柄是一个可迭代对象
f = open("胡辣汤", mode="r", encoding="utf-8")
for line in f: # 读取文件中的内容。 一行一行的读取。 每次读取的内容交给前面的变量
    print(line.strip())

注意: 读取完的?文件句句柄?一定要关闭 f.close()

 

write(‘str‘) writelines(‘str‘)

写的时候注意. 如果没有?文件. 则会创建?文件, 如果?文件存在. 则将原件中原来的内容删除, 再写入新内容

obj1 = open(E:PythonL\11-8\filetest.txt,r)
obj1 = open(filetest.txt,w+)
obj1.write(I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting
)
obj1.writelines([
                 Repeat outrightly, but also repeat the well-being of
,
                 Eventually swaying in the desert oasis
                 ]

wb模式下. 可以不指定打开?文件的编码. 但是在写?文件的时候必须将字符串串转化成utf-8的
bytes数据

f = open("?小娃娃", mode="wb")
f.write("?金金?毛狮王".encode("utf-8"))
f.flush()
f.close()

 

 

文本文件的复制

# 文本文件的复制
f1 = open(r"c:日记本.txt", mode="r", encoding="utf-8")
f2 = open(r"d:日记本.txt", mode="w", encoding="utf-8")

for line in f1: # 从f1中读取数据
    f2.write(line) # 写入到f2中
f1.close()
f2.close()
b - bytes 读取和写入的是字节 , 用来操作非文本文件(图片, 音频, 视频)
rb, wb, ab
# 把胡一菲从c盘复制到d盘, 单纯的从bytes角度来复制的。 适用于所有文件
f1 = open(r"c:胡一菲.jpg", mode="rb")
f2 = open(r"d:胡二非.jpg", mode="wb")

for line in f1: # 分批量的读取内容
    f2.write(line) # open()出来的结果可以使用read或者write. 根据mode来看

f1.close()
f2.close()

 文件操作 +:

r+ 读写, w+ 写读, a+ 追加写读, r+b, w+b, a+b

+ 扩展

# r+,
#正常的
f = open("person", mode="r+", encoding="utf-8")
content = f.read()
f.write("黄蓉")
print(content)

#错误的示范
f = open("person", mode="r+", encoding="utf-8")
f.write("杨千桦") # 默认如果直接写入的话。 在开头写入。 覆盖开头的内容
content = f.read()
print(content)

# r+
# 深坑请注意: 在r+模式下. 如果读取了了内容. 不论读取内容多少. 光标显?示的是多少. 再写入或者操作?文件的时候都是在结尾进?行行的操作.
#所以如果想做截断操作. 记住了了. 要先挪动光标. 挪动到你想要截断的位置. 然后再进?截断关于truncate(n), 如果给出了了n. 则从开头开头进?行行截断, 如果不给n, 则从当前位置截断. 后?面
#的内容将会被删除
f = open("person", mode="r+", encoding="utf-8") info = f.read(3) f.write("胡辣汤") print(info)

 w+  

先将所有的内容清空. 然后写入. 最后读取. 但是读取的内容是空的, 不常?

有?人会说. 先读不就好了了么? 错. w+ 模式下, ?一开始读取不到数据. 然后写的时候再将原来
的内容清空. 所以, 很少?.

 

f = open("person", mode="w+", encoding="utf-8") # 先清空。 然后再操作
f.write("你好。 我叫肿瘤君")
content = f.read() # 写入东西之后。 光标在末尾。 读取不到内容的
print(content)
f.close()
a+
a+模式下, 不论先读还是后读. 都是读取不到数据的.
# a+, 不论光标在何处 写入的时候都是在末尾
f = open("person", mode="a+", encoding="utf-8")
f.write("我叫李嘉诚") # 默认写在末尾
content = f.read()
print(content)
f.close()

 

光标

概述

seek() 方法用于移动文件读取指针到指定位置。

语法

seek() 方法语法如下:

fileObject.seek(offset[, whence])

参数

  • offset -- 开始的偏移量,也就是代表需要移动偏移的字节数

  • whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。 

返回值

该函数没有返回值。

f = open("person", mode="r",encoding=utf-8)
f.read(3) # 读取三个字符
# seek()移动光标
f.seek(3,0)
info = f.read(3) # 读取三个字符
print(info)

如果把seek(3,0)改成seek(3, 1)就会报错

  File "/code/day008 文件操作/07 光标.py", line 5, in <module>
    f.seek(3,1)
io.UnsupportedOperation: can‘t do nonzero cur-relative seeks

照理说,按照seek()方法的格式file.seek(offset,whence),后面的1代表从当前位置开始算起进行偏移,那又为什么报错呢?
这是因为,在文本文件中,没有使用b模式选项打开的文件,只允许从文件头开始计算相对位置,从文件尾计算时就会引发异常。将  f=open("aaa.txt","r+")  改成

f = open("person","rb")   就可以了
f = open("person", mode="rb")
f.read(9) # 读取三个字符
# seek()移动光标
f.seek(3,0)
info = f.read(9) # 读取三个字符
print(info.decode(utf-8)# 义在于

 tell() 程序返回当前光标的位置

概述

tell() 方法返回文件的当前位置,即文件指针当前位置。

 

语法

tell() 方法语法如下:

fileObject.tell()

参数

返回值

返回文件的当前位置。

# 生命的意义在于折腾
f = open("person", mode="r",encoding=utf-8)
info = f.read(3)
print(info)
print(f.tell()) # 获取光标位置 9
truncate() 截断文件. 慎用
尽量不要瞎测试, w, w+
f = open(r"C:Program Files (x86)TencentQQBinQQScLauncher.exe", mode="r+", encoding="utf-8")
f.seek(5) # 光标移动到5
f.truncate() # 默认从开头截取到光标位置
# f.truncate(3) # 从头截取到3
f.close()

文件的修改和操作

import os # 导入os模块

import time # 时间模块

# 优点:不用关闭句柄, 自动关闭连接
with open("唐诗", mode="r", encoding="utf-8") as f1,    open("唐诗_副本", mode="w", encoding="utf-8") as f2:
    for line in f1:
        line = line.replace("善良", "sb")
        f2.write(line)

time.sleep(5)
os.remove("唐诗") # 删除源文件
time.sleep(5)
os.rename("唐诗_副本", "唐诗") # 把副本改名成源文件
‘‘‘
编号,名称,价格,数量,仓库,phone
1,榴莲,500,60000,1号仓库,10010
2,苹果,700,70000,2号仓库,10086
1,榴莲,500,60000,1号仓库,155
2,苹果,700,70000,2号仓库,166
‘‘‘
f = open("水果.data", mode="r", encoding="utf-8")
titles = f.readline().strip() # 读取第一行 id,name,price,num
t_list = titles.split(",") # 【id,name,price,num】

lst = []
for line in f: # "1,苹果,500,60000"  {id:1,name:liulian, num:xx, price:xxx}
    dic = {}
    ll = line.strip().split(",")
    for i in range(len(t_list)):
        dic[t_list[i]] = ll[i]
    lst.append(dic)
f.close()
print(lst)

 

 

 

 



 

 





 






































以上是关于08 文件操作的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode 如何操作用户自定义代码片段(快捷键)

代码片段 PHP,预期文件结尾,我错在哪里?

反射机制入门

反射机制入门