Python常见读写文件操作实例总结【文本、json、csv、pdf等】


Posted in Python onApril 15, 2019

本文实例讲述了Python常见读写文件操作。分享给大家供大家参考,具体如下:

读写文件

读写文件是最常见的IO操作,python内置了读写文件的函数,用法和c是兼容的.

读写文件前,我们必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以读写文件就是请求操作系统打开一个文件对象(文件描述),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件).

1、读文件

要以读文件的模式打开一个文件对象,使用python内置的open()函数,传入文件名和标识符:

f = open("t1.txt","r",encoding="utf-8")

标识符'r'表示读。

如果文件不存在,open()函数就会抛出一个IOError的错误,并且会给出详细的错误码和信息,告诉你文件不存在。

f = open("t122.txt","r",encoding="utf-8")

Traceback (most recent call last):
  File "D:/Learn/python/day14/test.py", line 1, in <module>
    f = open("t122.txt","r",encoding="utf-8")
FileNotFoundError: [Errno 2] No such file or directory: 't122.txt'

如果文件打开成功,接下来,调用read()方法可以一次性读取文件的全部内容,python把内容读取到内存,用一个str对象表示。

print(f.read())

输出:

hello world!

最后一步调用close()方法关闭文件,文件使用完毕之后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限制的。

f.close()
f = open(r"文件地址","读取方式",encoding="utf-8")

"r":以只读方式
encoding:读取的编码格式
f.read() :一次性读取文件全部内容
f.close():关闭流
r"文件地址":不让转义字符“\”起作用

由于文件读写都有可能产生IOError,一旦出错,后面的f.close()就不会调用,所以,为了保证文件不管是否执行出错都能够正确的关闭文件,我们可以使用try … finally来实现.

try:
 f = open("t1.txt", "r", encoding="utf-8")
 print(f.read())
finally:
 if f:
  f.close()

但是每次都这么写实在太繁琐,所以,引入了with语句来自动帮我们调用close()方法:

with open("t1.txt", "r", encoding="utf-8") as f:
 print(f.read())

这和前面的try…finally是一样的,但是代码更加简洁,并且不必调用f.close()方法。

注意: 使用read()会一次性读取文件的全部内容,如果你的文件特别大,比如说有5G,那么你的内存就爆了,所以,为了保险起见,我们可以反复调用read(size)方法,每次最多读取size个字节内容,另外调用readline()可以每次读取一行内容,调用readlines()一次性读取所有的内容,并按行返回list,因此,要根据需要决定怎么调用。

如果文件很小,read()一次读取最方便,如果不能确定文件大小,反复调用read(size)比较保险,如果是配置文件,调用readlines()最方便。

for line in f.readlines():
 #把末尾的'\n'删掉
 print(line.strip())

2、二进制文件

前面讲的默认都是读取文本文件,并且是UTF-8编码的文本文件,要读取二进制文件,比如图片,视频等等,用'rb'模式打开文件即可:

f = open("tigle.jpg", "rb")
print(f.read())
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节

3、字符编码

要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件:

f = open('/user/demo/gbk.txt','r',encoding = 'gbk')
f.read()
'测试'

遇到有些编码不规范的文件,你可能遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符,遇到这种情况,open()函数还接收一个error参数,表示如果遇到编码错误之后如何处理,最简单的办法就是直接忽略。

f = open('/users/demo/gbk.txt','r',encoding = 'gbk',errors = 'ignore')

4、写文件

写文件和读文件都是一样的,唯一的区别就是调用open()函数时,传入标识符'w'或者'wb'表示写文件或写二进制文件:

f = open("/users/demo/test.txt",'w')
f.write('hello, world!')
f.close()

你可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件.

当我们写入文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入,只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘,忘记调用close()的后果是数据可能只写了一部分到磁盘,剩余的丢失了,所以,还是使用with语句来的保险:

with open('/users/demo/test.txt', 'w') as f:
 f.write('hello, world')

