python文件操作

python文件操作

为了长期保存数据以便重复使用、修改和共享,必须将数据以文件的形式存储到外部存储介质(如磁盘、U盘、光盘或云盘、网盘、快盘等)中。文件作在各类应用软件的开发中均占有重要的地位。

按照文件中的数据组织形式,将文件分为文本文件和二进制文件。

  1. 文本文件:储存常规字符,由若干文本行组成,通常以换行符结尾,常规字符串是指记事本或者其他文编编辑器能够正常显示、编辑并且人类能够直接阅读和理解的字符串。如英文字母、汉字、数字字符串。
  2. 二进制文件:二进制文件把对象内容以字节串(bytes)进行储存,通常无法直接被人类阅读和理解,**需要使用专门的软件对其进行解码后读取、显示、修改或执行。常见的有如图形图像文件、音视频文件、可执行文件、资源文件、各种数据库文件、各类office文档

文件对象

Python内置了文件对象,通过open()函数即可以指定模式打开指定文件并创建为文件对象,语法为:

open(file, mode='r',buffering=-1,encoding=None,errors=None,newline=None,closefd=True, opener=None)

  • file参数指定了被打开的文件名称

  • mode参数指定了打开文件后的处理方式

  • buffering参数指定了读写文件的缓存模式。0表示不缓存,1表示缓存,如大于1则表示缓冲区的大小。默认值-1表示由系统管理缓存。

  • encoding参数指定对文本进行编码和解码的方式,只适用于文本模式,可以使用Python支持的任何格式,如GBK、utf8、CP936等等。

f1 = open('file1.txt', 'r')     # 以读模式打开文件
f2 = open('file2.txt', 'w')      # 以写模式打开文件

f1.close()#当对文件内容操作完以后,一定要关闭文件对象,这样才能保证所做的任何修改都确实被保存到文件中。

文件打开方式

模式说明
r读模式(默认模式,可省略),如果文件不存在,则就抛出异常
w写模式,如果文件已经存在,会先清空原有内容
x写模式
a追加模式不覆盖原有内容
b二进制模式(可与其他模式组合使用)
t文本模式(默认模式,可省略)
+读+写,模式(可与其他模式组合使用)

文件对象常用方法

方法功能说明
close()把缓冲区的内容写入文件,同时关闭文件,并释放文件对象
read([size])从文本文件中读取size字符的内容作为结果返回,或从二进制文件中读取指定数量的字节并返回,如果省略size则表示读取所有内容
readable()测试当前文件是否可读
readline()文本文件中读取一行内容作为结果返回
readlines()文本文件中的每行文本作为一个字符串存入列表中,返回该列表,对于大文件会占用较多内存,不建议使用
seek(offset[,whence])把文件指针移动到新的字节位置,offset表示相对于whence的位置。whence0表示从文件头开始计算,1表示从当前位置开始计算,2表示从文件尾开始计算,默认为0
write(s)把s的内容写入文件
writable()测试当前文件是否可写
writelines(s)把字符串列表写入文本文件,不添加换行符

with 语句

即使写了关闭文件的代码,也无法保证文件一定能够正常关闭,例如,如果在打开文件之后和关闭文件之前发生了错误导致程序崩溃,这时文件就无法正常关闭。在管理文件对象时推荐使用with关键字,可以有效地避免这个问题。

with语句的用法如下:

with open(filename, mode, encoding) as fp:
    #这里写通过文件对象fp读写文件内容的语句
    
#上下文管理语句with还支持下面的用法:
with open('test.txt', 'r') as src, open('test_new.txt', 'w') as dst:
    dst.write(src.read())

seek()方法

seek()方法把文件指针定位到文件中指定字节的位置。读取时遇到无法解码的字符会抛出异常。

seek() 方法语法如下:

fileObject.seek(offset[, whence])
  • offset :文件中读/写指针的位置。

  • whence :(可选)0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。

二进制文件

使用pickle模块读取二进制文件

import pickle

