打开文件的两种方式
1.直接打开文件并赋值给变量,打开后得到操作句柄,但不会自动关闭
- file = open('文件名‘,'打开模式',’编码‘)
-
fd = open('../config/file1.txt','r',encoding='utf-8')
2.使用with子句,打开后文件会自动关闭,建议使用,并可以同时打开多个文件
with open('../config/file1.txt','r',encoding='utf-8') as fd1, open('../config/file2.txt','r',encoding='utf-8') as fd2: print("I had open two files")
打开文件的8种模式
========= =============================================================== 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) 'U' universal newline mode (deprecated) ========= ===============================================================
1.’r',默认模式,参数可以不写,打开只读文件,写入报错
>>> fd = open('../config/file1.txt','r',encoding='utf-8') >>> fd.write('java c rubby') Traceback (most recent call last): File "<stdin>", line 1, in <module> io.UnsupportedOperation: not writable
2.‘w’,先truncate原文件,后写入,不可读,文件不存在则创建
>>> fd = open('../config/file1.txt','w',encoding='utf-8') >>> print(fd.read()) Traceback (most recent call last): File "<stdin>", line 1, in <module> io.UnsupportedOperation: not readable >>> fd.write('java rubby go') 13 >>> fd.close() >>> fd = open('../config/file1.txt','r',encoding='utf-8') >>> fd.read() 'java rubby go'
3.'x',创建新文件,打开并写入,如果文件已经存在,则报错
>>> fd = open('../config/file21.txt','x',encoding='utf-8' ) >>> fd.read() Traceback (most recent call last): File "<stdin>", line 1, in <module> io.UnsupportedOperation: not readable >>> fd.write('123456') 6 >>> fd.close() >>> fd = open('../config/file21.txt','r',encoding='utf-8') >>> fd.read() '123456' >>> fd.close() >>> fd = open('../config/file21.txt','x',encoding='utf-8') Traceback (most recent call last): File "<stdin>", line 1, in <module> FileExistsError: [Errno 17] File exists: '../config/file21.txt'
4.’a',追加写内容到文件末尾
>>> fd = open('../config/file1.txt','a',encoding='utf-8') >>> fd.write('linux windows aix') 17 >>> fd.close() >>> fd = open('../config/file1.txt','r',encoding='utf-8') >>> fd.read() 'java rubby golinux windows aix'
5.'b',二进制模式,比如流文件mp3,并且需要同时指定一种读写模式
>>> fd = open('/tmp/Front_Right.wav','b') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Must have exactly one of create/read/write/append mode and at most one plus >>> fd = open('/tmp/Front_Right.wav','rb') >>> fd1 = open('/tmp/Front_Right.wav','wb') >>> fd2 = open('/tmp/Front_Right.wav','ab') >>> fd2 = open('/tmp/Front_Right.wav','w+b') >>> fd2 = open('/tmp/Front_Right.wav','r+b')
6.'t',文本模式,默认打开文本并读取模式rt
7.'+',打开硬盘文件读写
- r+,打开并写入
-
>>> fd = open('../config/file1.txt','r+',encoding='utf-8') >>> fd.read() 'java rubby golinux windows aix' >>> fd.write("mage") 4 >>> fd.seek(0) 0 >>> fd.read() 'java rubby golinux windows aixmage'
- w+,打开文件读写,文件存在则覆盖,不存在则创建
-
>>> fd = open('../config/file4.txt','w+',encoding='utf-8') >>> fd.write('guangzhou') 9 >>> fd.seek(0) 0 >>> fd.read() 'guangzhou' >>> fd.seek(0) 0 >>> fd.write('hangzhou') 8 >>> fd.seek(0) 0 >>> fd.read() 'hangzhouu'
- a+,打开文件读写,存在则将指针置于末尾,不存在则创建新文件
-
>>> fd = open('../config/file4.txt','a+',encoding='utf-8') >>> fd.read() '' >>> fd.seek(0) 0 >>> fd.read() 'hangzhouu' >>> fd.close() >>> fd = open('../config/file4.txt','a+',encoding='utf-8') >>> fd.write('beijing') 7 >>> fd.read() '' >>> fd.seek(0) 0 >>> fd.read() 'hangzhouubeijing'
- rb+, wb+, ab+ 对象是二进制,其他以上面一样
8.‘U’,deprecated
指针位置
1.f.tell(),告知字符指针位置
2.f.seek(),移动字符指针位置,f.seek(0)文件开头
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> fd.tell() 0 >>> fd.seek(0) 0 >>> fd.tell() 0 >>> fd.read(1) 'h' >>> fd.tell() 1 >>> fd.read(2) 'an' >>> fd.tell() 3 >>> fd.seek(0) 0 >>> fd.readline() 'hangzhouubeijing ' >>> fd.tell() 17
读取文件的4个read,默认从头开始读,并将将指针留在行尾
1.fd.read(size)
- 默认省略size,size为整型,字符个数
- 读取全部内容到内存,并将指针留在行尾
- 大文件读取不要用,占内存
- 返回的是字符串类型
-
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> fd.read() 'hangzhouubeijing' >>> fd.seek(0) 0 >>> fd.read(1) 'h' >>> fd.read(2) 'an' >>> fd.read(3) 'gzh' >>> fd.seek(0) 0 >>> fd.read(6) 'hangzh'
2.fd.readline(size)
- 默认一行行读取,size与上面一样
- 占用内存小
- 每行结尾带换行符
-
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> fd.readline() 'hangzhouubeijing ' >>> fd.readline() 'shenzhen ' >>> fd.readline() 'shanghai ' >>> fd.readline(1) 'a' >>> fd.readline(2) 'nh' >>> fd.readline() 'ui ' >>> fd.readline() 'guangdong ' >>> fd.readline() 'zhejiang' >>> fd.readline() ''
3.fd.readlines(size)
- 讲文本全部转换成列表,size表示下标
-
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> fd.readlines() ['hangzhouubeijing ', 'shenzhen ', 'shanghai ', 'anhui ', 'guangdong ', 'zhejiang'] >>> fd.seek(0) 0 >>> fd.readlines(1) ['hangzhouubeijing '] >>> fd.readlines() ['shenzhen ', 'shanghai ', 'anhui ', 'guangdong ', 'zhejiang']
4.fd.readable()
- 返回布尔值,判断文件是否可读
-
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> fd.readable() True
循环遍历迭代文本内容对象(遍历操作都可以这么干)
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> for line in fd: ... print(line) ... hangzhouubeijing shenzhen shanghai anhui guangdong zhejiang >>> fd.seek(0) 0 >>> for index,line in enumerate(fd.readlines()): ... print(index,line) ... 0 hangzhouubeijing 1 shenzhen 2 shanghai 3 anhui 4 guangdong 5 zhejiang >>>
其他方法
close(self, /) 关闭打开的文件
- | Flush and close the IO object.
- |
- | This method has no effect if the file is already closed.
detach(self, /) 干嘛用?
- | Separate the underlying buffer from the TextIOBase and return it.
- | After the underlying buffer has been detached, the TextIO is in an
- | unusable state.
>>> fd.detach() <_io.BufferedReader name='../config/file4.txt'> >>> fd.read() Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: underlying buffer has been detached
fileno(self, /) 返回文件描述符,干嘛用?
- | Returns underlying file descriptor if one exists.
- | OSError is raised if the IO object does not use a file descriptor.
>>> fd = open('../config/file4.txt','r',encoding='utf-8') >>> fd.fileno() 4 >>> fd = open('../config/filexxx.txt','w+',encoding='utf-8') >>> fd.fileno() 3
flush(self, /) 将缓存立即写入硬盘,提高效率
- | Flush write buffers, if applicable.
- | This is not implemented for read-only and non-blocking streams.
import time import sys for i in range(40): sys.stdout.write("#") sys.stdout.flush() time.sleep(0.1)
isatty(self, /) 是否连接到终端设备
- | Return whether this is an 'interactive' stream.
- | Return False if it can't be determined.
seekable(self, /)
- | Return whether object supports random access.
- | If False, seek(), tell() and truncate() will raise OSError.
- | This method may need to do a test seek().
truncate(self, pos=None, /)
- | Truncate file to size bytes.
- | File pointer is left unchanged. Size defaults to the current IO
- | position as reported by tell(). Returns the new size.
>>> fd = open('../config/file4.txt','r+',encoding='utf-8') >>> fd.truncate() 0
writable(self, /) 判断文件是否以写模式打开
| Return whether object was opened for writing.
>>> fd = open('../config/file4.txt','r+',encoding='utf-8') >>> fd.writable() True >>> fd = open('../config/file1.txt','r',encoding='utf-8') >>> fd.writable() False
修改文件的两种方式:
1.全部读入内存,修改完毕之后覆盖写入源文件
2.一行一行读取内存,修改完毕之后写入新文件,用新文件覆盖旧文件