Python 文件处理

1、打开文件

open() 方法

Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。 :::tips 注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。 ::: open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)
完整的语法格式如下:

  1. open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
  1. f1 = open(r'd:\测试文件.txt', mode='r', encoding='utf-8')
  2. content = f1.read()
  3. print(content)
  4. f1.close()
  1. with open(r'd:\测试文件.txt', mode='r', encoding='utf-8') as f1:
  2. content = f1.read()
  3. print(content)
  1. open()内置函数,open底层调用的是操作系统的接口。
  2. f1变量,又叫文件句柄,通常文件句柄命名有f1,fh,file_handler,f_h,对文件进行的任何操作,都得通过文件句柄.方法的形式。
  3. encoding:可以不写。不写参数,默认的编码本是操作系统默认的编码本。windows默认gbk,linux默认utf-8,mac默认utf-8。
  4. mode:可以不写。默认mode='r'
  5. f1.close()关闭文件句柄。
  6. 另外使用with open()的好处: ```python

    优点1:不用手动关闭文件句柄。

    with open(‘C:\Users\Fcant\test.txt’, encoding=’utf-8’) as f1: print(f1.read())

优点2:一个语句可以操作多个文件句柄。

with open(‘C:\Users\Fcant\test.txt’, encoding=’utf-8’) as f1, \ open(‘文件操作的写’, encoding=’utf-8’, mode=’w’) as f2: print(f1.read()) f2.write(‘hahaha’)

  1. <a name="83f72e23c2927812feed0255fc482798"></a>
  2. #### 绝对路径和相对路径
  3. 1. 绝对路径:指的是绝对位置,完整地描述了目标的所在地,所有目录层级关系是一目了然的。比如C:/Users/Python37/python.exe
  4. 1. 相对路径:是从当前文件所在的文件夹开始的路径。
  5. - 2.1 test.txt:是在当前文件夹查找 test.txt 文件。
  6. - 2.2 ./test.txt:也是在当前文件夹里查找test.txt文件, ./ 表示的是当前文件夹,可以省略。
  7. - 2.3 ../test.txt:从当前文件夹的上一级文件夹里查找 test.txt 文件。../ 表示的是上一级文件夹。
  8. - 2.4 demo/test.txt,在当前文件夹里查找demo这个文件夹,并在这个文件夹里查找 test.txt文件。
  9. 3. 路径书写的三种方法
  10. - 3.1:\\
  11. - `file = open('C:\\Users\\Python基础\\xxx.txt')`
  12. - 3.2: r'\'
  13. - `file = open(r'C:\Users\Python基础\xxx.txt')`
  14. - 3.3 :'/'(推荐)
  15. - `file = open('C:/Users/Python基础/xxx.txt')`
  16. <a name="372fa724a391f67eecaa2e6eccbd5ab0"></a>
  17. #### 常用文件的访问模式
  18. 1. 打开文件的模式有(默认为文本模式):

r 只读模式【默认模式,文件必须存在,不存在则抛出异常】 w 只写模式【不可读;不存在则创建;存在则清空内容在写入】 a 只追加写模式【不可读;不存在则创建;存在则只追加内容】

  1. 2. 对于非文本文件,我们只能使用b模式。注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码。

rb 以二进制读取 wb 以二进制写入 ab 以二进制追加

  1. 3. `'+'`模式(就是增加了一个功能)

r+b 读写【可读,可写】 w+b 写读【可写,可读】 a+b 写读【可写,可读】

  1. 4. bytes类型操作的读写,写读,写读模式

r+b 读写【可读,可写】 w+b 写读【可写,可读】 a+b 写读【可写,可读】

  1. 5. 关于`r+`模式:打开一个文件用于读写,文件指针默认将会放在文件的开头。
  2. :::tips
  3. 注意:如果在读写模式下,先写后读,那么文件就会出问题,因为默认光标是在文件的最开始,要是先写,则写入的内容会将原内容覆盖掉,直到覆盖到写完的内容,然后在从后面开始读取。
  4. :::
  5. ```python
  6. 文件'test.txt'中的内容是:Hello World
  7. #1. 先读后写
  8. f1 = open('C:\\Users\\Fcant\\test.txt', encoding='utf-8', mode='r+')
  9. content = f1.read()
  10. print(content)
  11. f1.write('Python开发者')
  12. f1.close()
  13. #2. 先写后读(错误实例)
  14. f1 = open('C:\\Users\\Fcant\\test.txt', encoding='utf-8', mode='r+')
  15. f1.write('Python开发者')
  16. content = f1.read()
  17. print(content)
  18. f1.close()

2、关闭文件

调用close()方法关闭文件
文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:

  1. f.close()

3、文件读写

A.文件读取的四种方式

文件读取的方式有三种:

1)read()

read:如果指定了参数 size,就按照该指定长度从文件中读取内容,否则,就读取全文。被读出来的内容,全部塞到一个字符串里面。这样有好处,就是东西都到内存里面了,随时取用;但如果文件内容太多了,内存会吃不消。注意换行符也为占用一个内存,缺点需要知道光标的位置,以及每一行的大小SIZE。

  1. f = open('C:\\Users\\Fcant\\test.txt', 'r',encoding='gbk') #这里的文本文件,大家可以自己写一个,没有硬性要求。
  2. # f.read(10)
  3. f.read(5)
  4. 'DataS'

2)readline()