with open('sample_pickle.dat', 'rb') as f:
    n = pickle.load(f)        #读出文件的数据个数
    for i in range(n):
        x = pickle.load(f)
        print(x)

使用struct模块写入二进制文件。

import struct

n = 1300000000
x = 96.45
b = True
s = 'HELLO'
sn = struct.pack('if?', n, x, b)       #序列化
with open('sample_struct.dat', 'wb') as fp:
    fp.write(sn)                       #写入字节串 
    fp.write(s.encode())               #字符串直接编码为字节串写入

使用struct模块读取二进制文件

import struct

with open('sample_struct.dat', 'rb') as fp:
    sn = fp.read(9)
    tu = struct.unpack('if?', sn) 
    print(tu)
    n, x, bl = tu
    print('n=', n)
    print('x=', x)
    print('bl=', bl)
    s = fp.read(9).decode()
    print('s=', s)

使用shelve序列化

Python标准库shelve也提供了二进制文件操作的功能,可以像字典赋值一样来写入二进制文件,也可以像字典一样读取二进制文件

import shelve

zhangsan = {'age':38, 'sex':'Male', 'address':'SDIBT'}
lisi = {'age':40, 'sex':'Male', 'qq':'1234567', 'tel':'7654321'}
with shelve.open('shelve_test.dat') as fp:
 fp['zhangsan'] = zhangsan      # 像操作字典一样把数据写入文件
 fp['lisi'] = lisi
  for i in range(5):
    fp[str(i)] = str(i)
with shelve.open('shelve_test.txt') as fp:
        print(fp['zhangsan'])                 #读取并显示文件内容
        print(fp['zhangsan']['age'])
        print(fp['lisi']['qq'])
        print(fp['3'])

案例

向文本文件中写入内容,然后再读出。
s = "Hello World!\n世界你好!\n"
with open("sample.txt","w") as fp:   # 默认使用cp936编码
    fp.write(s) 	#写入文件
with open('sample.txt') as fp:         #默认使用cp936编码
    print(fp.read())	#读取文件

读取并显示文本文件的前5个字符。

with open('sample.txt', 'r') as f:
    s = f.read(5)

print('s=',s)
print('字符串s的长度(字符个数)=', len(s))

读取并显示文本文件所有行。

with open('sample.txt') as fp:      #假设文件采用CP936编码
    for line in fp:                 #文件对象可以直接迭代
        print(line)

移动文件指针,然后读取并显示文本文件中的内容。

批量修改文本文件编码格式。
#方法一
import os

# 获取当前文件夹中所有记事本文件清单
fns = (fn for fn in os.listdir() if fn.endswith('.txt'))
for fn in fns:
    try:
        # 首先尝试使用UTF8编码打开并读取文件内容
        # 如果失败会抛出异常
        with open(fn, encoding='utf8') as fp:
            fp.read()
    except:
        # 以默认的GBK编码读取原文件内容
        # 以UTF8编码写入新文件
        with open(fn) as fp1:
            with open('t.txt', 'w', encoding='utf8') as fp2:
                fp2.write(fp1.read())
        # 删除原文件,把新文件重命名为原文件
        os.remove(fn)
        os.rename('t.txt', fn)   
#方法二
from os import listdir

fns = (fn for fn in listdir() if fn.endswith('.txt'))
for fn in fns:
    with open(fn, 'rb+') as fp:
        content = fp.read()
        try:
            # 尝试使用UTF8解码
            content.decode('utf8')
        except:
            # 使用GBK解码后再使用UTF8编码,写回文件
            content = content.decode('gbk').encode('utf8')
            fp.seek(0)
            fp.write(content)
#方法二
from os import listdir
from chardet import detect

fns = (fn for fn in listdir() if fn.endswith('.txt'))
for fn in fns:
    with open(fn, 'rb+') as fp:
        content = fp.read()
        # 判断编码格式
        encoding = detect(content)['encoding']
        # 格式转换
        content = content.decode(encoding).encode('utf8')
        # 写回文件
        fp.seek(0)
        fp.write(content)


自学笔记,仅供参考
21/11/22

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值