要写入特定编码的文本文件,请给open()函数传入encoding参数,将字符串自动转成指定编码。

以'w'模式写入文件时,如果文件已经存在,直接覆盖(相当于删掉后新写入一个文件),如果我们希望追加到文件的末尾怎么办?可以传入'a'以追加模式写入。

with open('/users/demo/test.txt', 'a') as f:
 f.write('hello, world')

5、StringIO

很多时候,数据读写不一定是文件,也可以在内存读写.

stirngIO顾名思义就是在内存中读写str。

要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:

from io import StringIO
f = StringIO()
f.write("hello")
f.write(" ")
f.write('world')
#获取写入后的str
print(f.getvalue())

输出:

hello world

要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:

from io import StringIO
f = StringIO("Hello\nHi\nGoodBye!")
while True:
 s = f.readline()
 if s == '':
  break
 # 去掉换行符
 print(s.strip())

输出:

Hello
Hi
GoodBye!

6、BytesIO

StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。

BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:

from io import BytesIO
f = BytesIO()
f.write("中文".encode('utf-8'))
print(f.getvalue())

输出:

b'\xe4\xb8\xad\xe6\x96\x87'

注意:写入的不是str,而是经过UTF-8编码的bytes。

和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:

from io import BytesIO
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
d = f.read()
print(d)
print(d.decode())

输出:

b'\xe4\xb8\xad\xe6\x96\x87'
中文

StringIO和BytesIO是在内存中操作str和bytes的方法,使得读写文件具有一致的接口.

7、序列化

在程序运行的过程中,所有的变量都是在内存中,比如定义一个dict

dict1 = {name:"lili",age:18}

在这里我把name进行修改,改成”leilei“,但是一旦程序结束,变量所占用的内存就会被操作系统全部回收,如果没有把修改的name存到磁盘上,下次name初始化的时候又是”lili“

在这里我们把变量从内存中变成可存储或者传输的过程称之为序列化,在python中叫picking,序列化之后,我们就可以把序列化后的内容写入磁盘,或是通过网络传输到别的机器上。反之,把变量内容从序列化的对象重新读取到内存里称之为反序列化,即unpicking。

python提供了pickle模块来实现序列化。

import pickle
d = dict({"name":"lili","age":18})
#pickle.dumps()方法把任意对象序列化成一个bytes,然后就可以把bytes写入文件
print(pickle.dumps(d))
#把序列化后的对象写入文件
f = open("t1.txt",'wb')
#参数一:要写入的对象, 参数二:写入文件的对象
pickle.dump(d,f)
f.close()
#从文件中读取序列化后的对象
f2 = open("t1.txt","rb")
#pickle.load()反序列化对象
d = pickle.load(f2)
f2.close()
print(d)
print(type(d))

输出:

{'name': 'lili', 'age': 18}
<class 'dict'>

注意:pickle只能用于python,并且不同版本的python彼此都不兼容,因此,只能用pickle保存一些不重要的数据,这样即使不能成功的反序列化也没什么关系。

8、Json

如果我们需要在不同的编程语言之间传递对象,那么我们必须把对象序列化成标准化格式,比如xml,但是更好的方法是json,因为json表现出来就是一个字符串,可以被所有的语言读取,也方便存储到磁盘或者网络传输,json不仅是标准模式,并且速度也比xml更快,还可以在web中读取,非常方便。

JSON类型 Python类型
{} dict
[] list
“string” str
1234.56 int或float
true/false True/False
null None

把python的dict对象变成一个json

import json
dict1 = {"name":"lili","age":18}
ji = json.dumps(dict1)
print(type(ji))
with open("dd.txt","w") as f:
 json.dump(dict1,f)
with open("dd.txt","r",encoding="utf-8") as f:
 du = json.load(f)
 print(du)
 print(type(du))

输出:

<class 'str'>
{'name': 'lili', 'age': 18}
<class 'dict'>

