文件操作
1.文件处理的流程
1)打开文件,得到文件句柄并赋值给一个变量
2)通过句柄对文件进行操作
3)关闭文件
read: 读
例如:
f = open(\'chenli.txt\') #打开文件 first_line = f.readline() print(\'first line:\',first_line) #读一行 data = f.read()# 读取剩下的所有内容,文件大时不要用 print(data) #打印读取内容 f.close() #关闭文件
由于read就会光标从文件头读到末尾,这样再次度就没内容 -- 所以用seek
seek: 控制光标移动 移动到哪个 字节(bytes),只有read方法是字符其他的是字节
以下是seek()方法的语法:
fileObject.seek(offset, whence)
参数
offset 数字 -- 这是在文件中读/写指针的位置。
whence -- 这是可选的,默认为0,文件的起始位置;1,当前位置;2,文件的末尾
表示在文件中移动指针,从whence(0起始,1当前,2末尾)偏移offset个字节,正往结束方向移动,负往开始方向移动
注意:python3中1,2模式只能在bytes模式下
f = open(\'ceshi2.txt\') #打开文件
data1 = f.read()
print(data1)
f.seek(0) #控制光标归0 --- 最前面
data2 = f.read() #这样就能读到数据
print(data2)
closed
print(f.closed) #判断文件是否是关闭状态
2.文件操作基本用法
1)基本用法:
file_object = open(file_name, access_mode = ‘r’, buffering = -1)
open函数有很多的参数,常用的是file_name,mode和encoding
file_name:打开的文件名,若非当前路径,需指出具体路径
access_mode文件打开模式
buffering的可取值有0,1,>1三个,0代表buffer关闭(只适用于二进制模式),1代表line buffer(只适用于文本模式),>1表示初始化的buffer大小;
encoding表示的是返回的数据采用何种编码,一般采用utf8或者gbk;
2)文件打开模式: 主要分 文本和bytes
- r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
- w,只写模式【不可读;不存在则创建;存在则清空内容,等待重新写】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【可读; 不存在则创建;存在则只追加内容】,文件指针自动移到文件尾。
"+" 表示可以同时读写某个文件
- r+, 读写【可读,可写】
- w+,写读【可读,可写】,消除文件内容,然后以读写方式打开文件。
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】,以读写方式打开文件,并把文件指针移到文件尾。
"b"表示以字节的方式操作,以二进制模式打开文件,而不是以文本模,这样就不能考虑字符编码。可用于读图片和影音:
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
------->
以bytes打开并读:
with open(\'a.txt\',\'rb\') as f:
print(f.read().decode(\'utf-8\'))
需要decode 转成汉字
以bytes打开并写:
with open(\'a.txt\',\'wb\') as f:
print(f.write(\'酥酥酥\').encode(\'utf-8\'))
需要encode 汉字转成bytes
复制图片:
3)以读r的方式打开文件
#!/usr/bin/env python # -*- coding:utf-8 -*- f=open(\'1.txt\',encoding=\'utf-8\',mode=\'r\') print(f) data1=f.read() print(data1)
1.txt
55542342 123
输出:
<_io.TextIOWrapper name=\'1.txt\' mode=\'r\' encoding=\'utf-8\'> 55542342 123
补充:
1)python中有三个方法来处理文件内容的读取: read() #一次读取全部的文件内容。 readline() #每次读取文件的一行。然后光标跑到第二行开头 ---- 后面的end=\'\'代表去掉后面自带的的换行符换成空 readlines() #读取文件的所有行,存成列表的形式,换行符这些以/t替代,空行以\n为一个元素 --- 结果就是原封不动的依次保存好 2)print(f.readable()) #判断文件是否是r模式打开的
3)print(f.closed) #判断文件是否是关闭状态
4)python中在文本文件内容移动的操作 file.seek(offset,whence=0) #从文件中给移动指针,从whence(0起始,1当前,2末尾)偏移offset个字节,正往结束方向移动,负往开始方向移动 file.tell() #返回当前文件中的位置。获得文件指针位置
5) file.truncate(size=file.tell()) #截取文件到最大size个字节,默认为当前文件位置
4)以w方式写入文件
# f=open(\'b.txt\',\'r\',encoding=\'utf-8\') #以读的方式打开文件,文件不存在则报错 f=open(\'b.txt\',\'w\',encoding=\'utf-8\') # print(f.writable()) f.write(\'111111\n22222222\') #文件的写入,在光标停的位置开始写 f.write() f.seek(0) f.write(\'\n333333\n444444\') f.writelines([\'\n55555\n\',\'6666\n\',\'77777\n\']) f.close()
a.txt 为空
b.txt
333333 444444 55555 6666 77777
补充:
file.write(str) #向文件中写入字符串(文本或二进制) file.writelines(seq) #写入多行,向文件中写入一个字符串列表,注意,可能要自己加入每行的换行符 file.flush() #刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入.
r和w 都是以文本的方式打开文件
3.文件的修改
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
read_f=open(\'b.txt\',\'r\') #此处应该指定字符编码,若是字母就没事
write_f=open(\'.b.txt.swap\',\'w\')
for line in read_f.readlines():
if line.startswith(\'1111\'):
line=\'2222222222\n\'
write_f.write(line)
read_f.close()
write_f.close()
os.remove(\'b.txt\')
os.rename(\'.b.txt.swap\',\'b.txt\')
4.上下文管理 with语句 ---- 另一种打开文件的方式,可以自动关闭文件
1):
当你做文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
正常情况下,代码如下:
file = open("/tmp/foo.txt")
data = file.read()
file.close()
这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。
然而with可以很好的处理上下文环境产生的异常。下面是with版本的代码:
with open("/tmp/foo.txt") as file:
data = file.read()
with的基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。
2):read读字符:
5.补充:
1).for ... else... :
为了保证for循环是完整的,不被打断走完了就能执行else
用于 ---->
for i in range(1,10): print(i) else: print(\'ok\') 结果: 1 2 3 4 5 6 7 8 9 ok
2).truncate: 截断字节,截断源文件,一个汉字三个字节
f.truncate(3)
3). f.tell(): 看光标位置
4)模拟 tail -f access.log : null、空、0则为False
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# tail -f access.log
import time
with open(\'access.log\',\'r\',encoding=\'utf-8\') as f:
f.seek(0,2)
while True:
line=f.readline().strip()
if line:
print(\'新增一行日志\',line)
time.sleep(0.5)