文件读写是每一门编程语言的最基本的核心功能,有了文件读写功能,才能方便地存储和读取数据

文件读写

现在的操作系统不允许普通的程序直接进行磁盘操作,所以文件读写请求操作系统打开一个文件对象,然后通过操作系统提供的接口对我们的文件进行读写操作。

读写文件是最常见的IO操作,python内置了读写文件的函数

在python中读写文件十分简单,我们可以使用python内置的open()函数来打开文件对象

1. open(file,mode,encoding,errors)
file:文件路径
mode:模式(r,w,a,rb,wb,ab)
encoding:指定读取的编码格式,如:utf-8,gbk等
errors:对编码错误的处理,默认是严格的,若使用"ignore"则可以忽略编码错误

功能:打开一个文件,并且获取到打开文件的对象

注意:

  1. 参数file:读取文件时,文件一定要存在;写入文件时,可以存在,也可以不存在,不存在会自动创建文件
  2. 参数mode:读取文件的时候使用"r"或者"rb",默认"r";写入文件时使用"w"、“a”、“wb"或者"ab”
  3. 当使用w模式的时候,覆盖写,若此文件已经存在,后面写的会将前面的文件进行覆盖,若此文件不存在,则创建此文件。
  4. 当使用a模式的时候,追加写,若此文件已经存在,后面写的追加在原文件的后面,若此文件不存在,则创建文件。

下面是参数mode分别为"w"和"a"的比较:

fp = open("demo.txt","w",encoding="utf-8")
fp.write("hello")
fp.close()

运行这段代码,不管运行多少次,demo.txt文件只有一个"hello"字符串

fp = open("demo.txt","a",encoding="utf-8")
fp.write("hello")
fp.close()

运行这段代码,运行多少次,demo.txt文件就会有多少个"hello"字符串,假设运行了3次,文件中内容如下:

hellohellohello
2. fp.close()

功能:关闭文件(如果是写入文件时,还有一个功能就是保证内容写入到文件中)

注意:当文件读取完毕之后,一定要进行关闭,因为打开的文件是占内存的,并且对于系统来讲它一次性打开文件的个数也是有限制的

3. fp.read()和fp.read(size)

需求:现在有这样一个文件demo.txt,文件内容如下,要求从文件中读取内容

There are bridges on the rivers, 河上有桥,
As pretty as you please; 如你所愿的那么悦目;
But the bow that bridges heaven, 然而横跨在穹苍的长虹,
And overtops the trees, 却比树梢更高,
And builds a road from earth to sky, 而能建筑一条通行天际的道路,
Is prettier far than these. 比这些更为美好。

fp.read()功能:一次性读取所有内容

fp = open("demo.txt","r",encoding="utf-8")
print(fp.read())
fp.close()

fp.read(size)功能:一次性读取size个字节(当文件比较大的时候建议使用此方法)

fp = open("demo.txt","r",encoding="utf-8")
while True:
    str1 = fp.read(100)
    if str1 == "":
        break
    print(str1,end="")
fp.close()
4. fp.readline()和fp.readlines()

fp.readline()功能:一次性读取一行

fp = open("demo.txt","r",encoding="utf-8")
while True:
    str1 = fp.readline()
    if str1 == "":
        break
    print(str1,end="")
fp.close()

fp.readlines()功能:一次性读取所有内容,以列表的方式返回,列表每个元素就是读取到每一行的数据

fp = open("demo.txt","r",encoding="utf-8")
print(fp.readlines())
fp.close()

运行结果如下:

['There are bridges on the rivers, 河上有桥,\n', 'As pretty as you please; 如你所愿的那么悦目;\n', 'But the bow that bridges heaven, 然而横跨在穹苍的长虹,\n', 'And overtops the trees, 却比树梢更高,\n', 'And builds a road from earth to sky, 而能建筑一条通行天际的道路,\n', 'Is prettier far than these. 比这些更为美好。']

注意:

  1. 当文件特别大的情况下,我们可以使用fp.read(size),或者fp.readline()
  2. 当读取配置文件的时候,建议使用fp.readline() 或者使用fp.readlines()