将一个class对象序列化为json

import json
class Student(object):
 def __init__(self, name, age, score):
  self.name = name
  self.age = age
  self.score = score
# 将student对象转换为dict
def student2dict(std):
 return {
  'name': std.name,
  'age': std.age,
  'score': std.score
 }
s = Student('Bob', 20, 88)
# 参数一:要传入的对象 参数二:将对象转为dict的函数
d = json.dumps(s, default=student2dict)
# 将dict转为对象
def dict2student(d):
 return Student(d['name'], d['age'], d['score'])
jsonStr = '{"age": 20, "score": 88, "name": "Bob"}'
# json反序列化为一个对象
# 参数一:json字符串,参数二:dict转为对象的函数
print(json.loads(jsonStr, object_hook=dict2student))
# 写入文件
with open("t1.txt","w") as f:
 f.write(d)
 #或者直接使用下面的语句
 #json.dump(s,f,default=student2dict)
# 读取文件
with open("t1.txt","r",encoding="utf-8") as f:
 du = json.load(f,object_hook=dict2student)
print(du)

输出:

<__main__.Student object at 0x000002CA795AA0F0>
<__main__.Student object at 0x000002CA7975B0F0>

9、读写csv文件

①、读csv文件

csv文件本身就是个纯文本文件,这种文件格式经常用来作为不同程序之间的数据交互的格式.

演示:

需求:读取001.scv文件

说明:可以直接打印,然后定义list

import csv
def readCsv(path):
 #列表
 infoList = []
 #以只读的形式打开文件
 with open(path, 'r') as f:
  #读取文件的内容
  allFileInfo = csv.reader(f)
  #将获取到的内容逐行追加到列表中
  for row in allFileInfo:
   infoList.append(row)
 return infoList
path = r"C:\Users\xlg\Desktop\001.csv"
info = readCsv(path)

②、写csv文件

演示:

需求:向002.csv文件中写入内容

import csv
#以写的方式打开文件
def writeCsv(path,data):
 with open(path,'w',newline='') as f:
  writer = csv.writer(f)
  for rowData in data:
   print("rowData =", rowData)
   #按行写入
   writer.writerow(rowData)
path = r"C:\Users\xlg\Desktop\002.csv"
writeCsv(path,[[1,2,3],[4,5,6],[7,8,9]])

10、读取pdf文件

pip是一个安装和管理python包的工具

在进行代码演示之前,首先进行安装和pdf相关的工具

a.在cmd中输入以下命令: pip list [作用:列出pip下安装的所有的工具]

b.安装pdfminer3k,继续输入以下命令:pip install pdfminer3k

c.代码演示

import sys
import importlib
importlib.reload(sys)
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter #解释器
from pdfminer.converter import PDFPageAggregator #转换器
from pdfminer.layout import LTTextBoxHorizontal, LAParams #布局
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed #是否允许pdf和text转换
def readPDF(path, toPath):
 #以二进制形式打开pdf文件
 f = open(path, "rb")
 #创建一个pdf文档分析器
 parser = PDFParser(f)
 #创建pdf文档
 pdfFile = PDFDocument()
 #链接分析器与文档对象
 parser.set_document(pdfFile)
 pdfFile.set_parser(parser)
 #提供初始化密码
 pdfFile.initialize()
 #检测文档是否提供txt转换
 if not pdfFile.is_extractable:
  raise PDFTextExtractionNotAllowed
 else:
  #解析数据
  #数据管理器
  manager = PDFResourceManager()
  #创建一个PDF设备对象
  laparams = LAParams()
  device = PDFPageAggregator(manager, laparams=laparams)
  #解释器对象
  interpreter = PDFPageInterpreter(manager, device)
  #开始循环处理,每次处理一页
  for page in pdfFile.get_pages():
   interpreter.process_page(page)
   layout = device.get_result()
   for x in layout:
    if (isinstance(x, LTTextBoxHorizontal)):
     with open(toPath, "a") as f:
      str = x.get_text()
      #print(str)
      f.write(str+"\n")
