脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - Python文件操作:高效处理文件的技巧

Python文件操作:高效处理文件的技巧

2023-12-01 16:01python学习之旅 Python

本文将带领读者深入探索文件操作的世界,并分享实用的技巧和工具。通过掌握这些技能,您将能够更加轻松地管理和处理文件,提高工作效率和数据处理能力。

文件操作是日常工作中不可或缺的一部分。无论是读取、写入、拷贝还是移动文件,都需要高效的文件操作技巧。本文将带领读者深入探索文件操作的世界,并分享实用的技巧和工具。通过掌握这些技能,您将能够更加轻松地管理和处理文件,提高工作效率和数据处理能力。

Python文件操作:高效处理文件的技巧

一、文件读写操作

在学习文件操作之前,先来回顾一下编码的相关以及数据类型的知识。

  • 字符串类型(str),在程序中用于表示文字信息,本质上是unicode编码中的二进制。
name = "lisa"
  • 字节类型(bytes),可表示文字信息,本质上是utf-8/gbk等编码的二进制(对unicode进行压缩,方便文件存储和网络传输。)
name = "lisa"
data = name.encode('utf-8')
print(data) # b'\xe6\xad\xa6\xe6\xb2\x9b\xe9\xbd\x90'

result = data.decode('utf-8')
print(result) # "lisa"

可表示原始二进制(图片、文件等信息)

1. 读文件

读文本文件:

# 1.打开文件
file_object = open('info.txt', mode='rb')
# 2.读取文件内容,并赋值给data
data = file_object.read()
# 3.关闭文件
file_object.close()

print(data) # b'jack-123\n\xe6\xad\xa6\xe6\xb2\x9b\xe9\xbd\x90-123'
text = data.decode("utf-8")
print(text)

# 1.打开文件
file_object = open('info.txt', mode='rt', encoding='utf-8')

# 2.读取文件内容,并赋值给data
data = file_object.read()

# 3.关闭文件
file_object.close()

print(data) # "lisa"

读图片等非文本内容文件:

file_object = open('a1.png', mode='rb')
data = file_object.read()
file_object.close()

print(data) # \x91\xf6\xf2\x83\x8aQFfv\x8b7\xcc\xed\xc3}\x7fT\x9d{.3.\xf1{\xe8\...

注意文件路径操作:

  • 相对路径,你的程序到底在哪里运行的?
  • 绝对路径
# 1.打开文件
file_object = open('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/info.txt', mode='rt', encoding='utf-8')
# 2.读取文件内容,并赋值给data
data = file_object.read()
# 3.关闭文件
file_object.close()
    windows系统中写绝对路径容易出问题:
# file_object = open('C:\\new\\info.txt', mode='rt', encoding='utf-8')

file_object = open(r'C:\new\info.txt', mode='rt', encoding='utf-8')
data = file_object.read()
file_object.close()
print(data)

读文件时,文件不存在程序会报错:

Traceback (most recent call last):
  File "/Users/wupeiqi/PycharmProjects/luffyCourse/day09/2.读文件.py", line 2, in 
    file_object = open('infower.txt', mode='rt', encoding='utf-8')
FileNotFoundError: [Errno 2] No such file or directory: 'infower.txt'
# 判断路径是否存在?
import os

file_path = "/Users/wupeiqi/PycharmProjects/luffyCourse/day09/info.txt"
exists = os.path.exists(file_path)
if exists:
    # 1.打开文件
    file_object = open('infower.txt', mode='rt', encoding='utf-8')
    # 2.读取文件内容,并赋值给data
    data = file_object.read()
    # 3.关闭文件
    file_object.close()
    print(data)
else:
    print("文件不存在")

2. 写文件

写文本文件:

# 1.打开文件
# 路径:t1.txt
# 模式:wb(要求写入的内容需要是字节类型)
file_object = open("t1.txt", mode='wb')

# 2.写入内容
file_object.write(    "lisa".encode("utf-8")    )

