I/O即输入/输出(Input/Output),是计算机系统中非常重要的概念,用于实现计算机与外部世界的数据交互。以下从硬件和软件两个角度为你详细介绍:
open()
函数可以打开一个文件进行读取或写入操作,通过网络编程相关的库可以实现网络数据的收发。I/O在计算机系统中起着桥梁的作用,它使得计算机能够与外部世界进行有效的数据交互和通信,无论是用户与计算机的交互,还是计算机与其他设备或系统之间的数据传输,都离不开I/O的支持。
Python对文本文件和二进制文件采用统一步骤。首先用open()
函数打开一个文件,然后返回一个文件。
使用内置函数open()
可以打开文件,如果指定文件不存在就会创造一个文件,语法格式如下:
fileObj=open(fileName , mode='r' , buffering=-1 , encoding =None ,errors=None , newline=None , closefd=True , opener=None )
在 Python 中,open()
函数用于打开一个文件,并返回一个文件对象。下面详细解释 open()
函数中各个参数的含义:
fileName
# 相对路径
fileObj = open('test.txt', 'r')
# 绝对路径(以 Windows 系统为例)
fileObj = open('C:\\Users\\username\\Documents\\test.txt', 'r')
mode
'r'
(只读模式)。常见的模式有:
'r'
:只读模式,用于读取文件内容。如果文件不存在,会抛出 FileNotFoundError
异常。'w'
:写入模式,用于创建一个新文件并写入内容。如果文件已存在,会先清空文件内容;如果文件不存在,则创建一个新文件。'a'
:追加模式,用于在文件末尾追加内容。如果文件不存在,则创建一个新文件。'x'
:独占创建模式,用于创建一个新文件。如果文件已存在,会抛出 FileExistsError
异常。'b'
:二进制模式,可以与上述模式组合使用,如 'rb'
表示以二进制只读模式打开文件。't'
:文本模式(默认),也可以与其他模式组合,如 'rt'
等同于 'r'
。'+'
:读写模式,可以与其他模式组合,如 'r+'
表示以读写模式打开文件。# 以写入模式打开文件
fileObj = open('test.txt', 'w')
# 以二进制只读模式打开文件
fileObj = open('test.bin', 'rb')
buffering
-1
。
-1
:使用系统默认的缓冲策略。对于二进制文件,通常是全缓冲;对于交互式文本文件,通常是行缓冲。0
:无缓冲,数据会立即写入文件。仅适用于二进制模式。1
:行缓冲,数据会在遇到换行符时写入文件。仅适用于文本模式。# 无缓冲模式(二进制文件)
fileObj = open('test.bin', 'wb', buffering=0)
encoding
None
。当使用文本模式打开文件时,需要指定正确的编码格式,否则可能会出现乱码。常见的编码格式有 'utf-8'
、'gbk'
等。# 以 UTF-8 编码打开文件
fileObj = open('test.txt', 'r', encoding='utf-8')
errors
None
。常见的处理方式有:
'strict'
:遇到错误时抛出 UnicodeDecodeError
或 UnicodeEncodeError
异常。'ignore'
:忽略错误,直接跳过无法解码的字符。'replace'
:用 ?
替换无法解码的字符。# 忽略编码错误
fileObj = open('test.txt', 'r', encoding='utf-8', errors='ignore')
newline
None
,表示使用系统默认的换行符(Windows 为 \r\n
,Unix/Linux 为 \n
)。
''
:不转换换行符。'\n'
:将所有换行符转换为 \n
。'\r'
:将所有换行符转换为 \r
。'\r\n'
:将所有换行符转换为 \r\n
。# 不转换换行符
fileObj = open('test.txt', 'r', newline='')
closefd
True
。如果 closefd
为 True
,当文件对象关闭时,底层的文件描述符也会被关闭;如果为 False
,则不会关闭底层的文件描述符。import os
fd = os.open('test.txt', os.O_RDONLY)
# 关闭文件对象时不关闭底层文件描述符
fileObj = open(fd, 'r', closefd=False)
opener
None
,表示使用系统默认的打开方式。import os
def custom_opener(path, flags):
return os.open(path, flags | os.O_RDONLY)
fileObj = open('test.txt', 'r', opener=custom_opener)
以上就是 open()
函数各个参数的详细解释。在实际使用时,根据具体需求选择合适的参数。
出于安全考虑,建议以下两种打开文件的方法:
try
语句块中调用open()
函数,在except
语句块中妥善处理文件操作异常,在finally
语句中关闭打开的文件。fileName='test.txt'
try:
fp=open(fileName,"w+")
print("%s文件创建成功"%fileName)
except IOError:
print("文件创建失败,%s文件不存在"%fileName)
finally:
fp.close()
with
语句是一种上下文管理协议,也是文件操作的通用结构。它能够简化try...except...finally
异常处理机制的流程。使用with
语句打开文件的语法格式如下:with open(文件)as file 对象:
操作file对象
使用file
对象的readline()
、readlines()
、read()
方法可以读取文件的内容。简单说明如下:
file.read(size=-1)
:从文件中读取整个文件内容。参数可选,如果给出,读取该行前size
长度的字符串或字节流。file.readline(size=-1)
:从文件中读取一行内容,包含换行符。参数可选,如果给出,读取该行前size长度的字符串或字节流。file.readlines(hint=-1)
:从文件中读取所有行,以每行为元素形成一个列表。参数可选,如果给出,读取hint
行。file.seek(offset[,whence])
改变当前文件操作指针的位置。file.read(size=-1)
此方法用于从文件中读取内容。
size
:可选参数,默认值为 -1。若指定了 size
,则读取文件中前 size
个字符(文本模式)或字节(二进制模式);若不指定或指定为 -1,则读取整个文件内容。# 以文本模式打开文件
with open('test.txt', 'r', encoding='utf-8') as file:
# 读取整个文件内容
content = file.read()
print(content)
# 重新打开文件
with open('test.txt', 'r', encoding='utf-8') as file:
# 读取前 10 个字符
partial_content = file.read(10)
print(partial_content)
file.readline(size=-1)
该方法用于从文件中读取一行内容,包括换行符。
size
:可选参数,默认值为 -1。若指定了 size
,则读取该行前 size
个字符(文本模式)或字节(二进制模式);若不指定或指定为 -1,则读取整行内容。with open('test.txt', 'r', encoding='utf-8') as file:
# 读取第一行
first_line = file.readline()
print(first_line)
# 再次读取一行,只读取前 5 个字符
partial_line = file.readline(5)
print(partial_line)
file.readlines(hint=-1)
此方法用于读取文件的所有行,并将每行内容作为一个元素存储在列表中。
hint
:可选参数,默认值为 -1。若指定了 hint
,则尝试读取 hint
行;若不指定或指定为 -1,则读取文件的所有行。with open('test.txt', 'r', encoding='utf-8') as file:
# 读取所有行
all_lines = file.readlines()
print(all_lines)
# 重新打开文件
with open('test.txt', 'r', encoding='utf-8') as file:
# 读取前 2 行
some_lines = file.readlines(2)
print(some_lines)
file.seek(offset[, whence])
该方法用于改变当前文件操作指针的位置。
offset
:表示要移动的字节数。正数表示向文件末尾方向移动,负数表示向文件开头方向移动。whence
:可选参数,指定参考位置,默认值为 0,具体取值如下:
# 以二进制模式打开文件
with open('test.txt', 'rb') as file:
# 移动指针到文件第 5 个字节处
file.seek(5, 0)
# 从第 5 个字节处开始读取内容
content = file.read()
print(content)
# 移动指针到当前位置向后 3 个字节处
file.seek(3, 1)
content = file.read()
print(content)
# 移动指针到文件末尾前 10 个字节处
file.seek(-10, 2)
content = file.read()
print(content)
使用文件对象的write()
和writelines()
方法可以为文件写入内容。简单说明如下:
writelines()
方法不会换行写入,如果需要换行,要手动加入换行符号\n
。write()
和 writelines()
方法的使用,同时给出相应的示例代码,帮助你更好地理解如何使用它们向文件中写入内容。f.write(s)
# 以文本写入模式打开文件
with open('example.txt', 'w', encoding='utf-8') as f:
# 写入一个字符串
text = "Hello, World!"
written_length = f.write(text)
print(f"写入的字符长度: {written_length}")
在上述代码中,我们以写入模式打开了一个名为 example.txt
的文件,然后使用 write()
方法向文件中写入了字符串 "Hello, World!"
,最后打印出实际写入的字符长度。
f.writelines(lines)
\n
。# 以文本写入模式打开文件
with open('example.txt', 'w', encoding='utf-8') as f:
# 定义一个字符串列表
lines = ["Line 1", "Line 2", "Line 3"]
# 手动添加换行符
lines_with_newline = [line + '\n' for line in lines]
# 写入列表内容
f.writelines(lines_with_newline)
在上述代码中,我们首先定义了一个字符串列表 lines
,然后使用列表推导式为每个元素添加了换行符,最后使用 writelines()
方法将处理后的列表写入文件。
# 使用 write() 方法逐行写入
with open('write_example.txt', 'w', encoding='utf-8') as f:
f.write("This is the first line.\n")
f.write("This is the second line.\n")
# 使用 writelines() 方法写入
lines = ["This is the third line.\n", "This is the fourth line.\n"]
with open('writelines_example.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
这个示例展示了分别使用 write()
和 writelines()
方法向不同文件中写入内容的过程,你可以根据实际需求选择合适的方法。
write()
和 writelines()
方法时,要确保以写入模式(如 'w'
、'wb'
等)打开文件。'a'
、'ab'
等)打开文件。删除文件需要用到os
模块,调用os.remove()
方法删除指定文件。
import os
f="test.txt"
if os.path.exists(f):
os.remove(f)
print("%s文件删除成功"%f)
else:
print("%s文件不存在"%f)
在 Python 中复制文件可以有多种实现方式,下面为你详细介绍几种常见的方法。
read()
和 write()
方法逐块复制这种方法是通过读取源文件的内容,然后将其写入目标文件。为了避免一次性读取大文件占用过多内存,我们可以采用逐块读取和写入的方式。
def copy_file(source_path, destination_path, chunk_size=1024):
try:
# 以二进制读取模式打开源文件
with open(source_path, 'rb') as source_file:
# 以二进制写入模式打开目标文件
with open(destination_path, 'wb') as destination_file:
while True:
# 逐块读取源文件内容
chunk = source_file.read(chunk_size)
if not chunk:
break
# 将读取的块写入目标文件
destination_file.write(chunk)
print(f"文件 {source_path} 复制到 {destination_path} 成功。")
except FileNotFoundError:
print(f"源文件 {source_path} 未找到。")
except Exception as e:
print(f"复制文件时出现错误: {e}")
# 使用示例
source_file = 'source.txt'
destination_file = 'destination.txt'
copy_file(source_file, destination_file)
copy_file
函数接受源文件路径、目标文件路径和可选的块大小作为参数。with
语句以二进制读取模式打开源文件,以二进制写入模式打开目标文件。while
循环逐块读取源文件内容,直到读取到文件末尾(即 chunk
为空)。每次读取的块大小由 chunk_size
参数指定。FileNotFoundError
异常(源文件未找到)和其他异常,并打印相应的错误信息。shutil
模块shutil
是 Python 标准库中的一个模块,提供了许多高级的文件和目录操作功能,其中 copy2()
函数可以方便地复制文件,并且会尽可能保留文件的元数据(如文件权限、创建时间等)。
import shutil
def copy_file_with_shutil(source_path, destination_path):
try:
# 使用 shutil.copy2 复制文件
shutil.copy2(source_path, destination_path)
print(f"文件 {source_path} 复制到 {destination_path} 成功。")
except FileNotFoundError:
print(f"源文件 {source_path} 未找到。")
except Exception as e:
print(f"复制文件时出现错误: {e}")
# 使用示例
source_file = 'source.txt'
destination_file = 'destination.txt'
copy_file_with_shutil(source_file, destination_file)
shutil
模块。copy_file_with_shutil
函数接受源文件路径和目标文件路径作为参数。shutil.copy2()
函数复制文件。FileNotFoundError
异常和其他异常,并打印相应的错误信息。这两种方法各有优缺点,使用 read()
和 write()
方法可以更灵活地控制复制过程,而使用 shutil
模块则更加简洁方便,并且能保留文件的元数据。你可以根据实际需求选择合适的方法。
使用os
模块的rename()
方法可以对为文件或目录进行命名。
os.rename(src, dst)
** 参数说明 **
src:代表当前文件或目录的路径,是重命名前的完整路径。
dst:表示新的文件或目录的路径,是重命名后的完整路径。
在 Python 中进行文件内容的搜索和替换可以通过多种方式实现,下面分别介绍在单个文件和多个文件中进行搜索和替换的方法。
def search_and_replace_in_file(file_path, search_text, replace_text):
try:
# 读取文件内容
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# 进行搜索和替换
new_content = content.replace(search_text, replace_text)
# 将替换后的内容写回文件
with open(file_path, 'w', encoding='utf-8') as file:
file.write(new_content)
print(f"在文件 {file_path} 中,将 '{search_text}' 替换为 '{replace_text}' 成功。")
except FileNotFoundError:
print(f"文件 {file_path} 未找到。")
except Exception as e:
print(f"处理文件时出现错误: {e}")
# 使用示例
file_path = 'test.txt'
search_text = 'apple'
replace_text = 'banana'
search_and_replace_in_file(file_path, search_text, replace_text)
content
中。replace()
方法将 search_text
替换为 replace_text
,得到新的内容 new_content
。new_content
写回文件。import os
def search_and_replace_in_files(directory, search_text, replace_text):
for root, dirs, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
try:
# 读取文件内容
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 进行搜索和替换
new_content = content.replace(search_text, replace_text)
# 将替换后的内容写回文件
with open(file_path, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f"在文件 {file_path} 中,将 '{search_text}' 替换为 '{replace_text}' 成功。")
except FileNotFoundError:
print(f"文件 {file_path} 未找到。")
except Exception as e:
print(f"处理文件 {file_path} 时出现错误: {e}")
# 使用示例
directory = '.' # 当前目录
search_text = 'apple'
replace_text = 'banana'
search_and_replace_in_files(directory, search_text, replace_text)
os.walk()
函数遍历指定目录下的所有文件和子目录。re
模块进行正则表达式替换。例如:import re
def regex_search_and_replace_in_file(file_path, pattern, replace_text):
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
new_content = re.sub(pattern, replace_text, content)
with open(file_path, 'w', encoding='utf-8') as file:
file.write(new_content)
print(f"在文件 {file_path} 中,根据正则表达式 '{pattern}' 进行替换成功。")
except FileNotFoundError:
print(f"文件 {file_path} 未找到。")
except Exception as e:
print(f"处理文件时出现错误: {e}")
# 使用示例
file_path = 'test.txt'
pattern = r'apple\d+'
replace_text = 'banana'
regex_search_and_replace_in_file(file_path, pattern, replace_text)
这个示例使用正则表达式 r'apple\d+'
匹配以 apple
开头后面跟数字的字符串,并将其替换为 banana
。
os.path
提供的abpath()
获取绝对路径。os.path.abpath(path)
import os
print(os.getcwd())
相对路径就是依赖当前的工作目录,如果在当前工作目录下有一个叫“meassage.txt”的文件,那么打开这个文件的时候,就可以直接写下文件名,这时采用就是系相对路径。
os.path,join(path1,path2,...)
os.path.exists(path)
path可以选绝对也可选相对。
import os
# 创建单个目录
directory = 'new_directory'
if not os.path.exists(directory):
os.mkdir(directory)
print(f"目录 {directory} 创建成功。")
else:
print(f"目录 {directory} 已存在。")
# 创建多级目录
nested_directory = 'parent_dir/child_dir'
if not os.path.exists(nested_directory):
os.makedirs(nested_directory)
print(f"多级目录 {nested_directory} 创建成功。")
else:
print(f"多级目录 {nested_directory} 已存在。")
在 Python 里,os.mkdir()
是 os
模块提供的一个用于创建目录的函数。下面从基本语法、参数、使用示例、异常情况和与其他方法对比几个方面详细介绍它。
os.mkdir(path, mode=0o777, *, dir_fd=None)
path
:必需参数,指定要创建的目录的路径。可以是绝对路径,也可以是相对路径。mode
:可选参数,用于指定新目录的权限模式,默认值是 0o777
(表示所有用户都有读、写、执行权限)。这个参数在不同操作系统上的作用可能会有所不同,并且在 Windows 系统中通常会被忽略。dir_fd
:可选参数,是一个文件描述符。如果指定了 dir_fd
,path
会被解释为相对于该文件描述符所引用的目录。这是一个比较高级的用法,一般情况下不需要使用。os.makedirs()
对比os.mkdir()
:只能创建单层目录,如果父目录不存在则会抛出 FileNotFoundError
异常。os.makedirs()
:可以递归创建多级目录。例如,要创建 parent_dir/child_dir
,如果 parent_dir
不存在,os.makedirs()
会先创建 parent_dir
,再在其中创建 child_dir
。示例代码如下:import os
# 定义要创建的多级目录路径
nested_dir_path = 'parent_dir/child_dir'
try:
# 创建多级目录
os.makedirs(nested_dir_path)
print(f"多级目录 {nested_dir_path} 创建成功。")
except FileExistsError:
print(f"多级目录 {nested_dir_path} 已存在。")
except PermissionError:
print("没有足够的权限创建多级目录。")
except Exception as e:
print(f"创建多级目录时出现未知错误: {e}")
综上所述,当你需要创建单个目录且确保父目录已经存在时,可以使用 os.mkdir()
;当需要创建多级目录时,使用 os.makedirs()
会更加方便。
import os
os.rmdir(path)
os.walk(top,topdown=True,onerror=None,followlinks=Fales)
参数说明
top
:必需参数,是一个字符串,表示要遍历的根目录的路径。可以是绝对路径或相对路径。例如,若你想遍历当前目录下的所有内容,可以传入 .
。topdown
:可选参数,是一个布尔值,默认值为 True
。
topdown=True
时,函数会先遍历根目录(top
指定的目录),然后递归遍历其子目录。也就是说,会先处理根目录下的文件和文件夹,再依次深入子目录进行处理。topdown=False
时,函数会先递归遍历子目录,最后再处理根目录。onerror
:可选参数,是一个回调函数,默认值为 None
。当遍历过程中出现错误(如权限不足无法访问某个目录)时,会调用这个回调函数。该回调函数应接受一个 OSError
类型的参数。followlinks
:可选参数,是一个布尔值,默认值为 False
。
followlinks=False
时,函数不会跟随符号链接(软链接)进入链接指向的目录。followlinks=True
时,函数会跟随符号链接进入链接指向的目录进行遍历。返回值
os.walk()
是一个生成器函数,每次迭代会返回一个三元组 (root, dirs, files)
:
root
:是一个字符串,表示当前正在遍历的目录的路径。dirs
:是一个列表,包含当前目录下的所有子目录的名称(不包含路径)。files
:是一个列表,包含当前目录下的所有文件的名称(不包含路径)。