readline() 方法用于从文件读取整行,包括 “\n“ 字符。从字面意思可以看出,该方法每次读出一行内容。所以,读取时占用内存小,比较适合大文件,该方法返回一个字符串对象。如果指定了一个非负数的参数,则返回指定大小的字节数,包括 “\n“ 字符。
语法:**fileObject.readline()**;

  1. f = open('C:\\Users\\Fcant\\test.txt', 'r',encoding='gbk')
  2. while True:
  3. line=f.read()
  4. if not line:#到 EOF,返回空字符串,则终止循环
  5. break
  6. print(line)

3)readlines()

readlines() 方法用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。当文件太大时,内存可能不够用。如果碰到结束符 EOF 则返回空字符串。
如果碰到结束符 EOF 则返回空字符串。
语法:**fileObject.readlines()**;

  1. f = open('C:\\Users\\Fcant\\test.txt', 'r',encoding='gbk')
  2. print(f.readlines())
  3. #遍历每行打印
  4. f = open('C:\\Users\\Fcant\\test.txt', 'r',encoding='gbk')
  5. for line in f.readlines():
  6. print(line)

4)for循环读取文件内容

for 循环读取。文件句柄是一个迭代器。特点是每次循环只在内存中占一行的数据,非常节省内存。

  1. f1 = open('C:\\Users\\Fcant\\test.txt', encoding='utf-8')
  2. for line in f1:
  3. print(line.strip())
  4. f1.close()

B.文件写入

w模式

没有文件,则创建文件,写入内容;如果文件存在,先清空原文件内容,在写入新内容。

  1. f1 = open('C:\\Users\\Fcant\\test.txt', encoding='utf-8', mode='w')
  2. f1.write('Hello World')
  3. f1.close()

wb模式

  1. f1 = open(r'编码进阶.png', mode='rb')
  2. content = f1.read()
  3. f1.close()
  4. f2 = open('图片.jpg', mode='wb')
  5. f2.write(content)
  6. f2.close()

关于清空

关闭文件句柄,再次以w模式打开此文件时,才会清空。

C.指针定位

tell() 方法用来显示当前指针的位置

  1. f = open('test.txt')
  2. print(f.read(10)) # read 指定读取的字节数
  3. print(f.tell()) # tell()方法显示当前文件指针所在的文字
  4. f.close()

seek(offset, whence) 方法用来重新设定指针的位置。

  • offset:表示偏移量
  • whence:只能传入012中的一个数字。
    • 0表示从文件头开始
    • 1表示从当前位置开始
    • 2 表示从文件的末尾开始
      1. f = open('test.txt','rb') # 需要指定打开模式为rb,只读二进制模式
      2. print(f.read(3))
      3. print(f.tell())
      4. f.seek(2,0) # 从文件的开头开始,跳过两个字节
      5. print(f.read())
      6. f.seek(1,1) # 从当前位置开始,跳过一个字节
      7. print(f.read())
      8. f.seek(-4,2) # 从文件末尾开始,往前跳过四个字节
      9. print(f.read())
      10. f.close()

      4、总结-文件的打开模式

      其实关于文件的打开有很多种模式,这里我们用一个表格总结一下
模式 概述
t 文本模式 (默认)。
x 写模式,新建一个文件,如果该文件已存在则会报错。
b 二进制模式。
+ 打开一个文件进行更新(可读可写)。
U 通用换行模式(不推荐)。
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

以上为文件打开的所有方式,但实际应用中常用的就其中几种,不必硬记,根据自己的需求记住几个常用的就好。

5、实现文件拷贝功能

  1. import os
  2. file_name = input('请输入一个文件路径:')
  3. if os.path.isfile(file_name):
  4. old_file = open(file_name, 'rb') # 以二进制的形式读取文件
  5. names = os.path.splitext(file_name)
  6. new_file_name = names[0] + '.bak' + names[1]
  7. new_file = open(new_file_name, 'wb') # 以二进制的形式写入文件
  8. while True:
  9. content = old_file.read(1024) # 读取出来的内容是二进制
  10. new_file.write(content)
  11. if not content:
  12. break
  13. new_file.close()
  14. old_file.close()
  15. else:
  16. print('您输入的文件不存在')

6、将数据写入内存

除了将数据写入到一个文件以外,还可以使用代码,将数据暂时写入到内存里,可以理解为数据缓冲区。Python中提供了StringIO和BytesIO这两个类将字符串数据和二进制数据写入到内存里。

StringIO

StringIO可以将字符串写入到内存中,像操作文件一下操作字符串。

  1. from io import StringIO
  2. # 创建一个StringIO对象
  3. f = StringIO()
  4. # 可以像操作文件一下,将字符串写入到内存中
  5. f.write('hello\r\n')
  6. f.write('good')
  7. # 使用文件的 readline和readlines方法,无法读取到数据
  8. # print(f.readline())
  9. # print(f.readlines())
  10. # 需要调用getvalue()方法才能获取到写入到内存中的数据
  11. print(f.getvalue())
  12. f.close()

BytesIO

如果想要以二进制的形式写入数据,可以使用BytesIO类,它的用法和StringIO相似,只不过在调用write方法写入时,需要传入二进制数据。

  1. from io import BytesIO
  2. f = BytesIO()
  3. f.write('你好\r\n'.encode('utf-8'))
  4. f.write('中国'.encode('utf-8'))
  5. print(f.getvalue())
  6. f.close()