# 3.文件关闭
file_object.close()
file_object = open("t1.txt", mode='wt', encoding='utf-8')

file_object.write("lisa")

file_object.close()

写图片等文件:

f1 = open('a1.png',mode='rb')
content = f1.read()
f1.close()

f2 = open('a2.png',mode='wb')
f2.write(content)
f2.close()

小案例:利用Python向某个网址发送请求并获取结果(利用第三方的模块)。

下载第三方模块:

pip install requests

使用第三方模块:

import requests

res = requests.get(url="网址")
print(res)
# 案例1:去网上下载一点文本,文本信息写入文件。
import requests

res = requests.get(
    url="https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20",
    headers={
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
    }
)

# 网络传输的原始二进制信息(bytes)
# res.content

file_object = open('files/log1.txt', mode='wb')
file_object.write(res.content)
file_object.close()

案例2:去网上下载一张图片,图片写入本地文件。

import requests

res = requests.get(
    url="https://hbimg.huabanimg.com/c7e1461e4b15735fbe625c4dc85bd19904d96daf6de9fb-tosv1r_fw1200",
    headers={
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
    }
)

# 网络传输的原始二进制信息(bytes)
# res.content

file_object = open('files/美女.png', mode='wb')
file_object.write(res.content)
file_object.close()

注意事项:

(1)路径

  • 绝对路径
  • 相对路径

(2)文件不存在时,w模式会新建然后再写入内容;文件存在时,w模式会清空文件再写入内容。

二、文件打开模式

上文我们基于文件操作基本实现了读、写的功能,其中涉及的文件操作模式:rt、rb、wt、wb,其实在文件操作中还有其他的很多模式。

========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
'r'       open for reading (default)
'w'       open for writing, truncating the file first
'x'       create a new file and open it for writing
'a'       open for writing, appending to the end of the file if it exists

'b'       binary mode
't'       text mode (default)

'+'       open a disk file for updating (reading and writing)

The default mode is 'rt' (open for reading text).

关于文件的打开模式常见应用有:

只读:r,rt,rb

  • 存在,读
  • 不存在,报错

只写:w,wt,wb

  • 存在,清空再写
  • 不存在,创建再写

只写:a,at,ab (常用于【尾部追加】)

  • 存在,尾部追加。
  • 不存在,创建再写。

三、常见功能

在上述对文件的操作中,我们只使用了write和read来对文件进行读写,其实在文件操作中还有很多其他的功能来辅助实现更好的读写文件的内容。

read,读

读所有【常用】:

f = open('info.txt', mode='r',encoding='utf-8')
data = f.read()
f.close()
f = open('info.txt', mode='rb')
data = f.read()
f.close()
- 读n个字符(字节)【会用到】
f = open('info.txt', mode='r', encoding='utf-8')
# 读1个字符
data = f.read(1)
f.close()

print(data) # 武
f = open('info.txt', mode='r',encoding='utf-8')

# 读1个字符
chunk1 = f.read(1)
chunk2 = f.read(2)
print(chunk1,chunk2)

f.close()
f = open('info.txt', mode='rb')

# 读1个字节
data = f.read(3)
f.close()

print(data, type(data))  # b'\xe6\xad\xa6' 
f = open('info.txt', mode='rb')

# 读1个字节
chunk1 = f.read(3)
chunk2 = f.read(3)
chunk3 = f.read(1)
print(chunk1,chunk2,chunk3)

f.close()

readline,读一行:

f = open('info.txt', mode='r', encoding='utf-8')

v1 = f.readline()
print(v1)

v2 = f.readline()
print(v2)

f.close()
f = open('info.txt', mode='r', encoding='utf-8')
v1 = f.readline()
print(v1)
f.close()

f = open('info.txt', mode='r', encoding='utf-8')
v2 = f.readline()
print(v2)
f.close()

readlines,读所有行,每行作为列表的一个元素:

f = open('info.txt', mode='rb')

data_list = f.readlines()

f.close()

