实验3 数据文件操作和异常处理
写在前面:这个任务是突然接到的,我很多知识都是现学的,写的有什么疏忽和遗漏请大家不要笑话并希望大家指出我的错误,学艺不精,继续努力。
- (1)在只打开给定的data.txt文件一次的情况下,实现对文件内容的两次读取:第一次连续读取全部奇数行的数据并输出;第二次连续读取全部偶数行的数据,对数据进行utf-8编码后输出。
- 前置知识(文件的读写)
- 1. 文件的打开
- 2,文件的读写
- 3,文件的光标移动
- 实现
- (2)读取并输出c:\windows路径下所有的文件列表;
- 前置知识 (os模块)
- 实现
- (3)计算实验数据目录中的sea.jpg图片文件的大小并输出;
- 前置知识(os.path模块)
- 实现
- (4) 对实验数据目录中的osData.txt文件进行操作:判断osData.txt文件是否存在,如果存在则在文件的末尾追加“I am ok.”字符串,如果文件不存在,则通过程序建立新文件并在文件中写入“My name is jack ”。
- 思路:
- 实现
- (5)编写程序接收用户输入的水果销售单价和数量,计算并输出水果的销售总额。要求程序能够捕获并处理当用户输入非数值类型的单价和数量时系统产生的异常,当捕获到异常时,使用单价和数量的默认值0进行总额的计算,并给用户输出相应的错误提示信息。
- 前置知识:(try except的使用)
- 思路:我们要处理的是非数值类型的数据 , 如何让非数值类型的数据报错呢 , 因为输入的时候肯定是str类型 , 我们做一下强制类型转换 , 转换成 float 类型 , 如果是数值类型就不会报错 , 反之会报错;
- 实现:
- (6) 读取给定的score.txt中保存的分数信息,按用户输入的学号或者姓名对学生的信息进行查询和输出(用户只输入一个查询数据),要求实现模糊条件查询,如姓胡的同学的成绩,学号中包括19字符的同学的成绩?
- 思路:
- 实现:
- (7) 编写程序实现:在实验数据目录中建立子目录copyImg;将实验数据目录中的sea.jpg图片文件拷贝10份到建立的copyImg目录中,文件名依次为seaCopy1.jpg , … , seaCopy10.jpg。
- 思路:
- 前置知识(os.makedir shutil.copy os.rename)
- 实现:
- 参考资料
(1)在只打开给定的data.txt文件一次的情况下,实现对文件内容的两次读取:第一次连续读取全部奇数行的数据并输出;第二次连续读取全部偶数行的数据,对数据进行utf-8编码后输出。
前置知识(文件的读写)
1. 文件的打开
open(path, mode, encoding)
path 文件路径
mode 打开模式
encoding 打开文件的编码
注意写编码方式的时候要加上 encoding 关键字
2,文件的读写
f.read(size)
读取 size 个字符
f.readline()
读取一行 , 返回一个字符串对象
f.readlines()
读取文件的所有行 , 返回一个自负床列表 , 可以进行遍历
每次读入一个字符串
f.write()
读入一个字符串列表
f.writelines()
关闭文件
f.close()
3,文件的光标移动
f,seek()
1. f.seek(p, 0) 或 f.seek(p)
将文件读取指针移动到文件的第p个字节处,表示绝对位置。
f.seek(0)移动到文件头位置。
2. f.seek(p, 1)
在当前位置的基础上,将文件读取指针移动p个字节,
表示相对位置。
3. f.seek(p, 2)
在文件尾的基础上,将文件读取指针移动p个字节,
表示相对位置。f.seek(0, 2)移动到文件尾位置。
实现
path = "C:/Users/联想/Desktop/data.txt"
my_file = open(path , 'r' , encoding = "utf-8")
cnt = 0
#先读取奇数行
for line in my_file.readlines():
cnt += 1
if(cnt % 2 == 1):
print(line , end = '')
cnt = 0
#光标移动到行首
my_file.seek(0)
print()
for line in my_file.readlines():
cnt += 1
if(cnt % 2 == 0):
print(line , end = '')
my_file.close()
(2)读取并输出c:\windows路径下所有的文件列表;
前置知识 (os模块)
1. os.sep
python是跨平台的。在Windows上,文件的路径分隔符是'\',在Linux上是'/'。
为了让代码在不同的平台上都能运行,那么路径应该写'\'还是'/'呢?
使用os.sep的话,就不用考虑这个了,os.sep根据你所处的平台,自动采用相应的分隔符号。
例如:
data_dir = os.sep.join(['hello', 'world'])
hello/world或者hello\world
2.os.listdir
传入路径 , 返回路径下所有文件名组成的列表
3.os.makedirs
传入path 建立新的文件夹
4.os.rename
os.rename(src, dst)
参数
src – 要修改的目录名
dst – 修改后的目录名
5.os.remove
os.remove(path)
path -- 要移除的文件路径
实现
知道了前置知识以后实现就很简单了 , 用一下 os 模块下的 listdir 函数 然后遍历一下就好了
import os
filelist = os.listdir("c:\windows")
for file in filelist:
print(file)
(3)计算实验数据目录中的sea.jpg图片文件的大小并输出;
前置知识(os.path模块)
os.path.exists 判断文件是否存在
os.path.join 连结文件路径
os.path.split 分割文件路径
os.path.getsize 得到文件大小
os.path.isfile 判断是否为文件
os.path.isdir 判断是否是文件夹
实现
filesize = os.path.getsize("C:/Users/联想/Desktop/sea.jpg")
print(filesize)
(4) 对实验数据目录中的osData.txt文件进行操作:判断osData.txt文件是否存在,如果存在则在文件的末尾追加“I am ok.”字符串,如果文件不存在,则通过程序建立新文件并在文件中写入“My name is jack ”。
思路:
我们已经知道 os.path 模块下有exists 这一个函数可以判断文件是否存在 , 根据其布尔类型的返回值我们可以进行下面的操作:
- 如果存在我们要追加 一个字符串这时候一定要注意打开方式 , 一定要是可追加的打开方式
- 如果文件不存在我们要选择可以创建文件的打开方式
- 最后可以查看文件内容进行验证
实现
import os
judge = os.path.exists("C:/Users/联想/Desktop/osDate.txt")
if(judge == True): #存在
t = open("C:/Users/联想/Desktop/osDate.txt" , 'a') #追加方式打开
t.write("I am ok") #写入字符串
t.close() #打开后记得关闭
else: #不存在字符串
t = open("C:/Users/联想/Desktop/osDate.txt" , 'w') # w 方式打开不存在自动创建
t.write("My name is jack")
t.close() #打开后记得关闭
# 检查一下是否操作成功
t = open("C:/Users/联想/Desktop/osDate.txt" , 'r') #以只读形式打开
print(t.readline())
t.close()
(5)编写程序接收用户输入的水果销售单价和数量,计算并输出水果的销售总额。要求程序能够捕获并处理当用户输入非数值类型的单价和数量时系统产生的异常,当捕获到异常时,使用单价和数量的默认值0进行总额的计算,并给用户输出相应的错误提示信息。
前置知识:(try except的使用)
有时候我们写程序的时候,会出现一些错误或异常,导致程序终止。使用try…except,这样程序就不会因为异常而中断。把可能发生错误的语句放在try模块里,用except来处理异常。
思路:我们要处理的是非数值类型的数据 , 如何让非数值类型的数据报错呢 , 因为输入的时候肯定是str类型 , 我们做一下强制类型转换 , 转换成 float 类型 , 如果是数值类型就不会报错 , 反之会报错;
实现:
#输入数据
n = eval(input("请输入要处理的信息数量:"))
ans = 0
for i in range(n):
price = input()
num = input()
try:
price = float(price)
num = float(num)
#如果不报错就计算贡献
ans += price * num
except:
#报错了显示 , 然后贡献 + 0
print("第{}组数据有误".format(i+1))
ans += 0
print(ans)
(6) 读取给定的score.txt中保存的分数信息,按用户输入的学号或者姓名对学生的信息进行查询和输出(用户只输入一个查询数据),要求实现模糊条件查询,如姓胡的同学的成绩,学号中包括19字符的同学的成绩?
思路:
先把数据存到列表里 , 进行遍历即可
实现:
path = "C:/Users/联想/Desktop/score.txt"
date = open(path , 'r')
date.readline()#不要第一行
#"学号 姓名 作业1 作业2 作业3 作业4 作业5" 第一行是目录信息
ls = []
for info in date.readlines():
infol = info.split()
ls.append(infol)
date.close()
#先把文件存在一个大列表里
#可以打开查看一下
# for i in ls:
# print(i)
# 按学号或者姓名进行查询
#查询姓胡同学的成绩
for i in ls:
if(i[1][0] == '胡'):
print(i)
#查询学号中包含 19 字符的同学的成绩
for i in ls:
if('19' in i[0]):
print(i)
(7) 编写程序实现:在实验数据目录中建立子目录copyImg;将实验数据目录中的sea.jpg图片文件拷贝10份到建立的copyImg目录中,文件名依次为seaCopy1.jpg , … , seaCopy10.jpg。
思路:
先建立子目录 , 然后进行拷贝
前置知识(os.makedir shutil.copy os.rename)
os.makedir(path , mode) 在某个路径下建立操作模式为 mode 的文件夹
shutil.copy(path1 , path2) 把一个文件复制到一个目录下
os.rename(name1 , name2) 把一个文件的路径名改掉
实现:
import shutil
import os
#0o777 模式是权限全开
os.mkdir("C:/Users/联想/Desktop/copyImg" , 0o777 )
for i in range(10):
shutil.copy("C:/Users/联想/Desktop/sea.jpg" , "C:/Users/联想/Desktop/copyImg")
os.rename("C:/Users/联想/Desktop/copyImg/sea.jpg", "C:/Users/联想/Desktop/copyImg/seaCopy{}.jpg".format(i+1))
参考资料
python 多空格字符串的分割
解决shutil.copyfile常见错误:PermissionError: [Errno 13] Permission denied
shutil 模块中 shutil.copy()、shutil.rmtree()、shutil.move()等基本函数用法介绍!