path = r"0319开始.pdf"
toPath = r"n.txt"
readPDF(path, toPath)

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
使用IPython来操作Docker容器的入门指引
Apr 08 Python
整理Python最基本的操作字典的方法
Apr 24 Python
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
Apr 19 Python
python中数组和矩阵乘法及使用总结(推荐)
May 18 Python
Kali Linux安装ipython2 和 ipython3的方法
Jul 11 Python
django使用admin站点上传图片的实例
Jul 28 Python
python处理excel绘制雷达图
Oct 18 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
Jan 10 Python
Python无头爬虫下载文件的实现
Apr 02 Python
pymongo insert_many 批量插入的实例
Dec 05 Python
python中str内置函数用法总结
Dec 27 Python
python小程序之飘落的银杏
Apr 17 Python
10招!看骨灰级Pythoner玩转Python的方法
Apr 15 #Python
Python后台开发Django会话控制的实现
Apr 15 #Python
浅析Python 实现一个自动化翻译和替换的工具
Apr 14 #Python
提升Python程序性能的7个习惯
Apr 14 #Python
Python根据当前日期取去年同星期日期
Apr 14 #Python
Python实现的微信支付方式总结【三种方式】
Apr 13 #Python
Python实现合并excel表格的方法分析
Apr 13 #Python
You might like
PHP的反射类ReflectionClass、ReflectionMethod使用实例
2014/08/05 PHP
php实现用于计算执行时间的类实例
2015/04/18 PHP
Yii框架常见缓存应用实例小结
2019/09/09 PHP
一个基于jquery的文本框记数器
2012/09/19 Javascript
基于datagrid框架的查询
2013/04/08 Javascript
chrome浏览器不支持onmouseleave事件的解决技巧
2013/05/31 Javascript
JS文本框追加多个下拉框的值的简单实例
2013/07/12 Javascript
常用的JavaScript验证正则表达式汇总
2013/11/26 Javascript
js如何判断用户是在PC端和还是移动端访问
2014/04/24 Javascript
node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
2014/11/04 Javascript
jQuery中end()方法用法实例
2015/01/08 Javascript
JavaScript对HTML DOM使用EventListener进行操作
2015/10/21 Javascript
js实现网页定位导航功能
2017/03/07 Javascript
微信小程序实战之上拉(分页加载)效果(2)
2017/04/17 Javascript
通过学习bootstrop导航条学会修改bootstrop颜色基调
2017/06/11 Javascript
浅谈webpack devtool里的7种SourceMap模式
2019/01/14 Javascript
详解vue-cli3开发Chrome插件实践
2019/05/29 Javascript
JS实现前端路由功能示例【原生路由】
2020/05/29 Javascript
浅谈使用nodejs搭建web服务器的过程
2020/07/20 NodeJs
Python实现全局变量的两个解决方法
2014/07/03 Python
使用Python的Treq on Twisted来进行HTTP压力测试
2015/04/16 Python
Python的gevent框架的入门教程
2015/04/29 Python
Python遍历文件夹和读写文件的实现代码
2016/08/28 Python
Python使用requests及BeautifulSoup构建爬虫实例代码
2018/01/24 Python
python的concat等多种用法详解
2018/11/28 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
python中Django文件上传方法详解
2020/08/05 Python
CSS3 animation实现简易幻灯片轮播特效
2016/09/27 HTML / CSS
探讨HTML5移动开发的几大特性(必看)
2015/12/30 HTML / CSS
物流仓管员岗位职责
2013/12/04 职场文书
中学家长会邀请函
2014/01/17 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
人事局接收函
2015/01/31 职场文书
幼儿园感恩节活动总结
2015/03/24 职场文书
2015国庆节感想
2015/08/04 职场文书
2019 入党申请书范文
2019/07/10 职场文书