print(data_list)

循环,读大文件(readline加强版)【常见】:

f = open('info.txt', mode='r', encoding='utf-8')
for line in f:
    print(line.strip())
f.close()

write,写:

f = open('info.txt', mode='a',encoding='utf-8')
f.write("lisa")
f.close()
f = open('info.txt', mode='ab')
f.write( "lisa".encode("utf-8") )
f.close()

flush,刷到硬盘:

f = open('info.txt', mode='a',encoding='utf-8')

while True:
    # 不是写到了硬盘,而是写在缓冲区,系统会将缓冲区的内容刷到硬盘。
  f.write("lisa")
    f.flush()

f.close()
file_object = open('files/account.txt', mode='a')

while True:
    user = input("用户名:")
    if user.upper() == "Q":
        break
    pwd = input("密码:")
    data = "{}-{}\n".format(user, pwd)
    file_object.write(data)
    file_object.flush()

file_object.close()

移动光标位置(字节):

f = open('info.txt', mode='r+', encoding='utf-8')

# 移动到指定字节的位置
f.seek(3)
f.write("lisa")

f.close()
注意:在a模式下,调用write在文件中写入内容时,永远只能将内容写入到尾部,不会写到光标的位置。

获取当前光标位置:

f = open('info.txt', mode='r', encoding='utf-8')

p1 = f.tell()
print(p1)  # 0

f.read(3)  # 读3个字符 3*3=9字节

p2 = f.tell()
print(p2)  # 9

f.close()
f = open('info.txt', mode='rb')

p1 = f.tell()
print(p1)  # 0

f.read(3)  # 读3个字节

p2 = f.tell()
print(p2)  # 3

f.close()

四、上下文管理

之前对文件进行操作时,每次都要打开和关闭文件,比较繁琐且容易忘记关闭文件。以后再进行文件操作时,推荐大家使用with上下文管理,它可以自动实现关闭文件。

with open("xxxx.txt", mode='rb') as file_object:
    data = file_object.read()
    print(data)

在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:

with open("xxxx.txt", mode='rb') as f1, open("xxxx.txt", mode='rb') as f2:
    pass

五、文件修改

文件操作改的流程如下所示:

  • 以读的模式打开原文件。
  • 以写的模式创建一个新文件。
  • 将原文件的内容读出来修改成新内容,写入新文件。
  • 将原文件删除。
  • 将新文件重命名成原文件。
import os
# 1, 以读的模式打开原文件。
# 2,以写的模式创建一个新文件。
with open('jack自述',encoding='utf-8') as f1,\
  open('jack自述.bak',encoding='utf-8',mode='w') as f2:
# 3,将原文件的内容读出来修改成新内容,写入新文件。
  old_content = f1.read()
  new_content = old_content.replace('jack', 'SB')
  f2.write(new_content)
os.remove('jack自述')
os.rename('jack自述.bak','jack自述')

六、面试题

文件操作,大文件如何读取内容 [ 50G的日志文件 ]:

def read_large_file(file_path, chunk_size=4096):
    with open(file_path, 'r') as file:
        while True:
            data = file.read(chunk_size)
            if not data:
                break
            yield data

# 使用示例
for chunk in read_large_file('large_log_file.log'):
    # 处理每个块的数据
    process_chunk(chunk)

在Python的文件操作中,readline()和readlines()是用于读取文件内容的两种常见方法,有什么区别?

  • readline()方法用于每次读取文件的一行内容,并将光标移动到下一行。每次调用readline(),它会返回文件中的下一行文本作为字符串。如果文件结束,readline()会返回空字符串。
  • readlines()方法则会一次性读取整个文件的所有行,并将每一行作为一个字符串存储在一个列表中。该方法返回一个包含所有行的列表。

