文件操作基本流程
文本文件和二进制文件
- 文本文件:可以使用文本编辑器查看
- 二进制文件:保存的内容不是直接给人查看的,而是使用专用软件查看的,例如图片文件、视频文件
操作文件过程
- 打开文件
- 读写文件
2.1:读,将文件内容读入内存
2.2:写:将内存内容写入文件 - 关闭文件
- open:负责打开文件,并且返回文件对象
- read / write / close 三个方法都需要通过 文件对象 来调用
- open函数:
-
- 第一个参数是文件名(文件名区分大小写),第二个参数是打开方式;
- 如果文件存在返回文件操作对象;
- 如果文件不存在抛出异常
- read方法:可以一次性读入并返回文件的所有内容;
- close方法:负责关闭文件;
# 1. 打开,文件名需要注意大小写
file = open("README")
# 2. 读取
text = file.read()
print(text)
# 3. 关闭
file.close()
文件打开方式
f=open("文件名","打开方式")
**PS:**r+方式中,指针放在文件开头,对于已有文件,该操作会将新的内容覆盖在原内容上
with open("1.txt","r+")as read_f:
read_f.write("111")
对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
rb
wb
ab
**注:**以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
- 频繁的移动文件指针,会影响文件的读写效率,开发中更多的时候会以 只读、只写 的方式来操作文件.
按行读取
- read方法默认会把文件的所有内容一次性读取到内存
- readline方法可以一次读取一行内容;
- readlines一次性读取整个文件内容,并按行返回到list,方便我们遍历
- 方法执行后,文件指针移动到下一行,准备再次读取;
# 方式一、通过循环按行读取文件所有内容
file1=open("1.txt")
i=1
while True:
text = file1.readline().strip()
if text:
print("这是第%s行内容" % i)
print(text)
i+=1
else:
break
file1.close()
# 用with重新组织
i=1
with open("1.txt")as read_f:
while True:
text=read_f.readline().strip()
if text:
print("这是第%s行内容" % i)
print(text)
i+=1
else:
break
# 方式二,通过for遍历按行读取文件所有内容
file1=open("1.txt")
for i in file1:
print(i.strip())
file1.close()
文件编码
- f=open(…)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。
f=open('a.txt','r',encoding='utf-8')
文件操作方法
常用
read(3)
- 文件打开方式为文本模式时,代表读取3个字符
- 文件打开方式为b模式时,代表读取3个字节
其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate
注意: - seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单
位移动的 - truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果。
所有
def close(self, *args, **kwargs): # real signature unknown
关闭文件
pass
def fileno(self, *args, **kwargs): # real signature unknown
文件描述符
pass
def flush(self, *args, **kwargs): # real signature unknown
刷新文件内部缓冲区
pass
def isatty(self, *args, **kwargs): # real signature unknown
判断文件是否是同意tty设备
pass
def read(self, *args, **kwargs): # real signature unknown
读取指定字节数据
pass
def readable(self, *args, **kwargs): # real signature unknown
是否可读
pass
def readline(self, *args, **kwargs): # real signature unknown
仅读取一行数据
pass
def seek(self, *args, **kwargs): # real signature unknown
指定文件中指针位置
pass
def seekable(self, *args, **kwargs): # real signature unknown
指针是否可操作
pass
def tell(self, *args, **kwargs): # real signature unknown
获取指针位置
pass
def truncate(self, *args, **kwargs): # real signature unknown
截断数据,仅保留指定之前数据
pass
def writable(self, *args, **kwargs): # real signature unknown
是否可写
pass
def write(self, *args, **kwargs): # real signature unknown
写内容
pass
def __getstate__(self, *args, **kwargs): # real signature unknown
pass
def __init__(self, *args, **kwargs): # real signature unknown
pass
@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature.
"""
pass
def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass
def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass
案例
案例1:文件的修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
import os
with open('a.txt') as read_f,open('a.txt.new','w') as write_f:
data = read_f.read()
data = data.replace('Hello','nihao')
write_f.write(data)
os.remove('a.txt')
os.rename('a.txt.new','a.txt')
方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖
import os
with open('a.txt') as read_f,open('a.txt.new','w') as write_f:
for line in read_f:
line = line.replace('nihao','Hello')
write_f.write(line)
os.remove('a.txt')
os.rename('a.txt.new','a.txt')
案例2:文件复制
1.小文件
用read方式,整个复制
with open("1.txt")as read_f,open("1_copy.txt","w",encoding="utf-8")as write_f:
text=read_f.read();
write_f.write(text)
2.大文件
考虑到资源,通常一行一行来复制
with open("1.txt")as read_f,open("1_bigCopy","w")as write_f:
while True:
text=read_f.readline()
if not text:
break
write_f.write(text)
3.计算总价
通过代码,创建text1,构建成这种数据类型:[{‘name’:‘apple’,‘price’:10,‘amount’:3},
{‘name’:‘tesla’,‘price’:1000000,‘amount’:1}…] 并计算出总价钱。
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3
list1=[]
with open("text1")as read_f:
#一次性读取整个文件内容,并按行返回到list,方便我们遍历
for i in read_f.readlines():
data=i.strip() #去掉换行符
text = data.split() #空格符分开
print(text) #结果是一个列表
dict1={"name":text[0],"num":text[1],"price":text[2]}
list1.append(dict1) #字典添加到列表中
print(list1)
sum=0
for i in list1:
sum+=int(i["price"])*int(i["num"])
print("总价格为:",sum)