5. fp.write(str)和fp.writelines(list)

fp.write(str)功能:将字符串写入到打开的文件中,注意写入必须是字符串

fp = open("demo.txt","w",encoding="utf-8")
fp.write("你好")
fp.close()

demo.txt文件中内容如下:

你好

fp.writelines(list)功能:将列表中的元素写入到打开的文件中,注意列表中元素一定是字符串

fp = open("demo.txt","w",encoding="utf-8")
fp.writelines(["hello","good","nice"])
fp.close()

demo.txt文件中内容如下:

hellogoodnice
with语句
with open(file,mode,encoding) as fp:
    #文件操作
    #写入文件
    #读取文件

在Python中,还提供了with语句,当with下面的语句执行完毕之后,它会自动帮我们关闭此文件,无需我们手动close文件

with open("demo.txt","r",encoding="utf-8") as fp:
    print(fp.read())
二进制文件的读写

当读取音频视频以及图片的时候,我们需要使用二进制文件的读取以及写入

与普通文件的读写一样,如下:

with open(file,mode) as fp:
	#写入文件
    #读取文件

注意:

  1. 无需传递参数encoding(编码格式)
  2. 读取二进制文件时,mode使用"rb";写入二进制文件时,mode使用"wb"或者"ab"
  3. 与普通文件读写一样,使用read函数和write函数,区别在于二进制文件读写的是二进制字符串
  4. 一般情况下,音频或者视频文件比较大,所以使用f.read(size)居多

需求:将图片读取并且写入到另外的一个文件中

def copyfile(path1,path2):
    with open(path1,"rb") as f1:
        with open(path2,"wb") as f2:
            while True:
                strb = f1.read(1024)
                if strb == b"":
                    break
                f2.write(strb)

if __name__ == '__main__':
    copyfile("Tulips.jpg","copy.jpg")
内存中的读写

很多时候,数据读写不一定是文件,也可以在内存读写

1. StringIO

StirngIO顾名思义就是在内存中读写字符串

要把字符串写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:

from io import StringIO

sio = StringIO()
sio.write("hello")
sio.write("good")
print(sio.getvalue())	#hellogood

我们可以使用getvalue()函数获取到写入内存的字符串

要读取StringIO,可以用一个str初始化StringIO,然后像读文件一样读取:

from io import StringIO

sio = StringIO("hello jerry!!!")
print(sio.read())	#hello jerry!!!
2. BytesIO

StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO

BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:

from io import BytesIO

bio = BytesIO()
bio.write("中国".encode("utf-8"))
print(bio.getvalue())
print(bio.getvalue().decode("utf-8"))

运行结果如下:

b'\xe4\xb8\xad\xe5\x9b\xbd'
中国

注意:写入的不是str,而是经过UTF-8编码的bytes

和StringIO类似,可以用一个bytes初始化BytesIO,然后像读文件一样读取:

from io import BytesIO

bio = BytesIO("中国红".encode("utf-8"))
strb = bio.read()
print(strb)
print(strb.decode("utf-8"))

运行结果如下:

b'\xe4\xb8\xad\xe5\x9b\xbd\xe7\xba\xa2'
中国红
CSV文件的读写

CSV文件以纯文本形式存储表格数据

具体读写方式如下:

import csv

def readCSVFile(path):
    csvlist = []
    with open(path,"r",encoding="gbk",errors="ignore") as fp:
        csv_reader = csv.reader(fp)
        for row in csv_reader:
            csvlist.append(row)
    return csvlist

def writeCSVFile(path,csvlist):
    with open(path,"w",encoding="gbk",errors="ignore") as fp:
        csv_writer = csv.writer(fp)
        # 一次性写入
        # csv_writer.writerows(res)
        #一行一行写入
        for row in csvlist:
            csv_writer.writerow(row)

if __name__ == '__main__':
    path1 = "000002.csv"
    path2 = "copy.csv"
    csvlist = readCSVFile(path1)
    writeCSVFile(path2,csvlist)