区别:

  • 返回类型:readline()方法返回一个字符串,即一行的文本内容。readlines()方法返回一个列表,其中每个元素是一个字符串,即每行的文本内容。
  • 读取方式:readline()方法按行顺序逐个读取,每次调用读取一行。而readlines()方法一次读取整个文件,并将每行作为一个字符串保存在列表中。
  • 内存占用:readlines()方法将整个文件内容存储在内存中的列表中,可能会占用较多的内存。而readline()方法只加载一行内容,所以对内存的占用更加有限。

以下是示例代码来展示readline()和readlines()的使用:

# 使用readline()方法逐行读取文件

with open('file.txt', 'r') as file:
    line = file.readline()
    while line:
        print(line)
        line = file.readline()

# 使用readlines()方法读取所有行

with open('file.txt', 'r') as file:
    lines = file.readlines()
    for line in lines:
        print(line)

上述代码中,假设有一个名为file.txt的文本文件。

  • 第一个示例使用readline()方法逐行读取文件内容并打印,直到文件结束。
  • 第二个示例使用readlines()方法一次性读取整个文件的所有行,并使用for循环逐行打印。

需要注意的是,在以上示例中,为了演示目的,我们使用with open语句来打开文件,这样可以自动关闭文件句柄,确保文件操作的正确性和安全性。

七、文件路径和目录操作

在python中有一些专门的模块去操作文件路径与目录:

例如os模块:

1. os

首先导入:

import os

获取当前脚本绝对路径:

import os

abs_path = os.path.abspath(__file__)
print(abs_path)

获取当前文件的上级目录:

import os

base_path = os.path.dirname( os.path.dirname(路径) )
print(base_path)

路径拼接:

import os

p1 = os.path.join(base_path, 'xx')
print(p1)

p2 = os.path.join(base_path, 'xx', 'oo', 'a1.png')
print(p2)

判断路径是否存在:

import os

exists = os.path.exists(p1)
print(exists)

-创建文件夹:

import os

os.makedirs(路径)

path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
if not os.path.exists(path):
    os.makedirs(path)

是否是文件夹:

import os

file_path = os.path.join(base_path, 'xx', 'oo', 'uuuu.png')
is_dir = os.path.isdir(file_path)
print(is_dir) # False

folder_path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
is_dir = os.path.isdir(folder_path)
print(is_dir) # True

删除文件或文件夹:

os.remove("文件路径")

path = os.path.join(base_path, 'xx')
shutil.rmtree(path)

除了路径操作之外,再给出一些稍微常见的函数,如下所示:

2. os.listdir

listdir,查看目录下所有的文件   查看一个目录下所有的文件【第一层】

使用Python代码实现遍历一个文件夹的操作。

import os


def print_directory_contents(sPath):
    """
    这个函数接收文件夹的名称作为输入参数
    返回该文件夹中文件的路径
    以及其包含文件夹中文件的路径
    """
    for s_child in os.listdir(sPath):
        s_child_path = os.path.join(sPath, s_child)
        if os.path.isdir(s_child_path): 
            # 如果是文件夹,走递归操作
            print_directory_contents(s_child_path)
        else:
            # 就一定是文件
            print(s_child_path)

target_path = 'xxxx'
print_directory_contents(target_path)

使用listdir求文件夹的大小:

import os
lst = [r'D:\code']
size = 0
while lst:
    path = lst.pop()
    name_lst = os.listdir(path)
    for name in name_lst:
        full_path = os.path.join(path,name)
        if os.path.isdir(full_path):
            lst.append(full_path)
        elif os.path.isfile(full_path):
            size += os.path.getsize(full_path)
print(size)

3. os.walk

Python标准库os模块的walk函数提供了遍历一个文件夹的功能,它返回一个生成器。walk,查看目录下所有的文件(含子孙文件)

import os

"""
data = os.listdir("/Users/jack/PycharmProjects/luffyCourse/day14/commons")
print(data)
# ['convert.py', '__init__.py', 'page.py', '__pycache__', 'utils.py', 'tencent']
"""

"""
要遍历一个文件夹下的所有文件,例如:遍历文件夹下的所有mp4文件
"""

