文件路径
相对路径
- 文件/文件夹的上一层:../, 一个路径中可以写多个../
- 相对路径是相对于当前文件的路径,../是按照从左往右的方向来执行,越往左和当前文件的就越近
f = open('../re_st/article/file.txt',
# 当前程序文件在re_st中,../回到上一层文件夹,找到re_st文件夹,再往下找
# 相对路径的关键点在于找到两个文件的共同文件夹
mode='a', encoding='utf-8')
f.write(' 功夫熊猫 ')
f.close()
绝对路径
- 第一种:文件在本地磁盘中的绝对路径
- 第二种:互联网上的网页中的绝对路径
文件的读写模式
读写模式 ‘r+’
with open('../re_st/article/file.txt', mode='r+',
encoding='utf-8') as f:
a = f.read()
f.write('测试')
print(a)
f.close()
'''
注意:r+模式中光标默认是在文件的开头位置,如果直接先写后读会导致开头位置的内容直接被覆盖掉,
如果先读后写,那么光标读到文件末尾,再执行写的操作,就不会出现覆盖的问题,这一点必须注意。
'''
写读模式 ‘w+’
with open('../re_st/article/file.txt', mode='w+',
encoding='utf-8') as f:
f.write('w+模式')
f.flush()
f.seek(0)
'''
注意:在该模式下是先写后读,那么光标问题也是需要注意的,内容写完之后光标停在了文件的末尾,
此时再执行读的操作结果是什么都读不到,那么必须执行seek操作,让光标回到指定的位置再开始读,
0表示的是开头位置,w+也会清空掉原文件。默认的w+用不到。
'''
r = f.read()
print(r)
追加读写模式 ‘a+’
# a+模式
with open('../re_st/article/file.txt', mode='a+',
encoding='utf-8') as f:
f.write('功夫熊猫')
f.flush()
f.seek(0)
# 同w+模式一样也需要注意光标的问题
r = f.read()
print(r)
只读模式 ‘r’
with open('../re_st/article/file.txt',
mode='r', encoding='utf-8') as f:
f.flush()
a = f.read()
print(a)
f.close()
只写模式 ‘w’, 这种模式是直接清空原文件内容
f = open('../re_st/article/file.txt',
mode='w', encoding='utf-8')
f.write(' 乌龟大师 ')
f.close()
# 必须加上close()
字节写模式 ‘rb’
with open('../re_st/article/file.txt',
mode='wb') as f:
context = '测试wb模式输入字节'
context = context.encode('utf-8')
f.write(context)
f.close()
# 如果希望输入的是字节,则必须先把内容进行编码操作,在写入文件
字节读模式 ‘wb’ ```python with open(‘../re_st/article/file.txt’,
mode='rb') as f:
f = f.read() print(f) print(f.decode(‘utf-8’))
读取字节用到的是rb模式,注意由于编辑器的原因,可能rb模式上不支持f.close()用法
- 追加写模式 'a',这种模式是在原文件基础上增加,不会清空原文件
```python
f = open('../re_st/article/file.txt',
mode='a', encoding='utf-8')
f.write(' 乌龟大师 ')
f.close()
# 必须加上close()
- 字节追加写模式 ‘ab’
with open('../re_st/article/file.txt',
mode='ab') as f:
context = '测试ab模式输入字节'
context = context.encode('utf-8')
f.write(context)
f.close()
Note r、w、r+模式用于文本操作 rb、wb模式用于非文本操作, b—->byte
光标
光标表示的是移动的字节数,默认开头为0,移动一个字节,数量加1,在读取文件的时候可以在read()括号内填件移动光标的数值,表示读取几个字节的内容,如果下次读取直接从当前的光标出来读取,不是从文件的开头进行读取。seek(字节数)可以使得光标回到指定的位置。
光标深坑
- 当r+模式下不管前边读取几个,后边的写操作都是从文件结尾处开始的
- write之前没有任何操作的情况下,写的操作是在文件的开头位置(覆盖掉开头的位置内容)
- write之前有任何操作的情况下,写的操作是在文件的末尾位置(也是覆盖,但是末尾没有内容,覆盖的是空格,此时是追加写的)
- seek(光标数)
- 光标数的单位是字节,每一种编码表示的所对应的文字的字节是不一样的,在utf-8编码类型下,三个字节代表一个汉字
- seek(0)回到开头的位置,seek(0, 2)到文件末尾的位置
- read(数值),注意这里的数值表示的是读取几个字符,中文表示的就是汉字,需要和seek中的字节区分
- tell()获取光标当前所在的位置,字节数,不是字符
'''
file.txt
'''
取其精华,去其糟粕取其精华,去其糟粕取其精华,去其糟粕取其精华,去其糟粕取其精华,去其糟粕测试程序测试程序测试程序测试程序测试程序测试程序测试程序
-----------------
'''
程序
'''
with open('../re_st/article/file.txt', mode='r+',
encoding='utf-8') as f:
f.seek(12)
# 移动12个字节
r1 = f.read(3)
# 读取三个汉字
f.write('测试程序')
# 光标在文件末尾开始执行写的操作
f.seek(0)
# 回到文件开头
f.seek(45)
# 移动45个字节,15个汉字包括标点符号
r2 = f.read(4)
# 读取4个汉字
f.seek(0,2)
l = f.tell()
print(r1)
print(r2)
print(l)
f.close()
修改文件中的内容
原文件是不能直接修改的,如果希望修改里边的内容必须先把原文件的内容全部拷贝修改完之后保存在新的文件中,在通过os模块把原文件删除,将新文件重命名为原文件的名字
# 修改文件中的内容
import os
with open('../re_st/article/eat.txt', mode='r',
encoding='utf-8') as f1, open('../re_st/article/eat_copy.txt', mode='w',
encoding='utf-8') as f2:
# 通过with..as..同时打开原文件,只读,新建文件只写
context = f1.read()
context = context.replace('庆丰包子铺', '凉皮')
# 读取所有的内容赋值给变量,通过字符串中的replace方法对内容进行修改
f2.write(context)
# 把修改后的内容保存在新的文件中
f1.close()
f2.close()
os.remove('../re_st/article/eat.txt')
# 删除原文件
os.rename('../re_st/article/eat_copy.txt', '../re_st/article/eat.txt')
# 通过rename对新的副本文件重命名为原文件的名字
# 此时修改工作完成
文件内容逐行读取及遍历读取文件所有的内容
读取一行(逐行读取): readline()
with open('../re_st/article/eat.txt', mode='r',
encoding='utf-8') as f:
r1 = f.readline()
r2 = f.readline()
# deadline()只读取一行,写一次读取从当前位置开始读
f.close()
print(r1)
print(r2)
遍历读取所有的内容
# 使用文件句柄字节循环逐行打印所有的内容
with open('../re_st/article/eat.txt', mode='r',
encoding='utf-8') as f:
for line in f:
print(line)
'''
readline()打印的用法和列表中通过下标索引获取元素的方式是一样的,
所以可以把文件当作一个整体,在文件句柄中直接循环打印出每一行, 在
打印全部文件上这种方式是最可取的,如果文件过大,直接read()所有的内容,
电脑系统会承受不了。
'''
f.close()
Note 需要注意的是readlines()和for循环遍历都可以实现把文件中所有的内容全部读取出来,但是相比较而言,for循环执行的效率更高。