文件操作

基本的文件处理

什么是文件

操作系统提供给用户的一个虚拟单位

文件有什么用

存储数据

打开文件的流程

找到文件路径

path = r'xxx\xxx.py'  # 鼠标右键点击文件,copy path

双击打开

f = open(path, 'w')  # r-->read 只读 ; w-->只写,清空当前文件后写入
print(f)  # 文件数据类型

看文件

data = f.read()
print(data)

写文件

f.write('nick handsome')

关闭文件

# del f  # 只删除了文件的引用以及文件在python内存中的占用,但是没有删除对操作系统的占用
f.close()  # 关闭操作系统对文件的占用

文件的三种打开方式

只读(r)

用f.read()来执行

将文件内容拿出来,读一行少一行

也就是说在同一次运行中,先执行f.read()之后,如果再执行一次,则第二次会什么都读不出来

这个时候,就要使用readline来一行一行的读

先创建一个TXT文件,内容为:

这是一个txt文件

这是第二行

f = open('test.py','r',encoding='utf8')  # 只读  # 文件内容拿出来,读一行少一行
print(f.read())  # 读取文件所有内容
print(1,f.readline())  # 已被读完,无法再次读取
print(2,f.readline())  #

结果为:
这是一个txt文件
这是第二行
1 
2 
f = open('test.txt','r',encoding='utf8')  
print(1,f.readline())  
print(2,f.readline())  

结果为:
1 这是一个txt文件

2 这是第二行

蚁后使用这个方式来循环文件:

f = open('test.txt','r',encoding='utf8')
for i in f:
    print(i)

print(f.readable())  # 是否可读 
f.close()

结果为:
这是一个txt文件

这是第二行
True

只写(w)

在打开一个文件后,会将文件内容清空再写

用f.write()来表示

f = open('test.py','w',encoding='utf8')  # 只写  # 清空后再写
lt = ['sdklfj','sdkfjksldf']
res = '\n'.join(lt)
f.write(res)
print(f.readable())
print(f.writable())
f.writelines(['sdklfj','sdkfjksldf'])
f.close()

结果为:
False
True

可见只写里是无法读取的。

同时在text.py文件的内容变成了:

sdklfj
sdkfjksldfsdklfjsdkfjksldf

追加(a)

追加就和append一样,顾名思义,在文件的末尾添加上想添加的东西

用的也是f.write()

f = open('test.py','a',encoding='utf8')  # 追加  # 文件末追加
f.write('写的是什么东西啊')  
f.close()

test.py结果变为:

sdklfj
sdkfjksldfsdklfjsdkfjksldf写的是什么东西啊

with管理文件上下文

之前我们使用open()方法操作文件,但是open打开文件后我们还需要手动释放文件对操作系统的占用。但是其实我们可以更方便的打开文件,即Python提供的上下文管理工具——with open()

ith open('text.txt', 'rt', encoding='utf8') as f:
    print(f.read())
结果为:
这是一个txt文件
这是第二行

with open()方法不仅提供自动释放操作系统占用的方法,并且with open可以使用逗号分隔,一次性打开多个文件,实现文件的快速拷贝

with open('text.txt', 'rb') as fr, \
        open('text.py', 'wb') as fw:
    f.write(f.read())

在这里使用\时,虽然换行了,但是在Python中默认他还是同一行,这样操作和在同一行没什么分别,但是对于看这段代码的人来说,能更加清楚的知道了打开了几个文件,分别是什么

文件的高级应用

文件高级应用可以做到即可读又可写(尽量不要使用)

r+

r+的写入是在原本文件后面追加

# test.py 文件内容为 '''111'''

with open('test.py', 'r+', encoding='utf8') as fr:
    data = fr.read()
    print(fr.writable())
    fr.write('x = 10')
    print(data)
结果为:
True
'''111'''

文件内容变为'''111'''x = 10

注意此时打印的data没有x = 10 是因为在写之前就已经读取了

w+

清空文件的功能是W提供的,w+更不要使用

也就是说,f.write()并不是清空文件的罪魁祸首

with open('test.py', 'w+', encoding='utf8') as fr:
    print(fr.readable())
    fr.write('x = 10')
