python之文件处理

'''
一、文件处理流程
1、打开文件,得到文件句柄并复制给一个变量  

文件句柄 = open('文件路径', '模式')

2、通过句柄对文件进行操作
3、关闭文件
'''

#1. 打开文件,得到文件句柄并赋值给一个变量
f = open('111', encoding='utf-8')

#2、通过句柄对文件进行操作

data = f.read()
print(data)

#关闭文件 f.close()


强调!!
close()关闭文件
#强调第二点:
f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。
这就用到了上节课讲的字符编码的知识:若要保证不乱码,文件以什么方式存的,就要以什么方式打开。

f=open('a.txt','r',encoding='utf-8')
字符编码
二、文件模式:
#
1. 打开文件的模式有(默认为文本模式): r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】 w,只写模式【不可读;不存在则创建;存在则清空内容】 a, 之追加写模式【不可读;不存在则创建;存在则只追加内容】 #2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式) rb wb ab 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码 #3. 了解部分 "+" 表示可以同时读写某个文件 r+, 读写【可读,可写】 w+,写读【可读,可写】 a+, 写读【可读,可写】 x, 只写模式【不可读;不存在则创建,存在则报错】 x+ ,写读【可读,可写】 xb
# 文件打开模式:r w a-追加
读r,只读不可写
f = open('111', 'r', encoding='utf-8')
print(f.readable())
print('第1行', f.readline(), end='')  # 一次只能读一行,去掉换行
print(f.readlines())  # 读取成列表
f.close()

# 写w,只写模式不可读,有文件清空在写,没有文件创建新的
f = open('111', 'w', encoding='utf-8')
f.write('1111\n')
f.write('22222\n')
f.write('333\n444\n555\n')  # 字符串形式
print(f.writable())
f.writelines(['455\n', '666\n'])  # 列表形式,写的内容必须是字符串,不能有其他类型
f.close()

# 追加a,a调用的wirte,只是以追加的方式
f = open('111', 'a', encoding='utf-8')
f.write('写到文件最后\n')
f.close()

r+,读写  a+ 写读
f = open('2', 'r+', encoding='utf-8')
d = f.read()
print(d)
f.write('sb')  # 从文件光标在哪里,就显示在哪。文件数据本质上是覆盖,没有修改一说
f.close()

 

三、操作文件方法
#掌握
f.read() #读取所有内容,光标移动到文件末尾
f.readline() #读取一行内容,光标移动到第二行首部
f.readlines() #读取每一行内容,存放于列表中

f.write('1111\n222\n') #针对文本模式的写,需要自己写换行符
f.write('1111\n222\n'.encode('utf-8')) #针对b模式的写,需要自己写换行符
f.writelines(['333\n','444\n']) #文件模式
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式

#了解
f.readable() #文件是否可读
f.writable() #文件是否可读
f.closed #文件是否关闭
f.encoding #如果文件打开模式为b,则没有该属性
f.flush() #立刻将文件内容从内存刷到硬盘
f.name

 

 

with的写法
#复制文件内容到另一个文件
src_f = open('2','r',encoding='utf-8')
f1=src_f.readlines()
src_f.close()

for i in f1:
    print(i)
det_f=open('2_new','w',encoding='utf-8')
det_f.writelines(f1[0]) #只写某一行
det_f.close()

#上面代码用with 来实现,with自动关闭文件
with open('2','r',encoding='utf-8') as src_f,\
        open('2_new','w',encoding='utf-8') as det_f:
    data=src_f.read()
    det_f.write(data)

# b的方式不能指定编码
f = open('111', 'rb')
data = f.read()
# 字符串---decode ---->bytes
# bytes---encode ---->字符串
print(data)
print(data.decode('utf-8'))
f.close()

f1=open('111','wb')#wb
f1.write(bytes('你好啊\n',encoding='utf-8'))
f1.write('美女\n'.encode('utf-8'))

f1.close()
print(f1.closed)

f2 = open('111', 'ab')#ab
f2.write('美男\n'.encode('utf-8'))
f2.close()

#不知道源文件是什么格式用latin编码
f3=open('2.txt','r+',encoding='latin-1',newline='')
#newline读取文件中真正的换行符号

f3_data=f3.read()#read读字符
print(f3_data)
# f3.write('wawa3\n')

f3.flush()#将文件内容从内存刷到硬盘
print(f3.name) #文件名
print(f3.tell())#读取文件当前光标位置
f3.seek(2)  # 从开头开始算,将光标移动到第2个字节

print(f3.read(4))#read(4)代表读取4个字符,其余的文件内光标移动都是以字节为单位的如seek、tell、read、truncate

print(f3.truncate(10))#从开头开始算,将文件只保留从0-10个字节的内容,文件必须以写方式打开,但是w和w+chuwei 
f3.close()
四 文件内光标移动
  一: read(3):

    1. 文件打开方式为文本模式时,代表读取3个字符
  
    2. 文件打开方式为b模式时,代表读取3个字节

  二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate

  注意:

    1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

    2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
# seek是字节的方式,需要用到b模式
f4 = open('2.txt', 'rb')  # 默认Windows系统编码gbk
print(f4.tell())
f4.seek(10, 0)  # 0从未见开头数,数10个字节
print(f4.tell())
f4.seek(3, 1)  # 1相对位置,相对于上一次光标的位置
print(f4.tell())
f4.seek(-10, 2)  # 2从文件末尾开始,seek 10
print(f4.tell())

# 循环文件的推荐方式
# 只要读出最后一行
for i in f4:
    offs = -10
    while True:
        f4.seek(offs, 2)
        data = f4.readlines()
        if len(data) > 1:
            print('最后一行是%s' % (data[-1].decode('utf-8')))
            break

        offs *= 2

f4.close()

五、文件修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:

方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
import os

with open('11.txt') as read_f,open('.11.txt.swap','w') as write_f:
    data=read_f.read() #全部读入内存,如果文件很大,会很卡
    data=data.replace('tom','love') #在内存中完成修改

    write_f.write(data) #一次性写入新文件

os.remove('11.txt')
os.rename('.11.txt.swap','a.txt') 

方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

import os

with open('11.txt') as read_f,open('.11.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('tom','xx')
        write_f.write(line)

os.remove('11.txt')
os.rename('.11.txt.swap','11.txt') 

 练习:

1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数,求出本次购物花费的总钱数
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3

2. 修改文件内容,把文件中的mac都替换成xx,
(使用正则表达式 替换文件内容 re.sub 方法替换,import re)
import os,re
num=0
with open('111','r',encoding='utf-8') as f,open('22.txt','w',encoding='utf-8') as w:
    data=f.read().split('\n')
    #1
    for i in data:
        line=i.split(' ')
        num+=int(line[1])*int(line[2])

    #2
    #列表转成字符串(列表里的元素是str类型)
    data1=''.join((data))

    # python 使用正则表达式 替换文件内容 re.sub 方法替换
    # 但是不会自动换行,不知道怎么搞了
    w.write(re.sub('mac','xxx',data1)) 

#前面代码先修改了源文件后复制到新文件,再删除源文件,用新文件重命名为源文件名
# os.remove('111')
# os.rename('22.txt','111')

print(num)
View Code

 

 



 

posted @ 2022-08-02 22:33  ilspring  阅读(576)  评论(0)    收藏  举报