data = os.walk("/Users/jack/Documents/视频教程/路飞Python/mp4")
for path, folder_list, file_list in data:
    for file_name in file_list:
        file_abs_path = os.path.join(path, file_name)
        ext = file_abs_path.rsplit(".",1)[-1]
        if ext == "mp4":
            print(file_abs_path)

使用walk来计算文件夹的总大小:

import os
g = os.walk('D:\软件')
s=0
for i in g :
    path,dir_list,name_list = i
    for j in name_list:
        s+=os.path.getsize(os.path.join(path,j))
print(f'该文件夹大小为:{s/1024**2}MB')

Python文件操作:高效处理文件的技巧

八、shutil

shutil库是Python的一个标准高级文件操作模块,它与os模块形成互补的关系。os模块主要提供了对文件或文件夹的新建、删除、查看等基本操作,还支持对文件以及目录的路径操作。然而,对于复制、移动、删除、压缩、解压等复杂操作,os模块一般不提供,这时候就需要用到shutil库了。

shutil库中包含了一些实用的函数,如copy(), move(), rmtree()等,这些函数可以帮助我们进行文件和文件夹的复制、移动和删除等操作。例如,我们可以使用shutil.copy()函数来复制文件,只需要指定源文件路径和目标文件路径即可。此外,shutil库还提供了一些其他的实用函数,如make_archive()函数,它可以帮助我们将多个文件或文件夹打包成一个归档文件。由于对比于os模块,使用的没有那么频繁,所以这里对于shutil的使用稍微简化,感兴趣可以查看官方文档。

同样的首先导入:

import shutil

删除文件夹:

path = os.path.join(base_path, 'xx')
shutil.rmtree(path)

拷贝文件夹:

shutil.copytree("/Users/jack/Desktop/图/csdn/","/Users/jack/PycharmProjects/CodeRepository/files")

拷贝文件::

shutil.copy("/Users/jack/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/jack/PycharmProjects/CodeRepository/")
shutil.copy("/Users/jack/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/jack/PycharmProjects/CodeRepository/x.png")

文件或文件夹重命名:

shutil.move("/Users/jack/PycharmProjects/CodeRepository/x.png","/Users/jack/PycharmProjects/CodeRepository/xxxx.png")
shutil.move("/Users/jack/PycharmProjects/CodeRepository/files","/Users/jack/PycharmProjects/CodeRepository/images")

文件压缩:

"""
# base_name,压缩后的压缩包文件
# format,压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir,要压缩的文件夹路径
"""
# shutil.make_archive(base_name=r'datafile',format='zip',root_dir=r'files')

解压文件:

"""
# filename,要解压的压缩包文件
# extract_dir,解压的路径
# format,压缩文件格式
"""
# shutil.unpack_archive(filename=r'datafile.zip', extract_dir=r'xxxxxx/xo', format='zip')

九、文件路径相关

在Python中进行文件操作时,路径同样非常重要。正确的路径可以确保程序能够找到需要读写的文件,并且避免覆盖或删除错误的文件。在使用Python进行文件操作时,可以使用绝对路径或相对路径来指定文件的位置。绝对路径是从根目录开始的完整路径,而相对路径则是相对于当前工作目录的路径。因此,在进行文件操作之前,必须先确定文件的路径,并使用合适的方法打开和关闭文件,以确保数据的正确读写和安全性。

1.  转义

windows路径使用的是\,linux路径使用的是/。

特别的,在windows系统中如果有这样的一个路径 D:\nxxx\txxx\x1,程序会报错。因为在路径中存在特殊符 \n(换行符)和\t(制表符),Python解释器无法自动区分。

所以,在windows中编写路径时,一般有两种方式:

  • 加转义符,例如:"D:\\nxxx\\txxx\\x1"
  • 路径前加r,例如:r"D:\\nxxx\\txxx\\x1"

2. 程序当前路径

项目中如果使用了相对路径,那么一定要注意当前所在的位置。

