当前位置: 首页 > article >正文

【新人系列】Python 入门(十四):文件操作

✍ 个人博客:https://blog.csdn.net/Newin2020?type=blog
📝 专栏地址:https://blog.csdn.net/newin2020/category_12801353.html
📣 专栏定位:为 0 基础刚入门 Python 的小伙伴提供详细的讲解,也欢迎大佬们一起交流~
📚 专栏简介:在这个专栏,我将带着大家从 0 开始入门 Python 的学习。在这个 Python 的新人系列专栏下,将会总结 Python 入门基础的一些知识点,方便大家快速入门学习~
❤️ 如果有收获的话,欢迎点赞 👍 收藏 📁 关注,您的支持就是我创作的最大动力 💪

Python 中对文件的操作有很多种常见的操作包括创建、删除、修改权限、读取、写入等这些操作可大致分为以下 2 类:

  • 删除、修改权限:作用于文件本身属于系统级操作。
  • 写入、读取:是文件最常用的操作作用于文件的内容属于应用级操作。

文件的应用级操作可以分为以下 3 步每一步都需要借助对应的函数实现:

  • 打开文件:使用 open( ) 函数该函数会返回一个文件对象。
  • 对已打开文件做读/写操作:读取文件内容可使用 read( )、readline( ) 以及 readlines( ) 函数;向文件中写入内容可以使用 write( ) 函数。
  • 关闭文件:完成对文件的读/写操作之后最后需要关闭文件可以使用 close( ) 函数。

1. 创建 / 打开文件

1.1 基本语法

open( ) 函数用于创建或打开指定文件该函数的常用语法格式下:

file = open(file_name [,mode='r' [,buffering=-1 [,encoding=None] ] ])

此格式中用 [ ] 括起来的部分为可选参数。其中常用参数所代表的含义如下:

  • file:表示要创建的文件对象。
  • file_name:要创建或打开文件的文件名称该名称要用引(单引号或双引号都可以)括起来。
  • mode:可选参数用于指定文件的打开模式,如果不写则默认以只读(r)模式打开文件。
  • encoding:手动设定打开文件时所使用的编码格式不同平台的 ecoding 参数值也不同以 Windows 为例,其默认为 cp936(实际上就是 GBK 编码)。

open 函数支持的文件打开模式:

在这里插入图片描述

1.2 上下文管理器

有时候我们 open 完文件后,可能会忘记关闭文件。而在 Python 中,使用 with as 语句可以操作上下文管理器(context manager),它能够帮助我们自动分配并且释放资源。

with as 语句的基本语法格式为:

with 表达式 [as target]:
    代码块

此格式中,用 [ ] 括起来的部分可以使用,也可以省略。其中,target 参数用于指定一个变量,该语句会将 expression 指定的结果保存到该变量中。

with open('open_file.txt', 'r') as f:
    print(f.read())

2. 读取文件

Python 提供了如下 3 种函数,它们都可以帮我们实现读取文件中数据的操作:

  • read( ) 函数:逐个字节或者字符读取文件中的内容
  • readline( ) 函数:逐行读取文件中的内容
  • readlines( ) 函数:一次性读取文件中多行内容

3.1 read( ) 函数

read( ) 函数的基本语法格式如下:

file.read([size])

其中,file 表示已打开的文件对象;size 作为一个可选参数,用于指定一次最多可读取的字符(字节)个数,如果省略,则默认一次性读取所有内容。

示例 1:读取文本

# open_file.txt
hello world1
hello world2
hello world3

# test.py - 读取1
f = open("open_file.txt", 'r')
print(f.read())     # 不指定字节数则默认全部读取出来
f.close()

# test.py - 读取2
f = open("open_file.txt", 'r')
print(f.read(5))     # hello
print(f.read(5))     #  worl
f.close()

示例 2:读取图片

# 以二进制形式打开指定文件
f = open("pic.png", 'rb')
print(f.read())    # 会输出字节流形式的数据

示例 3:rstrip 消除

我们还可以将 open 的文件或 read 读取到的数据赋值给一个变量,然后通过这个变量进行操作。

