python -- 文件操作

python -- 文件操作

一般对文件操作流程如下:

  1. 打开文件,得打文件句柄并赋值给一个变量;
  2. 通过句柄对文件进行操作;
  3. 关闭文件。

文件的基本操作

打开文件 f = open('filename','r',encoding='utf-8') with open('filename',encoding='utf-8') as f

# 一种文件打开的方式,这样的调用模式,文件不会自动关闭
f = open('filename', encoding='utf-8')
# 另一种较为常见的文件打开方式,这样的调用模式,会自动关闭文件
with open('filename', encoding='utf-8') as f_1, \
        open('filename2',encoding='utf-8') as f_2:
    pass

文件打开的模式分类

模式说明备注
r只读模式默认模式
w只写模式只写,不读
a追加模式可写,续写,不可读
r+读写模式可读,可写,建议使用这种
w+写读模式可写,可读,先重建,再读
a+追加读写模式类似r+模式
rb二进制读模式
wb二进制读模式
ab二进制追加写模式

读文件 file.read()

当文件f.read()读取一遍后,文件指针就指向文件的最后一行,如果不将指针返回,是无法读取第二遍。因为f.read()是将文件全读取一遍。

# 一种文件打开的方式,这样的调用模式,文件不会自动关闭
f = open('filename', 'r', encoding='utf-8')
# 另一种较为常见的文件打开方式,这样的调用模式,会自动关闭文件
with open('filename', encoding='utf-8') as f_1:
    pass

data = f.read()
# 使用with打开文件,不能再调用read(),因为文件已经关闭
# data_1 = f_1.read()

print(data)

f = open('filename', 'r', encoding='utf-8')

data = f.read()
data_1 = f.read()

print(data)
print('----------这是分割线----------')
print(data_1)

'''
以下是上面程序执行的结果:
The str in the file.
File's name is filename.
----------这是分割线----------
'''
f = open('filename', 'r', encoding='utf-8')

# 只读5个,可以是5个中文,也可以是5个数字或英文
print(f.read(5))
print('--------------------')
# 再只读5个,可以是5个中文,也可以是5个数字或英文,如果是换行符,打印出来也是换行。
print(f.read(5))

写文件 file.write(data)

注意写入内容的格式差异

f = open('filename', 'w', encoding='utf-8')

data = ('''我是第一行。\n我是第二行。\n我是第三行。\n''')
data_1 = ('''
我是第一行。\n
我是第二行。\n
我是第三行。\n
''')

f.write(data)
'''
以下是data传入内容最终效果,最后一行的换行也在内。
我是第一行。
我是第二行。
我是第三行。

'''
f.write(data_1)
'''
以下是data_1传入内容最终效果,最后一行的换行也在内。
我是第一行。

我是第二行。

我是第三行。


'''

追加文件 同写file.write(data),区别是在文件打开的模式上不同,a模式下,同样无法读

f = open('filename', 'a', encoding='utf-8')

data = ('''我是第一行。\n我是第二行。\n我是第三行。\n''')
data_1 = ('''
我是第一行。\n
我是第二行。\n
我是第三行。\n
''')

f.write(data)
'''
以下是data传入内容最终效果,最后一行的换行也在内。
我是第一行。
我是第二行。
我是第三行。

'''
f.write('----------我是分割线----------')
f.write(data_1)
'''
以下是data_1传入内容最终效果,最后一行的换行也在内。
我是第一行。

我是第二行。

我是第三行。


'''
''''
这个文件最终加入的内容效果,最后一行的换行也在内。
我是第一行。
我是第二行。
我是第三行。
----------我是分割线----------
我是第一行。

我是第二行。

我是第三行。

'''
# 在a模式下,同样无法读
f.read()

文件的深入操作

文件读一行 file.readline()

f = open('filename', 'r', encoding='utf-8')
a = f.readline()
b = f.readline()
c = f.readline()
d = f.readline()
print(a, b, c, d)

for i in range(2):
    print(f.readline())

'''
以下是打印的效果,包含最后一行换行。有格式上的不同差异。
我是第一行。
 我是第二行。
 我是第三行。
 我是第四行。

我是第五行。

我是第六行。

'''

文件读所有行 file.readlines()

f = open('filename', 'r', encoding='utf-8')
a = f.readlines()

# <class 'list'> ['我是第一行。\n', '我是第二行。\n', '我是第三行。\n', '我是第四行。\n', '我是第五行。\n', '我是第六行。']
print(type(a), a)

