文件与文件系统
- 文件:由创建者定义的、具有文件名的一组相关元素的集合。
- 文件管理:把所管理的程序和数据组织成一系列的文件,并能进行合理的存储、使用等操作。
打开文件
- open(file, mode=‘r’, buffering=None, encoding=None, errors=None, newline=None, closefd=True)
Open file and return a stream. Raise OSError upon failure.- file: 必需,文件路径(相对或者绝对路径)。
- mode: 可选,文件打开模式
- buffering: 设置缓冲
- encoding: 一般使用utf8
- errors: 报错级别
- newline: 区分换行符
- 常见的mode如下表所示:
打开模式 | 执行操作 |
---|---|
‘r’ | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
‘w’ | 打开一个文件只用于写入。 如果该文件已存在则打开文件,并从开头开始编辑。 即原有内容会被删除。 如果该文件不存在,创建新文件。 |
‘x’ | 写模式,新建一个文件,如果该文件已存在则会报错。 |
‘a’ | 追加模式,打开一个文件用于追加。 如果该文件已存在,文件指针将会放在文件的结尾。 也就是说,新的内容将会被写入到已有内容之后。 如果该文件不存在,创建新文件进行写入。 |
‘b’ | 以二进制模式打开文件。一般用于非文本文件,如:图片。 |
‘t’ | 以文本模式打开(默认)。一般用于文本文件,如:txt。 |
‘+’ | 可读写模式(可添加到其它模式中使用) |
f = open('将进酒.txt', encoding='utf8')
print(f)
for each in f:
print(each)
<_io.TextIOWrapper name='将进酒.txt' mode='r' encoding='utf8'>
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
文件对象方法
- fileObject.close() 用于关闭一个已打开的文件。关闭后的文件不能再进行读写操作, 否则会触发ValueError错误。
f = open("将进酒.txt")
print('FileName:', f.name)
f.close()
FileName: 将进酒.txt
- fileObject.read([size]) 用于从文件读取指定的字符数,如果未给定或为负则读取所有。
f = open('将进酒.txt',encoding='utf8')
line = f.read(4)
print("读取的字符串: %s" % line)
f.close()
读取的字符串: # 君不
- fileObject.readline()读取整行,包括 “\n” 字符。
f = open('将进酒.txt',encoding='utf8' )
line = f.readline()
print("读取的字符串: %s" % line)
f.close()
读取的字符串: # 君不见,黄河之水天上来,奔流到海不复回。
- fileObject.readlines()用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。
f = open('将进酒.txt', encoding='utf8' )
lines = f.readlines()
print(lines)
for each in lines:
each.strip()
print(each)
['# 君不见,黄河之水天上来,奔流到海不复回。\n', '# 君不见,高堂明镜悲白发,朝如青丝暮成雪。\n', '# 人生得意须尽欢,莫使金樽空对月。\n', '# 天生我材必有用,千金散尽还复来。\n', '# 烹羊宰牛且为乐,会须一饮三百杯。\n', '# 岑夫子,丹丘生,将进酒,杯莫停。\n', '# 与君歌一曲,请君为我倾耳听。\n', '# 钟鼓馔玉不足贵,但愿长醉不复醒。\n', '# 古来圣贤皆寂寞,惟有饮者留其名。\n', '# 陈王昔时宴平乐,斗酒十千恣欢谑。\n', '# 主人何为言少钱,径须沽取对君酌。\n', '# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。']
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
- fileObject.tell()返回文件的当前位置,即文件指针当前位置。
f = open('将进酒.txt', encoding='utf8' )
lines = f.read(20)
print(lines)
pos = f.tell()
print(pos)
# 君不见,黄河之水天上来,奔流到海不复
56
- fileObject.seek(offset[, whence])用于移动文件读取指针到指定位置。
- offset:开始的偏移量,也就是代表需要移动偏移的字节数,如果是负数表示从倒数第几位开始。
- whence:可选,默认值为 0。给 offset 定义一个参数,表示要从哪个位置开始偏移;0 代表从文件开头开始算起,1 代表从当前位置开始算起,2 代表从文件末尾算起。
f = open('将进酒.txt',encoding='utf8')
line = f.readline()
print(line)
line = f.readline()
print(line)
f.seek(2,0)
line = f.readline()
print(line)
f.close()
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
君不见,黄河之水天上来,奔流到海不复回。
- fileObject.write(str)用于向文件中写入指定字符串,返回的是写入的字符长度。
f = open('workfile.txt', 'wb+')
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'
16
5
b'5'
13
b'd'
在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容的。
如果文件打开模式带b,那写入文件内容时,str(参数)要用encode方法转为bytes形式,否则报错:TypeError: a bytes-like object is required, not ‘str’。
str = '...'
# 文本 = Unicode字符序列
# 相当于 string 类型
str = b'...'
# 文本 = 八位序列(0到255之间的整数)
# 字节文字总是以‘b’或‘B’作为前缀;它们产生一个字节类型的实例,而不是str类型。
# 相当于 byte[]
f = open('将进酒.txt','r+', encoding='utf8')
str = '\n作者:李白'
f.seek(0, 2)
line = f.write(str)
f.seek(0, 0)
for each in f:
print(each)
f.close()
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
作者:李白
-
注意.txt的文件保存的编码方式为UTF-8
-
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()
小马的程序人生
老马的程序人生
简洁的 with 语句
一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。
关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行它的清理方法。
try:
f = open('myfile.txt', 'w+')
for line in f:
print(line)
except OSError as error:
print('出错啦!%s' % str(error))
finally:
f.close()
这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。
try:
with open('myfile.txt', 'w+') as f:
for line in f:
print(line)
except OSError as error:
print('出错啦!%s' % str(error))
OS 模块中关于文件/目录常用的函数
我们所知道常用的操作系统就有:Windows,Mac OS,Linu,Unix等,这些操作系统底层对于文件系统的访问工作原理是不一样的,因此你可能就要针对不同的系统来考虑使用哪些文件系统模块……,这样的做法是非常不友好且麻烦的,因为这样就意味着当你的程序运行环境一改变,你就要相应的去修改大量的代码来应对。
有了OS(Operation System)模块,我们不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。
- os.getcwd()用于返回当前工作目录。
- os.chdir(path)用于改变当前工作目录到指定的路径。
import os
path = 'C:\\'
print("当前工作目录 : %s" % os.getcwd())
# 当前工作目录 : D:\**\datawhale\python
os.chdir(path)
print("目录修改成功 : %s" % os.getcwd())
# 目录修改成功 : C:\
当前工作目录 : E:\PycharmProjects\Jupyter_PRJ\python_learn
目录修改成功 : C:\
- listdir (path=’.’)返回path指定的文件夹包含的文件或文件夹的名字的列表。
序列化与反序列化
-
Python 的 pickle 模块实现了基本的数据序列和反序列化。
- 通过 pickle 模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
- 通过 pickle 模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
-
pickle模块中最常用的函数为:
pickle.dump(obj, file, [,protocol]) 将obj对象序列化存入已经打开的file中。 -
obj:想要序列化的obj对象。
-
file:文件名称。
-
protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
-
pickle.load(file) 将file中的对象序列化读出。
-
file:文件名称。
import pickle
dataList = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
dataDic = {0: [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自带的打开文件是否可以指定文字编码?还是只能用相关函数?
可以指定,在指定之前需要通过平台修改文件的编码方式
2、编写程序查找最长的单词
输入文档: res/test.txt
题目说明:
"""
Input file
test.txt
Output file
['general-purpose,', 'object-oriented,']
"""
def longest_word(filename):
# your code here
pass
import os,collections
path = r'./test.txt'
def longest_word(filename):
# your code here
f = open(filename, mode='r')
wordlist = []
maxlength = 0
ret = []
lines = f.readlines()
# 对每行利用split空格分割单词,strip去除标点符号,获得一个wordlist
for each in lines:
line = each.strip().strip('\n')
line = line.split(' ')
for index, item in enumerate(line):
item = item.strip('.').strip('?').strip('\'').strip(',').strip('(').strip(')')
line[index] = item
# print(line)
wordlist.extend(line)
# 在wordlist中找最长的单词
for item in wordlist:
if len(item)< maxlength:
continue
elif len(item) == maxlength:
ret.append(item)
else:
maxlength = len(item)
ret = []
ret.append(item)
return ret
print(longest_word(path))