文件结果变为x = 10
with open('test.py', 'w+', encoding='utf8') as fr:
    # print(fr.readable())
    # fr.write('x = 10')
    data =  fr.read()
    print(data)

此时文件结果反而什么也没有,并不是不能用read,而是此时文件里已经什么也没有了。如果要问为什么,就是被w清空了

a+

a+则是在原本追加的情况下还能进行读取

with open('test.py', 'a+', encoding='utf8') as fr:
    data = fr.read()  
    print(data)

    fr.write('x = 10')
    fr.flush()

这个时候你就会发现,依旧是什么都没有打印,但是寻思a也没有清除文本内容呀?而且多次打印后发现,txt文件中的x越来越多,但是却什么都打印不出来。这里就涉及到了一个指针的问题,我会在接下来一一进行阐述

指针

指针是文件的内置方法,其实也就是当你鼠标点击某一行字的时候,那一闪一闪的竖就是指针。那么问题回到上面,为什么明明文本中有数据,但是read()却读不出来呢?这就是因为read函数是从指针的地方开始读,而a+默认指针是在文件的末尾,所以自然什么也读不出来了。之前说的只读模式里一次运行只能读取一次也是相同的道理。

seek

用于改变指针位置后读取

with open('test.py', 'rb') as fr:
    fr.seek(1)  # 1表示位移1位,默认从文件头开始
    fr.seek(1, 0)  # 1表示偏移1位,0表示从头开始(这里和第一个一样)
    fr.seek(2, 1)  # 1表示偏移1位,1表示从当前位置开始
    fr.seek(0, 2)  # 0表示偏移0位,2表示文件末开始,把指针移到文件末
    print(fr.read())
结果依次为:
b' = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10'
b' = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10'    
b' 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10x = 10'
b''

因此在配合seek之后,a+也可以读取文件了

with open('test.py', 'a+', encoding='utf8') as fr:
    fr.seek(1, 0)
    data = fr.read()
    print(data)

    fr.write('x = 10')
    fr.flush()

tell

同于告诉你指针的位置

with open('test.py', 'r', encoding='utf8') as fr:
    fr.seek(2, 0)
    print(fr.tell())	# 2

read(n)

可以读取文件中的字节

with open('test.py', 'r', encoding='utf8') as fr:
    print(fr.read(5))	# x = 1
    print(fr.read(6))	# x = 10 

truncate截断

只读模式无法使用。只写模式会清空文件,所以一般用于追加模式

with open('test.py', 'a', encoding='utf8') as fr:
    fr.truncate(2)	# 将 x 后的内容全部清空

文件修改的俩种方式

首先,文件其实并没有修改这一说法,只有覆盖这一说法

因为在你文件里的这段文字的前后,其实可能都满满的存放着别的东西。如果你在这段文字中加上一些东西,也就意味着后面的所有内存都要移动几格,这是不科学的。

而平时修改文件的时候,都是模拟出来的效果,具体的说有两种实现方式。

方式一

import os

with open('test.txt') as fr, \
        open('test_swap.txt', 'w') as fw:
    data = fr.read()  # 全部读入内存,如果文件很大,会很卡
    data = data.replace('tank', 'tankSB')  # 在内存中完成修改

    fw.write(data)  # 新文件一次性写入原文件内容

# 删除原文件
os.remove('test.txt')
# 重命名新文件名为原文件名
os.rename('test_swap.txt', '37r.txt')
print('done...')

方式二

import os

with open('37r.txt') as fr,\
        open('37r_swap.txt', 'w') as fw:
    # 循环读取文件内容,逐行修改
    for line in fr:
        line = line.replace('jason', 'jasonSB')
        # 新文件写入原文件修改后内容
        fw.write(line)

os.remove('37r.txt')
os.rename('37r_swap.txt', '37r.txt')
print('done...')

总而言之,修改文件内容的思路为:以读的方式打开原文件,以写的方式打开一个新的文件,把原文件的内容进行修改,然后写入新文件,之后利用os模块的方法,把原文件删除,重命名新文件为原文件名,达到以假乱真的目的

posted @ 2019-08-08 17:00  黑井白子  阅读(117)  评论(0编辑  收藏  举报
Live2D