??????? 在Python中,I/O(输入/输出)流是处理数据输入和输出的机制。它们用于从文件、网络连接、内存等源读取数据,或将数据写入到这些目标中。I/O流以字节流和字符流的形式存在。
??????? Python中的I/O流分为两个基本类型:字节流和字符流。字节流以字节为单位进行读取和写入,而字符流以字符为单位进行读取和写入。每种类型又分为输入流和输出流。
Python 中没有像 Java 中的 java.io
包一样的专用包,但 Python 提供了内置的文件 I/O 模块,以及一些标准库和第三方库,用于处理文件和数据流。
主要的文件 I/O 模块包括:
open()
函数:用于打开文件,支持不同模式(只读、只写、追加等)。
os
模块:提供了许多文件和目录操作函数,如文件的移动、删除、重命名等。
shutil
模块:提供了高级的文件操作功能,如复制文件、删除目录等。
io
模块:提供了对内存中数据流的 I/O 支持。
tempfile
模块:用于处理临时文件和目录。
gzip
和 zipfile
模块:用于处理压缩文件。
虽然 Python 没有像 Java 那样的专用 I/O 包,但它的文件 I/O 功能非常强大且易于使用。你可以根据具体需求使用这些模块来进行文件处理和数据流操作。
bytes
或 bytearray
对象来表示,可以进行二进制数据的读取和写入。file_stream = open("file.txt","rb")
print(file_stream.__str__()) #<_io.BufferedReader name='file.txt'>
data = file_stream.readline()
print(data) #b'\xe8\xb4\xbe\xe5\x8d\x93\xe7\xbe\xa4\r\n'
file_stream.close()
str
对象来表示,可以进行文本数据的读取和写入。file_stream = open(r"C:\Users\yuliang\Desktop\学习\python\IO流\file.txt","r",encoding="utf-8")
print(file_stream.__str__()) #<_io.TextIOWrapper name='C:\\Users\\yuliang\\Desktop\\学习\\python\\IO流\\file.txt' mode='r' encoding='utf-8'>
data = file_stream.readline()
print(data) #贾卓群
file_stream.close()
所有的IO流对象都有close方法。
流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(浪费)很多资源。
注意:如果没有flush()可能会导致丢失数据
在 Python 中,OSError
和 IOError
都是异常类,用于处理与操作系统和文件IO相关的错误。虽然它们在不同的版本中可能有一些差异,但通常的区别如下:
1、OSError
OSError
是一个通用的操作系统错误异常类,它可以用于捕获各种与操作系统交互时可能发生的错误,不仅仅限于文件IO。OSError
的子类,而不再使用 IOError
。OSError
包括了文件不存在、权限问题、文件已存在、文件夹不存在等各种可能的操作系统级错误。try:
with open("nonexistent_file.txt", "r") as file:
data = file.read()
except OSError as e:
print(f"发生了操作系统错误: {e}")
2、IOError
IOError
曾在 Python 2 中是一个常见的异常类,用于表示文件IO相关的错误。但在 Python 3 中,大多数文件IO相关的异常已经移至 OSError
。IOError
在 Python 3 中并不常见,但仍然可以在某些情况下看到它,尤其是在与旧的代码或库进行交互时。????????总之,通常建议在 Python 3 中使用 OSError
来处理与文件IO和操作系统交互相关的错误,因为它更通用,可以捕获各种操作系统级错误。但在特定情况下,可能会遇到旧代码中仍然使用 IOError
的情况,因此需要根据具体情况来处理异常。
open()
函数是 Python 中用于打开文件的内置函数,它用于创建一个文件对象,以便进行文件的读取、写入或其他操作。open()
函数的详细用法如下:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数解释:
file
:要打开的文件名(字符串)或文件路径。mode
:打开文件的模式(字符串)。
'r'
,表示只读模式。'w'
(写入模式)、'a'
(追加模式)、'b'
(二进制模式)、't'
(文本模式)等。'wb'
表示以二进制写入模式打开文件。buffering
:缓冲策略。默认为 -1
,表示使用默认的缓冲策略。可以设置为 0
(无缓冲)、正整数(缓冲区大小),或负整数(使用系统默认缓冲大小)。encoding
:用于文本模式的编码格式(字符串)
'utf-8'
或 'latin-1'
。默认为 None
,表示使用系统默认编码。errors
:用于文本模式的编码错误处理方式。默认为 None
,表示使用默认错误处理方式。常见选项包括 'strict'
(抛出异常)、'ignore'
(忽略错误字符)、'replace'
(替换错误字符)等。newline
:文本模式下的换行符处理方式。默认为 None
,表示使用系统默认。常见选项包括 '\n'
(Unix 风格换行符)、'\r\n'
(Windows 风格换行符)等。closefd
:在使用文件描述符时是否自动关闭文件。默认为 True
。opener
:一个可选的自定义文件打开器函数,用于在打开文件之前进行更多的自定义操作。open()
函数返回一个文件对象,你可以使用该文件对象执行各种文件操作,如读取、写入、关闭等。
with open
是 Python 中用于打开文件的上下文管理器(Context Manager),它提供了更安全和方便的方式来处理文件操作。下面是 with open
语法的详解以及底层调用的魔术方法:
with open
语法的一般形式如下:
with open(filename, mode, *args, **kwargs) as file:
# 在这个代码块中进行文件操作
# 文件将在代码块结束后自动关闭
参数:
filename
:要打开的文件的路径或文件名。mode
:文件的打开模式,如读取('r'
)、写入('w'
)、追加('a'
)等。*args
和 **kwargs
:可选的其他参数,通常用于指定编码、错误处理等。1、with open
语句的工作原理在 with open
代码块进入时,open()
函数被调用,返回一个文件对象,并将该对象分配给 file
变量。
在 with
代码块内,你可以使用 file
变量来执行文件的读取、写入等操作。
在 with
代码块退出时,文件对象的 __exit__()
方法被自动调用,这个方法负责关闭文件。这是上下文管理器的关键之处,它确保文件在不再需要时被正确关闭,无论代码块是否正常执行或抛出异常。
下面是一个具体的示例,演示了如何使用 with open
打开文件:
# 打开文件并自动关闭
with open("example.txt", "r") as file:
data = file.read()
print(data) # 在这个代码块中使用文件
# 文件在代码块结束后自动关闭,无需手动调用 file.close()
__enter__()
和 __exit__()
__enter__()
方法在进入 with
代码块时被调用,通常用于执行资源分配和准备工作,例如打开文件。
__exit__()
方法在退出 with
代码块时被调用,通常用于执行资源清理工作,例如关闭文件。如果 with
代码块中出现了异常,__exit__()
方法也会捕获并处理异常(如果需要),然后继续传播异常或忽略它,确保资源得以释放。
在使用 with open
语法时,这些魔术方法会自动被调用,使得文件操作更加安全和便捷,不需要手动管理文件的打开和关闭。这是 Python 中的一种最佳实践,特别是在处理文件时。
with open
和 open
都是用于打开文件的 Python 语法,但它们在用法和行为上有一些区别和联系。
open
函数:
open()
是 Python 的内置函数,用于打开文件并返回一个文件对象,你可以使用这个对象执行文件的读取、写入等操作。open()
函数时,你需要显式地打开和关闭文件,以确保资源被正确释放。file = open("example.txt", "r") # 打开文件
data = file.read() # 读取文件内容
file.close() # 关闭文件
这种方式需要手动管理文件的打开和关闭,容易忘记关闭文件,从而导致资源泄漏。
with open
语句:
with open
是一种上下文管理器(Context Manager)的用法,它通过 with
关键字创建一个上下文,自动管理文件的打开和关闭。在退出 with
代码块时,会自动关闭文件。with open("example.txt", "r") as file: # 使用 with 打开文件
data = file.read() # 在此代码块中使用文件
# 文件在代码块结束后自动关闭
????????使用 with open
语句可以确保文件在退出代码块时被正确关闭,无论代码块是否正常执行或抛出异常。
总结:
open
是一个函数,用于打开文件,需要手动管理文件的打开和关闭,容易出错。with open
是一种上下文管理器,通过 with
关键字创建文件的上下文,自动管理文件的打开和关闭,更安全和方便。建议在大多数情况下使用 with open
语句来处理文件,以确保文件的正确关闭,避免资源泄漏。这是 Python 中的一种最佳实践。
输入流中的open函数中的mode选择为“r”,表示为Read,输入流
- r:表示read,字符输入流
- rb:表示read binary,字节输入流
使用open函数
file_stream = None
try:
#使用绝对路径
file_stream = open(r"C:\Users\yuliang\Desktop\学习\python\IO流\file1.txt","r",encoding="utf-8")
except FileNotFoundError as e:
print(e)
finally:
if file_stream is not None:
file_stream.close()
使用with open 上下文管理对象
try:
# 使用绝对路径
with open(r"C:\Users\yuliang\Desktop\学习\python\IO流\file1.txt",mode="r",encoding="utf-8") as file_stream:
pass
except FileNotFoundError as e:
print(e)
#使用with open上下文管理对象后就不用关闭流了
相对路径默认为运行代码的当前主模块的路径
使用open函数
#首先声明一个变量赋值为None,方便后期判断
file_stream = None
try:
#使用相对路径
file_stream = open("file.txt","r",encoding="utf-8")
except FileNotFoundError as e:
print(e)
finally:
if file_stream is not None:
file_stream.close()
使用with open上下文管理对象
try:
# 使用相对路径
with open("file.txt",mode="r",encoding="utf-8") as file_stream:
pass
except FileNotFoundError as e:
print(e)
#使用with open上下文管理对象后就不用关闭流了
read(size)
: 从流中读取指定大小的数据。如果未指定大小,它将读取整个流????????在 Python 中,输入流对象通常是用于读取数据的对象,例如文件对象、标准输入对象(sys.stdin
),或者网络套接字对象。其中,read
方法是用于从输入流中读取数据的重要方法。下面是关于 read
方法的详细解释:
file.read(size)
file
: 输入流对象,例如文件对象或标准输入对象。size
: 可选参数,用于指定要读取的字符数。如果未提供 size
参数或 size
参数为负数,它将读取整个输入流直到流结束。read
方法的行为如下:
如果提供了 size
参数,则 read
方法会尝试从输入流中读取指定数量的字符数据,并将这些数据作为一个字符串返回。如果没有足够的数据可用,它将返回实际可用的数据。如果 size
参数为负数或未提供,则会尝试读取整个输入流直到流结束。
如果已经到达输入流的末尾,read
方法将返回一个空字符串 ''
(如果 size
参数为负数或未提供),或者返回一个空字符串 ''
(如果指定了 size
参数且已读取了所有可用数据)。
下面是一些示例,演示了如何使用 read
方法:
with open("file.txt", mode = "r", encoding = "utf-8") as file:
#print(file.read())
#贾卓群
#博彦科技
#read方法中的参数表示需要读入的字符数
data = file.read(5)
print(data)
#贾卓群
#博
readline()
: 从流中读取一行数据在 Python 中,输入流对象通常是用于读取数据的对象,例如文件对象、标准输入对象(sys.stdin
),或者网络套接字对象。readline
方法是用于从输入流中读取一行数据的方法。下面是关于 readline
方法的详细解释:
file.readline(size)
file
: 输入流对象,例如文件对象或标准输入对象。size
: 可选参数,用于指定要读取的最大字符数。如果提供了 size
参数,readline
方法将尝试读取不超过 size
字符的数据。如果未提供 size
参数或 size
参数为负数,它将读取整行数据,直到遇到行结束符为止(通常是换行符 \n
)。readline
方法的行为如下:
如果提供了 size
参数,它将尝试读取不超过 size
字符的数据,并返回包含这些数据的字符串。如果行长度大于 size
,则返回的字符串将截断为 size
字符。如果 size
参数为负数或未提供,则将读取整行数据,直到遇到行结束符为止。
如果已经到达输入流的末尾,readline
方法将返回一个空字符串 ''
(如果 size
参数为负数或未提供),或者返回包含剩余可用数据的字符串(如果指定了 size
参数且已读取了所有可用数据)。
下面是一些示例,演示了如何使用 readline
方法:
# 从文件中读取数据
with open("example.txt", "r") as file:
# 读取一行数据
line1 = file.readline()
print(line1)
# 读取下一行数据(无需指定size参数)
line2 = file.readline()
print(line2)
readlines()
: 从流中读取多行数据,并返回一个包含每行文本的列表????????在 Python 中,输入流对象通常是用于读取数据的对象,如文件对象、标准输入对象(sys.stdin
),或者网络套接字对象。readlines
方法是用于从输入流中读取多行数据的方法。以下是关于 readlines
方法的详细解释:
file.readlines(hint)
file
: 输入流对象,例如文件对象或标准输入对象。hint
: 可选参数,用于指定读取的字符总数的估计值。它可以用于优化读取操作,但不保证准确性。readlines
方法的行为如下:
如果提供了 hint
参数,它会尝试读取字符数不超过 hint
的数据,并将这些数据分割成行。如果 hint
参数为负数或未提供,则将尝试读取所有可用数据,并将其分割成行。
readlines
方法返回一个包含所有行文本的列表,每一行作为列表的一个元素。
如果已经到达输入流的末尾,readlines
方法将返回包含剩余可用数据的列表,如果没有剩余数据,则返回一个空列表 []
。
下面是一些示例,演示如何使用 readlines
方法:
# 从文件中读取多行数据
with open("example.txt", "r") as file:
# 读取所有行
lines = file.readlines()
print(lines)
# 读取前3行(使用hint参数)
lines_subset = file.readlines(3)
print(lines_subset)
输出流中的open函数中的mode选择为“w”,表示为Write,输出流
- w:表示write,字符输出流
- wb:表示write binary,字节输出流
????????在 Python 中,字节数据(bytes
)是一种不可变的序列数据类型,它用于存储一系列字节值。每个字节值都是一个整数,取值范围在 0 到 255 之间,表示一个 8 位的二进制数据。字节数据通常用于处理二进制数据、网络通信、文件 I/O 等场景。
字节数据的特点包括:
不可变性: 与字符串类似,字节数据是不可变的,一旦创建就不能修改。要对字节数据进行修改,通常需要创建一个新的字节数据对象。
字面值表示: 字节数据可以用字面值表示,以字母 b
开头,后面跟着字节数据的内容。例如:b'Hello'
。
元素访问: 可以使用索引访问字节数据中的单个字节,就像访问字符串中的字符一样。
字节串转换: 字节数据与字符串之间可以相互转换,使用 encode
方法将字符串转换为字节数据,使用 decode
方法将字节数据转换为字符串。需要注意的是,这需要指定字符编码。
常用于二进制数据: 字节数据通常用于处理二进制数据,如图像、音频、视频文件,或者在网络通信中传输原始数据。
以下是一些示例,演示了字节数据的基本用法:
# 创建字节数据
byte_data = b'Hello, World!'
# 访问字节数据中的单个字节
print(byte_data[0]) # 输出:72 (ASCII码值 'H')
# 字节数据与字符串的相互转换
string_data = byte_data.decode('utf-8')
print(string_data) # 输出:Hello, World!
new_byte_data = string_data.encode('utf-8')
print(new_byte_data) # 输出:b'Hello, World!'
????????需要注意的是,字节数据不同于整数或字符数据类型,它是一种特殊的数据类型,用于处理原始二进制数据。在许多情况下,特别是在处理文件 I/O、网络通信或编写低级数据处理代码时,字节数据非常有用。
可采用绝对路径或相对路径
mode 中 “a” 模式表示追加
try:
#以追加模式创建文件输出流对象
with open("jzq.txt", mode = "a", encoding = "utf-8") as file:
file.write("我是一名Python软件工程师")
except Exception as e:
print(e)
write(data)
: 向流中写入数据。通常用于写入文件或网络套接字类型:
@abstractmethod
def write(self, __s: AnyStr) -> int: ...
????????在 Python 中,I/O 流对象通常是用于写入数据的对象,例如文件对象、标准输出对象(sys.stdout
),或者网络套接字对象。write
方法是用于向这些流中写入数据的重要方法。下面是关于 write
方法的详细解释:
file.write(str)
file
: I/O 流对象,例如文件对象或标准输出对象。str
: 要写入的字符串或字节数据。write
方法的行为如下:
write
方法将给定的字符串或字节数据写入到流中。如果是字符串,它将直接写入;如果是字节数据,它也会写入,不作任何修改。
write
方法不会自动添加行结束符(例如换行符 \n
)。如果需要在每行末尾添加换行符,你需要手动添加它。
write
方法返回写入的字符数或字节数,具体取决于写入的是字符串还是字节数据。
以下是一些示例,演示如何使用 write
方法:
try:
#以追加模式创建文件输出流对象
with open("jzq.txt", mode = "a", encoding = "utf-8") as file:
num = file.write("我是一名Python软件工程师\n") # 写入字符串并添加换行符
print(num) #16 返回字符串中的字符数
except Exception as e:
print(e)
write
方法非常有用,可以用于将数据写入文件、屏幕或网络套接字等输出流中。需要注意的是,当使用文件对象写入文件时,要确保文件模式(例如 "w" 或 "a")允许写入操作。另外,如果你使用二进制模式打开文件(例如 "wb" 或 "ab"),write
方法将接受字节数据而不是字符串。
writelines(lines)
: 向流中写入多行数据,参数是一个包含多行文本的列表????????在 Python 中,I/O 流对象通常是用于写入数据的对象,例如文件对象、标准输出对象(sys.stdout
),或者网络套接字对象。writelines
方法是用于向流中写入多行数据的方法。下面是关于 writelines
方法的详细解释:
file.writelines(lines)
file
: I/O 流对象,例如文件对象或标准输出对象。lines
: 一个可迭代的对象,通常是包含多行文本字符串的列表或生成器。writelines
方法的行为如下:
writelines
方法接受一个包含多行文本字符串的可迭代对象,例如列表。它会将列表中的每个字符串写入流中,但不会自动添加行结束符(例如换行符 \n
)。
如果需要在每行的末尾添加换行符,你需要在写入字符串之前手动添加它们。
writelines
方法返回 None
,并且不会返回写入的字符数或字节数。
以下是一些示例,演示如何使用 writelines
方法:
# 向文件中写入多行数据
lines = ["Hello, World!\n", "Python is great!"]
with open("example.txt", "w") as file:
file.writelines(lines)
????????在 Python 中,标准输出流通常指的是 sys.stdout
,它是一个 sys
模块中的输出流对象,用于将文本数据输出到控制台。标准输出流是 Python 标准库中的一部分,提供了一种在控制台上输出信息的简单方式。以下是关于 Python 标准输出流的详细解释:
sys 模块:sys
模块是 Python 标准库中的一个模块,包含了与系统交互相关的方法和属性。sys.stdout
是 sys
模块中的一个属性,表示标准输出流。
sys.stdout 属性:sys.stdout
是 sys
模块中的一个属性,它是一个文件对象(类似于 sys.stdin
和 sys.stderr
),用于标准输出流的操作。通过 sys.stdout
,你可以将文本数据输出到控制台。
print 函数:Python 提供了 print()
函数,它是向标准输出流写入文本数据的主要方法。print()
函数可以接受一个或多个参数,并将它们输出到标准输出流,并在每个参数之间自动添加一个空格,以及一个可选的换行符。
你可以通过修改 sys.stdout
来实现标准输出重定向。例如,你可以将 sys.stdout
替换为一个文件输出流对象,从而将所有的输出写入到指定文件中,而不是默认输出到控制台。
import sys
# 打开一个文件并将 sys.stdout 替换为文件对象
with open("output.txt", "w") as file:
sys.stdout = file
print("This will be written to output.txt")
#或者
with open("data.txt", "a",encoding="utf-8") as file:
print("贾卓群", file=file)
一旦 sys.stdout
被重定向,所有后续的 print
语句和标准输出都将发送到被指定的文件。
在完成标准输出重定向后,你可以通过将 sys.stdout
恢复到原始值来还原标准输出流。
import sys
# 恢复 sys.stdout 到默认值
sys.stdout = sys.__stdout__
#sys模块中
__stdout__ = None # (!) real value is "<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>"
这将恢复 sys.stdout
到默认的标准输出流,使输出再次显示在控制台上。
以下是一个示例,演示了如何使用 sys.stdout
进行标准输出重定向:
import sys
# 保存原始的 sys.stdout
original_stdout = sys.stdout
# 打开一个文件并将 sys.stdout 替换为文件对象
with open("output.txt", "w") as file:
sys.stdout = file
print("This will be written to output.txt")
# 恢复 sys.stdout 到默认值
sys.stdout = original_stdout
print("This will be displayed on the console")
在此示例中,标准输出流首先被重定向到一个文件,然后恢复到默认的标准输出流。
总之,sys.stdout
是一个非常有用的工具,用于控制和管理 Python 程序的标准输出。你可以使用它来将输出重定向到不同的目的地,如文件或其他自定义输出流,以满足不同的需求。
????????Python 中有类似于 Java 中对象流(ObjectInputStream 和 ObjectOutputStream)的序列化和反序列化机制。Python 提供了 pickle
模块,它用于将 Python 对象序列化为二进制数据,并将二进制数据反序列化为 Python 对象。 pickle
模块提供了与 Java 对象流类似的功能,允许你在 Python 中保存和加载对象。
import pickle
# 创建一个 Python 对象
data = {'name': 'Alice', 'age': 30}
# 打开一个文件以进行序列化
with open('data.pickle', 'wb') as file:
pickle.dump(data, file)
上面的代码将 Python 字典对象 data
序列化到名为 "data.pickle" 的文件中。
import pickle
# 打开文件以进行反序列化
with open('data.pickle', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 输出:{'name': 'Alice', 'age': 30}
上面的代码从 "data.pickle" 文件中反序列化对象,并将其加载回 Python 程序中。
需要注意的是,pickle
模块用于序列化和反序列化 Python 对象,但它只适用于 Python 程序之间的通信,不适用于与其他编程语言的交互。此外,pickle
不是安全的,因此不要从不受信任的来源加载 pickle
数据,以防止恶意代码执行。
如果需要与其他编程语言交互或在网络上传输数据,可以考虑使用更通用的数据格式,如 JSON 或 Protocol Buffers(protobuf)。这些格式更具跨语言兼容性,并且更安全。
在 Python 中,I/O 流对象通常是文件对象、标准输入输出对象或网络套接字对象等。以下是一些常用的 I/O 流对象的实例方法:
读取数据:
read(size)
: 从流中读取指定大小的数据。如果未指定大小,它将读取整个流。readline()
: 从流中读取一行数据。readlines()
: 从流中读取多行数据,并返回一个包含每行文本的列表。写入数据:
write(data)
: 向流中写入数据。通常用于写入文件或网络套接字。writelines(lines)
: 向流中写入多行数据,参数是一个包含多行文本的列表。定位和偏移:
seek(offset, whence)
: 移动流的位置指针到指定的偏移量。whence
参数指定相对于哪个位置进行偏移,默认为 0(文件开头)。tell()
: 返回当前流的位置指针。关闭流:
close()
: 关闭流,释放相关资源。在文件操作后记得关闭文件,以免资源泄漏。判断流状态:
closed
: 流对象的属性,表示流是否已关闭。eof()
: 判断是否已到达流的末尾。刷新缓冲区:
flush()
: 强制将缓冲区中的数据写入底层设备或文件。这些是常用的 I/O 操作方法,具体取决于你使用的 I/O 流对象的类型。例如,文件对象 (open()
返回的对象) 和标准输入/输出对象 (sys.stdin
、sys.stdout
、sys.stderr
) 都支持这些方法,但网络套接字对象可能有不同的方法和行为。