基本使用
打开文件
open(filename[,mode,encoding="编码"]):第一个参数文件名如果不加路径,默认在该py文件目录下(路径举例:E:/XXX或E:\\xxx),第二个是模式,默认为'r'——只读,举例:f = open('E:/abc.txt') ,如果要转编码并写入模式:
f = open('E:/abc.txt','w',encoding='utf-8')
1. 模式
'r' 只读
'w' 可写入,但是会覆盖原来文件,没有就新建文件
'a' 可写入,但不会覆盖,会从末尾追加
'b' 以二进制打开
'x' 如果文件存在打开会引发异常,没有就新建
't' 以文本模式打开
'r+' 可读写模式
'U' 通用换行符支持
2. 方法
(1)close(): 关闭文件,因为文件写入时是写在内存,只有关闭时才写入硬盘,所以写完记得关闭
(2)read(size = -1):读取文件size个字符,不写默认是-1,此时读取所有内容(换行按\n来表示,很不好看),并作为字符串返回,一定要注意读完以后文件指针将会指向末尾,所以下一次在用read方法时会发现读取不出内容了,所以这个就要用seek移动指针或者关闭文件重新定义
(3)tell():返回当前文件指针指向的位置
(4)seek(offset,from):移动文件指针,代表从from参数开始偏移offset个字节,0代表起始位置,1代表当前位置,2代表文件末尾
(5)readline():按序列读取一行内容,默认\n为边界
(6)write():写入内容,但必须要有写入权限才行,否则报错,写完会返回写入的长度,例如:len1 = f.write('abc'),此时len1就为3
(7)truncate():删除内容,把当前指针以后的内容全删了,举例:
f.seek(0) #定位到开头
f.truncate() #把所有内容删了
f.write(str(1)) #添加字符1
#相当于把文本清空,然后写了个1
注:
1.文件还可以转化为list之类的,例如:list1 = list(f),此时文件内容的按\n被隔开,然后可以用for语句读取文件所有内容,举例:
for each_line in list1:
print(each_line)
2.上面输出文件内容方法相对低效,所以一般都直接用for输出整个文件,举例:
for each_line in f:
print(each_line)
文件描述符
通过fileno函数,我们可以查看一个文件对应的文件描述符,对应的是程序中打开的文件序号,举例:
import sys
print(sys.stdin.fileno())
print(sys.stdout.fileno())
print(sys.stderr.fileno())
with open("test1", "r") as f:
print(f.fileno())
with open("test2", "r") as f:
print(f.fileno())
with open("test3", "r") as f:
print(f.fileno())
# 0
# 1
# 2
# 3
# 3
# 4
可以看出python在启动时会先启动标准流的文件(文件描述符分别为:0/1/2),所以之后打开的文件就从3开始递增,当释放一个文件资源时,该描述符序号被释放,之后打开的文件可以继续使用该序号的文件描述符
print本质
python中的print的本质是通过sys.stdout来进行内容输出,而sys.stdout的本质是一个"文件",相当于我们所有的输入输出的本质都是在对sys.stdin/sys.stdout/sys.stderr这些文件来进行读写操作,举例:
import sys
print(sys.stdin, sys.stdin.fileno())
print(sys.stdout, sys.stdout.fileno())
print(sys.stderr, sys.stderr.fileno())
# 向终端输出内容
sys.stdout.write("terminal output...")
# <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'> 0
# <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> 1
# <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'> 2
# terminal output...
closefd
open函数不仅可以打开本地文件,也可以打开文件描述符,而该参数默认为True,代表close后会将对应的文件资源释放,而对于一些文件描述符,我们只是希望close时将打开文件描述符的对象释放,而不释放对应的文件资源,那么则可以设置closefd=False,举例:
import sys
# with上下文结束后不释放描述符对应资源
with open(sys.stdout.fileno(), "w", closefd=False) as f:
f.write("stdout..., closefd=False\n")
print(111)
# with上下文结束后释放描述符对应资源
with open(sys.stdout.fileno(), "w", closefd=True) as f:
f.write("stdout..., closefd=True\n")
# 标准输出流被关闭,这里输出会报错
print(222)
# stdout..., closefd=False
# 111
# stdout..., closefd=True
# OSError: [Errno 9] Bad file descriptor
获取文件编码
需要使用到chardet模块,按二进制可读打开文件,然后通过detect()方法查看,举例:
>>> f = open("F:/a/a.txt", 'rb')
>>> chardet.detect(f.readline())
{'language': '', 'encoding': 'UTF-8-SIG', 'confidence': 1.0}
所以就可以根据文件来设置编码了:
import chardet
with open(filename , "rb") as f_code:
code = chardet.detect(f_code.readline())['encoding'] #获取文件编码
with open(filename , "r", encoding=code) as f: #根据编码设置
content = f.read()
忽略编码
有时候使用文件的编码解码也可能会出现无法解析的情况,例如两种编码混在同一个文件里的时候,此时可以设置errors参数为ignore来避免该问题,示例:
import chardet
with open(filename , "rb") as f_code:
code = chardet.detect(f_code.readline())['encoding'] #获取文件编码
with open(filename , "r", encoding=code, errors='ignore') as f: #根据编码设置
content = f.read()
文件权限
可用os模块下的chmod()函数,具体参考:http://www.runoob.com/python/os-chmod.html
删除文件
使用os模块下的remove()函数可以实现删除文件,举例:
import os
os.remove('aaa.txt')
压缩文件操作
可以使用自带的zipfile模块来进行操作,举例:
>>> import zipfile
>>> path = "test.zip"
>>> file = zipfile.ZipFile(path, 'r')
# 读取压缩文件
>>> file.namelist()
# 查看压缩文件列表
['0.txt', '1/', '1/1_1.txt']
# 压缩文件内容格式:
# -0.txt
# -1
# -1_1.txt
>>> file.printdir()
# 打印文件列表
File Name Modified Size
0.txt 2018-11-27 15:23:08 5
1/ 2018-11-27 15:22:10 0
1/1_1.txt 2018-11-27 15:22:46 5
>>> file.NameToInfo
# 直接看所有文件信息
{'0.txt': <ZipInfo filename='0.txt' external_attr=0x20 file_size=5>, '1/': <ZipInfo filename='1/' external_attr=0x10>, '1/1_1.txt': <ZipInfo filename='1/1_1.txt' external_attr=0x20 file_size=5>}
>>> file.open("1/1_1.txt").read()
# 读取文件内容
b'file1'
>>> file.getinfo('0.txt')
# 可以看见文件大小为5字节
<ZipInfo filename='0.txt' external_attr=0x20 file_size=5>
>>> file.getinfo('0.txt').file_size
# 获取文件大小
5
>>> file.getinfo('0.txt').compress_size
5
>>> z.extract('1/1_1.txt', "./")
'C:\\Users\\Administrator\\Desktop\\1\\1_1.txt'
# 解压某个文件到当前路径
>>> z.extractall("./")
# 解压所有文件
>>> file.close()
# 记得关闭文件,或者直接用with打开
打包文件
可以使用自带的tarfile模块来进行操作,举例:
import tarfile
# 创建一个tar文件
tar = tarfile.open('test.tar', 'w')
for file in ["1.txt", '2.txt']:
# 添加文件
tar.add(file)
tar.close()