【python学习笔记】task09 文件与文件系统
文件与文件系统
1.打开文件
基本语句
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
其中
file
: 必需,文件路径(相对或者绝对路径)。mode
: 可选,文件打开模式buffering
: 设置缓冲encoding
: 一般使用utf8errors
: 报错级别newline
: 区分换行符
常见的mode
如下表所示
打开模型 | 执行操作 |
---|---|
‘r’ | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
‘w’ | 打开一个文件只用于写入。 如果该文件已存在则打开文件,并从开头开始编辑。 即原有内容会被删除。 如果该文件不存在,创建新文件。 |
‘x’ | 写模式,新建一个文件,如果该文件已存在则会报错。 |
‘a’ | 追加模式,打开一个文件用于追加。 如果该文件已存在,文件指针将会放在文件的结尾。 也就是说,新的内容将会被写入到已有内容之后。 如果该文件不存在,创建新文件进行写入。 |
‘b’ | 以二进制模式打开文件。一般用于非文本文件,如:图片。 |
‘t’ | 以文本模式打开(默认)。一般用于文本文件,如:txt。 |
‘+’ | 可读写模式(可添加到其它模式中使用) |
【例子】打开一个文件,并返回文件对象,如果该文件无法被打开,会抛出OSError
f = open('将进酒.txt')
print(f)
# <_io.TextIOWrapper name='将进酒.txt' mode='r' encoding='cp936'>
for each in f:
print(each)
2.文件对象方法
方法 | 作用 |
---|---|
fileObject.close() | 用于关闭一个已打开的文件。关闭后的文件不能再进行读写操作, 否则会触发ValueError错误 |
fileObject.read([size]) | 用于从文件读取指定的字符数,如果未给定或为负则读取所有 |
fileObject.readline() | 读取整行,包括 “\n” 字符。 |
ileObject.readlines() | 用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。 |
fileObject.tell() | 返回文件的当前位置,即文件指针当前位置。 |
fileObject.seek(offset[, whence]) | 用于移动文件读取指针到指定位置。offset :开始的偏移量,也就是代表需要移动偏移的字节数,如果是负数表示从倒数第几位开始。whence :可选,默认值为 0。给 offset 定义一个参数,表示要从哪个位置开始偏移;0 代表从文件开头开始算起,1 代表从当前位置开始算起,2 代表从文件末尾算起。 |
fileObject.write(str) | 用于向文件中写入指定字符串,返回的是写入的字符长度。 如果文件打开模式带b,那写入文件内容时,str(参数)要用encode方法转为bytes形式,否则报错: TypeError: a bytes-like object is required, not 'str'。 |
fileObject.writelines(sequence) | 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符\n。 |
【例子】
#使用fileObject.close() 关闭文件
f=open('将进酒.txt')
print('Filename:',f.name) #Filename: 将进酒.txt
f.close()
#使用fileObject.read([size]) 从文件读取指定的字符数,如果未给定或为负则读取所有。
f=open('将进酒.txt')
line=f.read(20)
print('读取的字符串:%s'%line) #读取的字符串:君不见,黄河之水天上来,奔流到海不复回。
f.close()
#fileObject.readline()读取整行,包括 "\n" 字符。
f = open('将进酒.txt', 'r')
line = f.readline()
print("读取的字符串: %s" % line)
#fileObject.readlines()用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for... in ... 结构进行处理。
f = open('将进酒.txt', 'r')
lines = f.readlines()
print(lines)
for each in lines:
each.strip()
print(each)
f.close()
#fileObject.tell()返回文件的当前位置,即文件指针当前位置
f = open('将进酒.txt', 'r')
line = f.readline()
print(line)
# 君不见,黄河之水天上来,奔流到海不复回。
pos = f.tell()
print(pos) # 42
f.close()
#fileObject.seek(offset[, whence])用于移动文件读取指针到指定位置
f = open('将进酒.txt', 'r')
line = f.readline()
print(line)# 君不见,黄河之水天上来,奔流到海不复回。
line = f.readline()
print(line)# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
f.seek(0, 0)
line = f.readline()
print(line)# 君不见,黄河之水天上来,奔流到海不复回。
f.close()
#fileObject.write(str)用于向文件中写入指定字符串,返回的是写入的字符长度。
f = open('workfile.txt', 'wb+')
#b'前缀表示:后面字符串是bytes 类型。
print(f.write(b'0123456789abcdef')) # 16
print(f.seek(5)) # 5
print(f.read(1)) # b'5'
print(f.seek(-3, 2)) # 13
print(f.read(1)) # b'd'
#fileObject.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符\n
f = open('test.txt', 'w+')
seq = ['小马的程序人生\n', '老马的程序人生']
f.writelines(seq)
f.seek(0, 0)
for each in f:
print(each)
# 小马的程序人生
# 老马的程序人生
f.close()
3.简洁的with语句
关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行它的清理方法。
【例子】下面代码执行完后,就算处理过程中出问题了f也会关闭
try:
f = open('myfile.txt', 'w')
for line in f:
print(line)
except OSError as error:
print('出错啦!%s' % str(error))
finally:
f.close()
# 出错啦!not readable
可以使用with解决
try:
with open('myfile.txt', 'w') as f:
for line in f:
print(line)
except OSError as error:
print('出错啦!%s' % str(error))
# 出错啦!not readable
OS 模块中关于文件/目录常用的函数
有了OS(Operation System)
模块,我们不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。
方法 | 作用 |
---|---|
os.getcwd() | 用于返回当前工作目录。 |
os.chdir(path) | 用于改变当前工作目录到指定的路径。 |
listdir (path=’.’) | 返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
os.mkdir(path) | 创建单层目录,如果该目录已存在抛出异常。 |
os.makedirs(path) | 用于递归创建多层目录,如果该目录已存在抛出异常。 |
os.remove(path) | 用于删除指定路径的文件。如果指定的路径是一个目录,将抛出 OSError。 |
os.rmdir(path) | 用于删除单层目录。仅当这文件夹是空的才可以, 否则, 抛出 OSError。 |
os.removedirs(path) | 递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常。 |
os.rename(src, dst) | 方法用于命名文件或目录,从 src 到 dst,如果 dst 是一个存在的目录, 将抛出 OSError。 |
s.system(command) | 运行系统的shell命令(将字符串转化成命令) |
os.curdir | 指代当前目录(.) |
os.pardir | 指代上一级目录(…) |
os.sep | 输出操作系统特定的路径分隔符(win下为\,Linux下为/) |
os.linesep | 当前平台使用的行终止符(win下为\r\n,Linux下为\n) |
os.name | 指代当前使用的操作系统(包括:‘mac’,‘nt’) |
os.path.basename(path) | 去掉目录路径,单独返回文件名 |
os.path.dirname(path) | 去掉文件名,单独返回目录路径 |
os.path.join(path1[, path2[, …]])将 path1,path2 | 各部分组合成一个路径名 |
os.path.split(path) | 分割文件名与路径,返回(f_path,f_name)元组。如果完全使用目录,它会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在。 |
os.path.splitext(path) | 分离文件名与扩展名,返回(f_path,f_name)元组。 |
os.path.getsize(file) | 返回指定文件大小,单位是字节。 |
os.path.getatime(file) | 返回指定文件最近的访问时间 |
os.path.getctime(file) | 返回指定文件的创建时间 |
os.path.getmtime(file) | 返回指定文件的最新的修改时间浮点型秒数,可用time模块的gmtime()或localtime() |
os.path.exists(path) | 判断指定路径(目录或文件)是否存在 |
os.path.isabs(path) | 判断指定路径是否为绝对路径 |
os.path.isdir(path) | 判断指定路径是否存在且是一个目录 |
os.path.isfile(path) | 判断指定路径是否存在且是一个文件 |
os.path.islink(path) | 判断指定路径是否存在且是一个符号链接 |
os.path.ismount(path) | 判断指定路径是否存在且是一个悬挂点 |
os.path.samefile(path1,path2) | 判断path1和path2两个路径是否指向同一个文件 |
#使用os.getcwd() os.chdir(path)修改文件路径
import os
path = 'E:\python学习'
print("当前工作目录 : %s" % os.getcwd())
# 当前工作目录 : E:\python学习
os.chdir(path)
print("目录修改成功 : %s" % os.getcwd())
# 目录修改成功 : C:\
#listdir (path='.')返回path指定的文件夹包含的文件或文件夹的名字的列表。
import os
dirs = os.listdir()
for item in dirs:
print(item)
#os.rename(src, dst)方法用于命名文件或目录,从 src 到 dst,如果 dst 是一个存在的目录, 将抛出 OSError。
import os
print("目录为: %s" % os.listdir(os.getcwd()))
os.rename("test.txt", "test2.txt")
print("重命名成功。")
print("目录为: %s" % os.listdir(os.getcwd()))
#使用os.system(command)先自行创建一个a.py的文件,然后由shell命令打开。
import os
path = os.getcwd() + '\\a.py'
a = os.system(r'python %s' % path)
os.system('calc') # 打开计算器
序列化与反序列化
Python 的 pickle
模块实现了基本的数据序列和反序列化。
- 通过
pickle
模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。 - 通过
pickle
模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
pickle模块中最常用的函数为:
(1)pickle.dump(obj, file, [,protocol])
将obj对象序列化存入已经打开的file中。
obj
:想要序列化的obj对象。file
:文件名称。protocol
:序列化使用的协议。如果该项省略,则默认为0。如果为负值HIGHEST_PROTOCOL,则使用最高的协议版本。
(2)pickle.load(file)
将file中的对象序列化读出。
【例子】
import pickle
dataList=[[1,1,'yes'],
[1,1,'yes'],
[1,0,'no'],
[0,1,'no'],
[0,1,'no']]
dataDic={1:[1,2,3,4],
1:('a','b'),
2:{'c':'yes','d':'no'}}
#使用dump()将数据序列化到文件中
fw = open(r'.\dataFile.pkl', 'wb')
# Pickle the list using the highest protocol available.
pickle.dump(dataList, fw, -1)
# Pickle dictionary using protocol 0.
pickle.dump(dataDic, fw)
fw.close()
# 使用load()将数据从文件中序列化读出
fr = open('dataFile.pkl', 'rb')
data1 = pickle.load(fr)
print(data1)
data2 = pickle.load(fr)
print(data2)
fr.close()
# [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
# {0: [1, 2, 3, 4], 1: ('a', 'b'), 2: {'c': 'yes', 'd': 'no'}
练习题
1、打开中文字符的文档时,会出现乱码,Python自带的打开文件是否可以指定文字编码?还是只能用相关函数?
可以指定
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
其中encoding: 一般使用utf8
2、编写程序查找最长的单词
输入文档: res/test.txt
题目说明:
"""
Input file
test.txt
Output file
['general-purpose,', 'object-oriented,']
"""
def longest_word(filename):
# your code here
pass
?没有提供文件,不知道文件中字符串的格式,此处按照单词是用空格分开的来处理
def longest_word(filename):
f=open(filename)
a=f.read()
a=a.split()
print(a)
long=''
for line in a:
if len(line)>len(long):
long=line
for line in a:
if len(line)==len(long):
print(line)
pass