for line in a:
    print(line)
print('--------------------')
for line_1 in a:
    print(line_1.strip())
'''
以下是print(line)和print(line_1)的效果。
由于每一行带换行符号。所以需要用到line.strip()。
我是第一行。

我是第二行。

我是第三行。

我是第四行。

我是第五行。

我是第六行。
--------------------
我是第一行。
我是第二行。
我是第三行。
我是第四行。
我是第五行。
我是第六行。

'''

打印前2行的内容,需要使用循环。即循环打印列表。

f = open('filename', 'r', encoding='utf-8')
a = f.readlines()

for index, line in enumerate(a):
    if index == 2:
        break
    # 这里不用print(line),是因为每一个列表中的元素都含有一个回车符,所以这里用到了strip()
    print(line.strip())

'''
以下是以上程序的效果。
我是第一行。
我是第二行。

'''

2层嵌套循环的写法

此时的f已经变成了迭代器

f = open('filename', 'r', encoding='utf-8')
count = 0
exit_flag = 1

while exit_flag == 1:
    for line in f:
        print(line)
        count += 1
        if count > 1:
            exit_flag = 0
            break

1层循环的写法

此时的f已经变成了迭代器

f = open('filename', 'r', encoding='utf-8')
count = 0

for line in f:
    if count > 1:
        break
    print(line)
    count += 1

查看文件句柄的指针位置 f.tell()

f = open('filename', 'r', encoding='utf-8')

print(f.tell())  # 0
f.readline()
# 第一句话有多长,那个数值就是这里显示的
print(f.tell())
# 再读5个字符
a = f.read(5)
print(a)
# 返回值是,又加了上面的f.read(5)后的值
print(f.tell())

将文件句柄的指针位置复位 f.seek()

f = open('filename', 'r', encoding='utf-8')

# 先循环打印两行
for i in range(2):
    a = f.readline()
    print(a.strip())

print(f.tell())
# 0代表文件句柄的起始位,也可以输入你想让它回到的位置
f.seek(0)
# 又打印了第一行的内容
print(f.readline())

查询文件编码 f.encoding

f = open('filename', 'r', encoding='utf-8')

# utf-8
print(f.encoding)

查询文件句柄在内存的编号 f.fileno()

f = open('filename', 'r', encoding='utf-8')

# 一个数字,操作系统专门有一个接口,处理所有文件,这个数字就是所有文件的编号
# 打开的文件并非python打开,而是调用了系统的I/O,这就是来自I/O的信息
print(f.fileno())

查询文件名 f.name

f = open('filename', 'r', encoding='utf-8')

# filename
print(f.name)

判断文件是否是一个tty文件类型 f.isatty()

判断文件是否可seek f.seekable()

判断文件是否可读 f.readable()

判断文件是否可写 f.writeable()

判断文件是否关闭 f.closed()

f = open('filename', 'r', encoding='utf-8')

# f.isatty()  返回True 或 False
# f.seekable()  返回True 或 False
# f.readable()  返回True 或 False
# f.writeable()  返回True 或 False
# f.closed()  返回True 或 False

# False
print(f.isatty())
# True
print(f.seekable())
# True
print(f.readable())
# False
print(f.writable())
# False
print(f.closed)

文件的写,文件的刷新写 f.write('str') f.flush()

f = open('filename', 'w+', encoding='utf-8')

# f.write('str')是写入,但是由于内存的buffer,需要通过f.flush()刷新到文件上
f.write('我是新建的第一行。\n')
f.flush()
f.close()

f = open('filename', 'r+', encoding='utf-8')

print(f.readline())

f.write('str') f.flush() 进度条的应用技巧

import sys, time

for i in range(50):
    # stdout是sys模块中的标准输出
    sys.stdout.write('#')
    # 写入后的强制刷新
    sys.stdout.flush()
    # time模块下的睡眠时间
    time.sleep(0.1)

'''
程序最后会呈现是:
#  ##  ###  ####  ... ... 50个#的结果
'''

文件的截断 f.truncate(int), 如果()内不加数字,,类似于清空

f = open('filename','a+',encoding='utf-8')

# 读一行文件内的数据
f.readline()
# 打印一句话后,光标的位置
print(f.tell())
# 将光标返回到句柄2的位置
f.seek(2)
# 2
print(f.tell())
# 做一次截断,这里20并非是从句柄2开始,而是从句柄的0位开始截断
# f.truncate(20)如果赋值于变量,会返回20
# 从句柄的0位开始截断,步长为20,文件内容直接出效果
f.truncate(20)
# todo 这里会报错,类似编译编码的错
print(f.readline())

