Date: 2019-05-28
Author: Sun
文件的处理包括读文件和写文件,读写文件就是请求操作系统打开一个文件对象,然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)
文件读取可分为以下步骤:
打开文件要使用open内建函数:
open(file [, mode=‘r‘, encoding=None, errors=None])
参数说明:
? file:文件路径,可以是相对路径和绝对路径
? mode:文件打开模式
encodeing: 文件编码方式,不用于二进制文件,一般是utf-8,gbk
? errors:指定如何处理编码和解码错误 ,适用于文本文件
返回值:一个可迭代的文件对象
mode | 解释 |
---|---|
r | 只读 |
w | 写之前会清空文件的内容 |
a | 追加的方式,在原本内容中继续写 |
r+ | 可读可写 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
b | rb、wb、ab、rb+、wb+、ab+意义和上面一样,用于二进制文件操作 |
注意:二进制文件一般用于视频、音频、图片
读取文件常用函数:
函数 | 解释 |
---|---|
read([size]) | 读取文件(读取size字节,默认读取全部) |
readline([size]) | 读取一行,如果指定size,将读入指定的字符数 |
readlines() | 把文件内容按行全部读入,返回一个包含所有行的列表 |
#打开文件
fp = open('qfile.txt','r',encoding='utf-8')
#读取文件全部内容
#content = fp.read()
#print(content)
#读取指定字符数,包括行尾的换行符\n
# print(fp.read(20))
#读取一行
# print(fp.readline(5)) #读取指定字符数
# print(fp.readline()) #读取一整行,直到碰到一个\n
#读取所有行,返回列表
# print(fp.readlines())
#关闭文件
fp.close()
#由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。
# 所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:
# try:
# fp = open('qfile.txt','r',encoding='utf-8')
# print(fp.readlines())
# finally:
# fp.close()
#可以简写为:
#with语句会自动调用close方法关闭文件
with open('qfile.txt','r',encoding='utf-8') as fp:
print(fp.readline())
#fread()和freadlines()会一次读入文件全部内容,如果文件太大,会直接耗尽内存的,因为文件对象可迭代,所以可以用for循环遍历文件读取
with open('qfile.txt','r',encoding='utf-8') as fp:
for line in fp:
print(line.strip()) #注意无论是read、readline、readlines都会读入行末的\n,所以需要手动剔除\n
读取大文件
比如给你一个10G大文件,如何读取?
python文件对象提供了三个“读”方法: .read()
、.readline()
和 .readlines()
。
.read()
每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而.read()
生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。
处理大文件是很容易想到的就是将大文件分割成若干小文件处理,处理完每个小文件后释放该部分内存。这里用了iter 和 yield
(关于yield和iter是属于生成器的,后续章节会讲到)
# -*- coding: utf-8 -*-
__author__ = 'sun'
__date__ = '2019/5/28 18:26'
def read_in_chunks(filePath, chunk_size=1024*1024):
"""
Lazy function (generator) to read a file piece by piece.
Default chunk size: 1M
You can set your own chunk size
"""
file_object = open(filePath)
while True:
chunk_data = file_object.read(chunk_size)
if not chunk_data:
break
yield chunk_data
def process(chunk):
'''
do some data with chunk.
:param chunk:
:return:
'''
pass
if __name__ == "__main__":
filePath = './path/filename'
for chunk in read_in_chunks(filePath):
process(chunk)
关于读取大文件,经常在面试过程中被问到,其实采用map-reduce原理来解决此类问题是最佳方案。
将大块文件数据分块读取,然后分发到不同的线程或者进程中处理,也就是map思想,采用分而治之的思想处理每块数据,然后进行reduce结果合并最终结果数据。
path = "file11.txt"
#IO流
#1.打开文件
f = open(path,"w",encoding="utf-8")
#2.写入内容,将内容写入到缓冲区
#不会自动换行,需要换行的话,需要在字符串末尾添加换行符
f.write("Whatever is worth doing is worth doing well该行很骄傲很关键\n")
#3.刷新缓冲区【加速数据的流动,保证缓冲区的流畅】
f.flush()
#4.关闭文件 关闭文件也会刷新缓冲区
f.close()
#简写方式:可以不用手动调用close
with open(path,"w",encoding="utf-8") as f1:
f.write("Whatever is worth doing is worth doing well该行很骄傲很关键")
文件是顺序向后读写的,如果想要移动文件指针,可以使用seek方法:
file_obj.seek(offset,whence=0)
功能:移动文件指针
参数:offset 是偏移量,正数表示从文件开头向文件末尾移动,负数相反。
? whence : 文件指针的位置,可选参数,值可以是
? SEEK_SET or 0 表示文件开头位置,是默认值
? SEEK_CUR or 1 表示当前位置
? SEEK_END or 2 文件末尾位置
返回值:新的位置
#1.txt内容:hello world
with open('1.txt','r',encoding='utf-8') as fp:
fp.seek(5) #移动到hello后的空格位置
print(fp.read(3)) #wo
fp.seek(0) #移动到开头
print(fp.read(5)) #hello
print(fp.tell()) #tell()显示当前指针位置
字符串类型和字节类型转换过程
? 字符串类型转换为字节类型:编码,encode
? 字节类型转换为字符串类型:解码,decode
str = "今天是个好日子 today is a good day"
path = "file22.txt"
with open(path,"wb") as f:
result = str.encode("utf-8")
print(result)
f.write(result)
with open(path,"rb") as f1:
data = f1.read()
print(data)
print(type(data))
newData = data.decode("utf-8")
print(newData)
print(type(newData))
需要引入os模块
函数名 | 函数值 |
---|---|
os.name | 获取当前的操作系统的类型nt->windows posix->unix 后者Linux |
os.environ[?n‘va??r?n] | 获取操作系统中的环境变量 |
os.environ.get("path")[?n‘va??r?n] | 获取path的环境变量 |
os.curdir | 获取当前的目录 |
os.getcwd() | 获取当前的工作目录 |
os.listdir() | 以列表的形式 返回当前目录的文件 |
os.mkdir() | 创建目录 |
os.rmdir() | 删除目录 |
os.rename(old,new) | 修改文件后者文件夹的名字 |
os.remove() | 删除文件 |
os.system(command) | 执行系统命令 |
os.path.join(path1,path2) | 将path1和path2拼接成一个正常的路径 |
os.path.splitext() | 获取文件扩展名 |
os.path.isdir() | 判断是否是目录 |
os.path.isfile() | 判断是否是文件 |
os.path.exists() | 判断文件或者目录是否存在 |
os.path.getsize() | 获取文件的大小(字节) |
os.path.dirname() | 获取路径的目录名 |
os.path.basename() | 获取路径的文件名 |
os.path.abspath() | 返回文件的绝对路径 |
os.path.split() | 拆分路径 |
原文:https://www.cnblogs.com/sunBinary/p/10940902.html