例如:在/Users/jack/PycharmProjects/CodeRepository/路径下编写 demo.py文件:

with open("a1.txt", mode='w', encoding='utf-8') as f:
    f.write("你好呀")

用以下两种方式去运行:

  • 方式1,文件会创建在 /Users/jack/PycharmProjects/CodeRepository/ 目录下。
cd /Users/jack/PycharmProjects/CodeRepository/
python demo.py
  • 方式2,文件会创建在 `/Users/jack`目录下。
cd /Users/jack
python /Users/jack/PycharmProjects/CodeRepository/demo.py


import os

"""
# 1.获取当前运行的py脚本所在路径
abs = os.path.abspath(__file__)
print(abs) # /Users/jack/PycharmProjects/luffyCourse/day09/20.路径相关.py
path = os.path.dirname(abs)
print(path) # /Users/jack/PycharmProjects/luffyCourse/day09
"""
base_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_dir, 'files', 'info.txt')
print(file_path)
if os.path.exists(file_path):
    file_object = open(file_path, mode='r', encoding='utf-8')
    data = file_object.read()
    file_object.close()

    print(data)
else:
    print('文件路径不存在')

总结

文件操作是每个开发者和数据处理人员必备的技能。在本文中,我们详细介绍了文件读写、路径和目录操作、文件拷贝以及文件批量处理等方面的技巧和工具。通过学习和应用这些技能,您将能够更加灵活地处理和管理文件,提高工作效率。要记住,好的文件操作习惯对于数据处理和项目管理至关重要。继续探索并不断实践,您将成为一个更加优秀的文件操作专家!

原文地址:https://mp.weixin.qq.com/s?__biz=Mzg4NzY0MDEyNg==&mid=2247484798&idx=1&sn=e31b693355fb13bc1fa0f815a5c3e48c

延伸 · 阅读

精彩推荐
  • PythonwxPython的安装与使用教程

    wxPython的安装与使用教程

    wxPython是Python语言的一套优秀的GUI图形库。wxPython可以很方便的创建完整的、功能键全的GUI用户界面。这篇文章给大家介绍了wxPython的安装与使用,感兴趣的...

    Jimmy.li9442021-03-31
  • PythonPython中的复制操作及copy模块中的浅拷贝与深拷贝方法

    Python中的复制操作及copy模块中的浅拷贝与深拷贝方法

    浅拷贝和深拷贝是Python基础学习中必须辨析的知识点,这里我们将为大家解析Python中的复制操作及copy模块中的浅拷贝与深拷贝方法:...

    cangmean5862020-08-31
  • PythonPython如何对齐字符串

    Python如何对齐字符串

    这篇文章主要介绍了Python如何对齐字符串,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...

    David Beazley9082020-07-31
  • Python使用Python下载抖音各大V视频的思路详解

    使用Python下载抖音各大V视频的思路详解

    这篇文章主要介绍了使用Python下载抖音各大V视频的思路详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以...

    松鼠爱出饼干8992021-09-03
  • PythonAnaconda环境变量的配置图文详解

    Anaconda环境变量的配置图文详解

    Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项,下面这篇文章主要给大家介绍了关于Anaconda环境变量配置的相关资料...

    可爱以南10392022-08-31
  • PythonPython管理Windows服务小脚本

    Python管理Windows服务小脚本

    这篇文章主要为大家详细介绍了Python管理Windows服务的小脚本,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    q_qqq_qqqq7702021-01-21
  • Pythonpython黑魔法之参数传递

    python黑魔法之参数传递

    这篇文章主要介绍了python黑魔法之参数传递,分析了python参数传递的方法,感兴趣的小伙伴们可以参考一下...

    icedoom2732020-08-12
  • PythonPython 和 MongoDB 其实很配

    Python 和 MongoDB 其实很配

    MongoDB 其实就是一个大大的 JSON,在 Python 的世界里 dict 也是最吃香的类型,所以,他们天生就是一对。...

    哎妈呀Bug7372021-08-31