二进制模式打开文件的那些事

f = open('filename','wb')

# 如果这里不加,encode(),就会报编码的错。
#由于程序使用的二进制,但str又不是二进制格式,所以需要encode()来转译。
f.write('我是新建的第一行。\n'.encode())

文件的修改

'''
以下是filename的内容
我是第一行。
我是第二行。
我是第三行。
我是第四行。
我是第五行。
我是第六行。
'''

# 要求1将filename中‘我是第四行。’这句话替换成'我是插队的。'
# 要求2将filename中‘我是第五行。’这句话中的‘是第五行’替换成'也是来插队的,保持队形'。

f = open('filename','r', encoding='utf-8')
f_new = open('filename_new','w+', encoding='utf-8')

for line in f:
    if line == '我是第四行。\n':
        line = '我是插队的。\n'
    elif '是第五行' in line:
        line = line.replace('是第五行', '也是来插队的,保持队形')
    f_new.write(line)
写在后面
  • 由于打开的文件会在内存里开辟一个新的对象,如果不将其赋值,这个对象的值在文件关闭后就消失,所以要给这个内存对象赋一个变量。这个变量又称,句柄。句柄包含:文件名,字符集,大小,在硬盘上的起始位置。
  • w,是以写打开文件,所以用了w等于先清空文件内容。类似创建一个文件。慎用。
  • a ,追加模式,append的意思。【可读,不存在就新建,存在就追加。但是不能读】
    r+ 读写模式。后面有解释。
  • 如果open()内不加encoding=’utf-8’,pycharm会报错,由于windows默认的编码是gbk,python默认打开格式是unicode,所以要把utf-8编码加入。
  • file.read(),默认是全部读取。file.read(5)则表示只读取5个元素(5个中文或5个数字,英文,特殊符)
  • file.readlines(),只适合读取小文件,因为file.readlines()是将文件里的文件全部读出,并生产列表。
  • 如果使用r+模式打开文件(可读,可写),读的时候会记录光标位置,而写始终在文件的末尾开始写。使用场景较多。
  • 如果使用w+模式打开文件(可写,可读),先创建一个文件,可写,可读。如果之前文件有内容,就会清除。但是写始终在文件尾端开始。没有什么比较好的使用场景。
  • 由于文件在硬盘中的存储的模式,所以文件始终在文件尾端开始。
  • 使用二进制文件打开模式,rb wb ab,后面不加encoding='utf-8',因为本身就是二进制。
  • 只有在网络传输打开文件时,才会用到二进制打开文件模式,rb,wb,ab。python2中还能用str模式,但是python3中只能用二进制模式。
  • 文件修改的思路,一种全部加载内存,像vim一样,另一种打开一个文件,再写入一个新文件。

模式说明备注
r只读模式默认模式
w只写模式只写,不读
a追加模式可写,续写,不可读
r+读写模式可读,可写,建议使用这种
w+写读模式可写,可读,先重建,再读
a+追加读写模式类似r+模式
rb二进制读模式
wb二进制读模式
ab二进制追加写模式

作用代码备注
打开文件f = open('filename','r',encoding='utf-8')赋值给变量
打开文件with open('filename',encoding='utf-8') as f文件自动关闭,且可打开多个文件
写文件f.write('str')非二进制写
写文件f.write('str'.encode())二进制写,前提需要二进制打开
刷新写文件f.flush()结合f.write('str')写文件使用
读文件f.read() f.read(50)不加参数:全读;加参数:读参数的个数
读文件f.readline()读一行,带换行符,建议与.strip()配合
读文件f.readlines()读所有行,并返回列表形式,每一行的内容就是元素
截断文件f.truncate(int)如果int=空,等同于清空文件,int值等于从0位开始截断
查光标f.tell()返回值是int型
读光标复位f.seek(int)int=0光标复位到文件头
查文件编码f.encoding注意书写格式
查文件名f.name注意书写格式
查文件句柄的位置f.fileno()返回值是int型
是否ttyf.isatty()返回值:True or False
是否可seekf.seekable()返回值:True or False
是否可读f.readable()返回值:True or False
是否可写f.writeable()返回值:True or False
是否已关闭f.closed()返回值:True or False

转载于:https://www.cnblogs.com/gzz041/p/7076603.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值