f = open("open_file.txt", 'r')
contents = f.read()
print(contents.rstrip())   #rstrip()用于消除原始结果后会空出的一行
f.close()

read( ) 函数抛出 UnicodeDecodeError 异常的解决方法

在使用 read( ) 函数时,如果 Python 解释器提示 UnicodeDecodeeError 异常或者显示为乱码,其原因在于目标文件使用的编码格式和 open( ) 函数打开该文件时使用的编码格式不匹配。

例如现在我有一段脚本用来获取并打印 ping www.baidu.com 返回的数据信息。

import subprocess

if __name__ == '__main__':
    shell_cmd = 'ping www.baidu.com'
    p = subprocess.Popen(shell_cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while p.poll() is None:
        line = p.stdout.readline()
        line = line.strip()
        if line:
            print(line)
    if p.returncode == 0:
        print('Subprogram success')
    else:
        print('Subprogram failed')

我们在 cmd 中 ping 这个网址,就会返回一些数据信息:

在这里插入图片描述

但是我们运行上面的脚本打印出来的信息确实一些字节流,看不懂什么意思。

在这里插入图片描述

这就需要我们对返回的数据进行解码操作,我先尝试用 utf-8 进行解码。

import subprocess

if __name__ == '__main__':
    shell_cmd = 'ping www.baidu.com'
    p = subprocess.Popen(shell_cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while p.poll() is None:
        line = p.stdout.readline()
        line = line.strip()
        if line:
            line = line.decode('utf-8')
            print(line)
    if p.returncode == 0:
        print('Subprogram success')
    else:
        print('Subprogram failed')

却发现运行时返回了 UnicodeDecodeeError 的异常。

在这里插入图片描述

这是因为返回的数据格式不是 utf-8,即编码格式不匹配。因此,我们可以使用 chardet 库中的 detect 检测函数来检测返回的数据的编码格式是什么。

import subprocess
import chardet

if __name__ == '__main__':
    shell_cmd = 'ping www.baidu.com'
    p = subprocess.Popen(shell_cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while p.poll() is None:
        line = p.stdout.readline()
        line = line.strip()
        if line:
            print(chardet.detect(line))
            print(line)
    if p.returncode == 0:
        print('Subprogram success')
    else:
        print('Subprogram failed')

这时候我们就可以获取到返回数据的编码格式,即为 GB2312 格式。

在这里插入图片描述

因此,我们在解码的时候指定用 GB2312 格式即可返回解码成功后的数据。

import subprocess

if __name__ == '__main__':
    shell_cmd = 'ping www.baidu.com'
    p = subprocess.Popen(shell_cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while p.poll() is None:
        line = p.stdout.readline()
        line = line.strip()
        if line:
            line = line.decode('GB2312')
            print(line)
    if p.returncode == 0:
        print('Subprogram success')
    else:
        print('Subprogram failed')

在这里插入图片描述

2.2 readline( ) 函数

readline( ) 函数用于读取文件中的一行,包含最后的换行符 “\n”。此函数的基本语法格式为:

file.readline([size])

其中,file 为打开的文件对象;size 为可选参数,用于指定读取每一行时,一次最多读取的字符(字节)数。

f = open("open_file.txt")
print(f.readline())
print(f.readline())
f.close()

在这里插入图片描述

如果不想打印出空行,则可以在后面通过 end 指定结尾不是换行符。

f = open("open_file.txt")
print(f.readline(), end='')
print(f.readline(), end='')
f.close()

在这里插入图片描述

注意 readline 中传入的参数不是指定读取的行数,而是字节数。

f = open("open_file.txt")
print(f.readline(3), end='')    # hel
f.close()

另外,我们也可以通过 for 循环遍历获取文件中的每行数据。

filename = 'open_file.txt'
f = open(filename)
for line in f:
    print(line.rstrip())    #rstrip()可以消除原始结果每行后的空白行
f.close()

2.3 readlines( ) 函数

readlines( ) 函数用于读取文件中的所有行,它和调用不指定 size 参数的 read( ) 函数类似,只不过该函数返回是一个字符串列表,其中每个元素为文件中的一行内容。

readlines( ) 函数的基本语法格式如下:

file.readlines()

其中,file 为打开的文件对象。和 read( )、readline( ) 函数一样,它要求打开文件的模式必须为可读模式(包括 r、rb、r+、rb+ 4 种)。

f = open("open_file.txt")
print(f.readlines())    # ['hello world1\n', 'hello world2\n', 'hello world3']
f.close()

2.4 读取大文件

Python 读取文件一般是利用 open( ) 函数以及 read( ) 函数来完成,但该方式仅适合读取小文件。因为调用 read( ) 会一次性读取文件的全部内容,调用 readlines( ) 一次读取所有内容并按行返回 list。如果文件过大,如 10G,会造成 MemoryError 内存溢出,正确的做法:可以反复调用 read(size) 方法,每次指定读取 size 个字节的内容。

处理大文件核心思路: 通过参数指定每次读取的大小长度,这样就避免了因为文件太大读取出问题。

while True:
    block = f.read(1024)
    if not block:
        break

2.5 fileinput 模块

Python 提供了 fileinput 模块,通过该模块中的 input( ) 函数,我们能同时打开指定的多个文件,还可以逐个读取这些文件中的内容。

fileinput 模块中 input( ) 该函数的语法格式如下:

fileinput.input (files="filename1, filename2, ...", inplace=Faise, backup=", bufsize=0, mode='r', openhook=None)

其中,各个参数的含义如下:

  • files:多个文件的路径列表。
  • inplace:用于指定是否将标准输出的结果写回到文件,此参数默认值为 False。
  • backup:用于指定备份文件的扩展名。
  • bufsize:指定缓冲区的大小,默认为 0。
  • mode:打开文件的格式,默认为 r(只读格式)。
  • openhook:控制文件的打开方式,例如编码格式等。
import fileinput

# 常规读取当个文件
for line in fileinput.input('open_file.txt'):
    print(line, end='')

# 读取多个文件 - 先读取完test01.txt再读取test02.txt
for line in fileinput.input(files=('test01.txt', 'test02.txt')):
    print(line, end='')

如果我们对文件进行修改,例如下面将 open_file.txt 里的数据转换为大写字母,则可以通过 backup 参数对文件进行备份。下面在修改完 open_file.txt 里面的数据后,也会同时生成一个 open_file.txt.bak 的文件,存储修改之前的数据,避免一些误操作导致文件被破坏。

import fileinput

# 对文件进行处理并进行备份,并且转换为大写
for line in fileinput.input('open_file.txt', backup='.bak', inplace=True):
    print(line.upper(), end='')

2.6 linecache 模块

除了可以借助 fileinput 模块实现读取多个文件外,Python 还提供了 linecache 模块。和前者不同,linecache 模块擅长读取指定文件中的指定行。

换句话说,如果我们想读取某个文件中指定行包含的数据,就可以使用 linecache 模块。

import linecache
import string

# 读取string模块中第3行的数据
print(linecache.getline(string.__file__,3), end='')     # Public module variables:

# 读取普通文件open_file.txt文件中第2行的数据
print(linecache.getline('open_file.txt', 2), end='')    # HELLO WORLD2

3. 写文件

我们再回顾一下上面的内容,调用 open( ) 时提供两个实参,第一个是要打开的文件的名称,第二个则是告诉 Python 进行的模式,常见模式为读取模式(‘r’)、写入模式(‘w’ )、附加模式(‘a’)或读写模式(‘r+’)。如果省略了模式实参,Python 将以默认的只读模式打开文件。

Tips:
写入模式会再返回文件对象前清空该文件的内容,如果想在文件后直接添加内容而不是覆盖原有的内容,可以以附加模式打开文件。

3.1 write( ) 函数

Python 中的文件对象提供了 write( ) 函数,可以向文件中写入指定内容。

该函数的语法格式如下:

file.write(string)

其中:

  • file 表示已经打开的文件对象
  • string 表示要写入的字符串
f = open("test01.txt", 'w')
f.write("hello world1\n")
f.write("hello world2\n")
f.write("hello world3\n")
f.close()

3.2 writelines( ) 函数

Python 的文件对象中,不仅提供了 write( ) 函数,还提供了 writeliines( ) 函数,可以实现将字符串列表写入文件中。一般配合着 readlines( ) 函数使用,可以快速的将文件中的数据复制到其它文件中。

f_r = open("test01.txt", 'r')
list1 = f_r.readlines()

f_w = open("test02.txt", 'w')
f_w.writelines(list1)

Tips:
Python 只能将字符串写入文本文件,如果要将数值数据存储到文本文件中,必须先使用函数 str( ) 将其转换为字符串格式。

3.3 json.dump( ) 和 json.load( )

  1. json.dump( )

在 Python 中,json.dump() 函数用于将数据对象序列化为 JSON 格式并将其写入文件。例如,下面我们可以将 numbers 列表存储于 numbers.json 文件中。

import json
numbers = [2,3,5,7,11,13]
filename = 'numbers.json'
with open(filename, 'w') as f:
    json.dump(numbers, f)
  1. json.load( )

json.load() 函数则用于从文件中读取 JSON 格式的数据并将其反序列化为 Python 对象。例如,下面我又将刚才存入 numbers.json 中的数据读取出来。

import json
filename = 'numbers.json'
with open(filename) as f:
    numbers = json.load(f)
print(numbers)

4. 文件指针

实现对文件指针的移动,文件对象提供了 tell( ) 函数和 seek( ) 函数。tell( ) 函数用于判断文件指针当前所处的位置,而 seek( ) 函数用于移动文件指针到文件的指定位置。

在这里插入图片描述

  1. tell( ) 函数

由于 read 函数每次调用完后,文件的指针会停留在当前读取完的数据的位置,下次再次读取时会从上次读取完的位置继续读取。而通过 tell( ) 函数可以判断当前指针处于哪个位置,tell( ) 函数的用法很简单,其基本语法格式如下:

file.tell()

现在我通过 read 函数分别读取 1 个字节以及 2 个字节的数据,然后调用 tell 函数可以发现当前文件的指针停留在了第 3 个字节的位置。

f = open('open_file.txt', 'r')
print(f.read(1))
print(f.read(2))
print(f.tell())  # 判断文件指针的位置

在这里插入图片描述

  1. seek( ) 函数

上面可知,文件读取完后指针不会重置,因此下次想从头或者其它位置开始读取,则可以使用 seek( ) 函数将文件指针移动至指定位置,该函数的语法格式如下:

file.seek(offset[, whence])

接着上面的案例,我们可以通过 seek 函数将函数指针移至开头的位置,这样下次读取时又会从头开始读取。

f = open('open_file.txt', 'r')
print(f.read(1))
print(f.read(2))
print(f.tell())  # 判断文件指针的位置
f.seek(0)
print(f.read(1))

在这里插入图片描述


http://www.kler.cn/a/414497.html

相关文章:

  • 智慧防汛平台在城市生命线安全建设中的应用
  • 深入理解 JavaScript 中的 AbortController
  • Web前端学习_CSS盒子模型
  • Cypress内存溢出奔溃问题汇总
  • 有关物流无人机与快递配送的协同研究
  • 20241124 Typecho 视频插入插件
  • 【微服务】消息队列与微服务之微服务详解
  • 报错:java: 无法访问org.springframework.boot.SpringApplication
  • R 因子
  • 深度学习day4-模型
  • Java知识及热点面试题总结(三)
  • IOC控制反转详解
  • Vue.js 中的样式绑定:动态控制你的样式
  • MAC 怎么终端怎么退出和进入Anaconda环境
  • React的基本知识:useEffect
  • 24/11/24 视觉笔记 滤镜
  • 如何评估爬虫获取的数据质量?
  • 扫雷-完整源码(C语言实现)
  • Excel中根据某列内容拆分为工作簿
  • Spring |(八)AOP配置管理
  • CA系统(file.h---申请认证的处理)
  • 图论2图的应用补充
  • 中信建投张青:从金融巨擘到公益大使的蜕变之旅
  • 08、Spring 集成MyBatis3.5
  • 【Linux】linux下一切皆文件 | 重定向 | 缓冲区与缓冲区
  • 软件测试面试之数据库部分