数据管理
- 数据处理概述
数据处理的基本目的是从大量的、可能是杂乱无章的、难以理解的数据中抽取并推导出对于某些特定的人们来说是有价值、有意义的数据。当下数据处理贯穿于社会生产和社会生活的各个领域。数据处理技术的发展及其应用的广度和深度,极大地影响了人类社会发展的进程。数据处理也是大数据,数据分析等后续学科的基本环节。 - 基本概念
- 数据 : 能够输入到计算机中并被识别处理的信息集合。
- 数据存储阶段
- 人工管理阶段:人为管理,没有固定的格式和存储方法,容易混乱。
- 文件管理阶段 :数据可以长期保存,存储数据量大,使用简单。
- 数据库管理阶段:高效,可以存储更大量数据,便于管理,更加专业。
1. 文件处理
1.1 引入
- 什么是文件
文件是保存在持久化存储设备(硬盘、U盘、光盘..)上的一段数据,一个文本,一个py文件,一张图片,视频音频等这些都是文件。 - 文件分类
- 文本文件:打开后会自动解码为字符,如txt文件,word文件,py程序文件。
- 二进制文件:内部编码为二进制码,无法通过文字编码解析,如压缩包,音频,视频,图片等。必须通过专门的解码软件进行打开。
- 字节串类型
- 概念 : 在python3中引入了字节串的概念,与str不同,字节串以字节序列值表达数据,更方便用来处理二进制数据。(就是数据以的二进制形式表现)
- 字符串与字节串相互转化方法 - 普通的英文字符字符串常量可以在前面加b转换为字节串,例如:b'hello' - 变量或者包含非英文字符的字符串转换为字节串方法 :str.encode() - 字节串转换为字符串方法 : bytes.decode() 注意:python字符串用来表达utf8字符,因为并不是所有二进制内容都可以转化为utf8字符,所以不是所有字节串都能转化为字符串,但是所有字符串都能转化成二进制,所以所有字符串都能转换为字节串。
"""
字节串类型:bytes
字符串 <--> 字节串 :decode,encode
"""
# ascii字符:英文下的全部符号
bytes1 = b"hello" # 英文:字符串-> 字节串
print(bytes1) # b'hello' 二进制打印
print(type(bytes1)) # <class 'bytes'>
# 非ascii字符
bytes2 = "你好".encode() # 非英文:字符串-> 字节串
print(bytes2) # b'\xe4\xbd\xa0\xe5\xa5\xbd' 二进制打印
print(bytes2.decode()) # 字节串-> 字符串
print(bytes1.decode()) # 字节串-> 字符串
1.2 文件读写操作
使用程序操作文件,无外乎对文件进行读或者写(大前提是ls查看文件有读写权限)
- 读 :即从文件中获取内容到程序
- 写 :即通过程序修改文件中的内容
对文件实现读写的基本操作步骤为:打开文件,读写文件,关闭文件。
1.2.1 打开文件
file_object = open(file_name, access_mode='r', buffering=-1,encoding=None) 函数:内置函数(无需导入模块) 要点:功能 参数 返回值 功能:打开一个文件,返回一个文件对象。 参数:file_name 文件名; access_mode 打开文件的方式,如果不写默认为‘r’ buffering 1表示有行缓冲,默认-1则表示使用系统默认提供的缓冲机制。 encoding='UTF-8' 设置打开文件的编码方式,一般Linux下不需要直接默认none,win需要 返回值:成功返回文件操作对象。
打开模式 | 效果 |
r | 以读方式打开,文件必须存在,否则报错 |
w | 以写方式打开,文件不存在则创建,存在清空原有内容 |
a | 以追加模式打开,文件不存在则创建,存在则继续进行写操作不清空原内容 |
r+ | 以读写模式打开 文件必须存在 |
w+ | 以读写模式打开文件,不存在则创建,存在清空原有内容 |
a+ | 追加并可读模式,文件不存在则创建,存在则继续进行写操作 |
rb | 以二进制读模式打开 同r(上面是文本字符串进行读写,这以下字节串形式读写) |
wb | 以二进制写模式打开 同w |
ab | 以二进制追加模式打开 同a |
rb+ | 以二进制读写模式打开 同r+ |
wb+ | 以二进制读写模式打开 同w+ |
ab+ | 以二进制读写模式打开 同a+ |
注意 :
- b以二进制方式打开文件,读取内容为字节串,写入也需要写入字节串
- 不加b以文本字符串打开文件,读取内容字符串,写入也需要字符串
- 无论什么文件都可以使用二进制方式打开,但是非文本的二进制文件则不能以文本方式打开,否则后续读写会报错。
"""
文件打开
"""
file = open("file1.txt", "w") # 文件不存在就创建,存在就清空文件内容
# file = open("file1.txt", "r")#文件必须存在
# file = open("file1.txt", "a")文件不存在就创建,存在不清空文件内容
file.close()
1.2.2 读取文件
- 方法1
read([size]) 功能: 来直接读取文件中字符。 参数: 如果没有给定size参数(默认值为-1)或者size值为负,文件将被读取直至末尾,给定size最多读取给定数目个字符(字节)。 返回值: 返回读取到的内容 说明:中括号表示可选参数,可不写,默认读取全部,写上表示一次读取size个字节(论单位)或者字符(论个数),看你打开方式
注意:1. 文件过大时候不建议直接读取到文件结尾,占用内存较多,效率较低,循环读取
2. 读到文件结尾如果继续进行读操作会返回空字符串。
3. 文件里的空格与回车等皆是字符
- 方法2
readline([size]) 功能: 用来读取文件中一行 参数: 如果没有给定size参数(默认值为-1)或者size值为负,表示读取一行,给定size表示在一行里面最多读取制定的字符(或字节),通常如果按照行读取一般参数不写。 返回值: 返回读取到的内容
- 方法3
readlines([sizeint]) 功能: 读取文件中的每一行作为列表中的一项 参数: 如果没有给定size参数(默认值为-1)或者size值为负,文件将被读取直至末尾,给定size表示读取到size字符(字节)所在行为止。 返回值: 返回读取到的内容列表
- 方法4
# 文件对象本身也是一个可迭代对象,在for循环中可以迭代文件的每一行。 for line in f: print(line,end = "")
"""
文件读取 read readline readlines
1.一个有英文一字节,一个汉字3字节
2.通常不会一次将文件内容全部读取到内存,
而是采取循环读取,一次读一点,速度更快
大文件通常不会一次性读取出来
"""
# read
# 字符串格式读取与字节串格式读取
file = open("file2.txt", "r")
data = file.read(4) # 空格回车也算字符
print(data)
file.close()
file = open("file2.txt", "rb")
data = file.read(4) # +b 读取4个字节
print(data) # b'\xe7\xa9\xba\xe6'
file.close()
print("1-----------")
# 循环每次读取一点
file = open("file2.txt", "r")
while True:
data = file.read(1)
if not data: # 文件最后字符是空判断
break
print(data, end="")
file.close()
print()
print("2-----------")
# readline
file = open("file2.txt", "r")
data = file.readline()
print(data)
data = file.readline()
print(data)
file.close()
print("3-----------")
# readlines
file = open("file2.txt", "r")
data = file.readlines()
print(data)
file.close()
print("4-----------")
# 迭代按行取值
file = open("file2.txt", "r")
for data in file:
print(data, end="")
file.close()
"""
练习 01 : 使用dict.txt文件完成
编写一个函数,参数传入一个单词,返回值是
这个单词对应的解释,如果这个单词不存在则
返回 Not Found 即可
"""
def find_word(word):
file = open("dict.txt", "r")
while True:
str_data = file.readline()
list_data = str_data.split(" ", 1)
if word < list_data[0]: # 增加查询效率,减少无效查询
return "no this world"
if word == list_data[0]:
file.close()
return list_data[1].lstrip()
if not str_data:
file.close()
return "no this world"
print(find_word("word"))
# 方法二
"""
练习 01 : 使用dict.txt文件完成
编写一个函数,参数传入一个单词,返回值是
这个单词对应的解释,如果这个单词不存在则
返回 Not Found 即可
"""
# str01 = "hello world"
# str02 = str01.split(" ", 1) # 只切割一次
# print(str02)
#
#
# def find_word(word):
# file = open("dict.txt", "r", encoding="UTF-8")
# for line in file:
# temp = line.split(" ", 1) # 切割第一个字符串成两块
# if word < temp[0]: # 增加效率,后面不可能就不用遍历到尾了
# break
# elif temp[0] == word:
# return temp[1].strip() # 去除两边空格
# file.close()
# return "not find your word"
# print(find_word("world"))
1.2.3 写入文件
- 方法1
write(data) 功能: 把文本数据或二进制数据块的字符(字节)串写入到文件中去(看你打开方式) 参数:要写入的内容 返回值:写入的字符(字节)个数
注意: 如果需要换行要自己在写入内容中添加\n
- 方法2
writelines(str_list) 功能:接受一个字符串列表作为参数,将它们写入文件。 参数: 要写入的内容列表
"""
文件写操作
write
writelines
"""
# write
# 字符写入
file = open("file3.txt", "w")
file.write("你好 world\n")
file.write("hello 世界\n")
file.close()
# 二进制写入,但呈现方式还是utf-8字符格式
file = open("file3.txt", "ab")
file.write("你好 world\n".encode())
file.write("hello 世界\n".encode())
file.close()
# writelines
file = open("file3.txt", "a")
list01 = ["hello\n", "world\n"]
file.writelines(list01)
file.close()
1.2.4 关闭文件
打开一个文件后我们就可以通过文件对象对文件进行操作了,当操作结束后可以关闭文件操作
- 方法
file_object.close()
- 好处
- 可以销毁对象节省资源,(当然如果不关闭程序结束后对象也会被销毁)。
- 防止后面对这个对象的误操作。
1.2.5 with操作
python中的with语句也可以用于访问文件,在语句块结束后会自动释放资源。
- with语句格式
with context_expression [as obj]: with-body
- with访问文件
with open('file','r+') as f: #等价于f = open() 然后只能在with语句块里面编写代码,并且最后不用关闭文件 f.read()
注意 : with语句块结束后会自动释放f所以不再需要close().甚至close关闭会报错
"""
with 语句块打开文件
作用是相当于lambda小型化简单快捷操作
"""
with open("file4.txt", "w") as f:
f.write("ni hao\n")
# with 语句块结束,f文件对象自动销毁
"""
练习 02 : 重点练习
编写一个函数 复制一个文件
参数是要复制的文件 ,没有返回值
具体功能就是将要file3.txt复制一份到当前目录下名称叫file_new.txt
增加功能 : 文件不能一次读取,需要循环读写操作
思路 : 从原文件读 --> 写入新文件
"""
def copy_file(filename_old):
file_new = open("file_new.txt", "w")
file_old = open(filename_old, "r")
while True:
data = file_old.read(1)
file_new.write(data)
if not data:
break
file_new.close()
file_old.close()
copy_file("file3.txt")
#二进制文件:图片拷贝
def copy_file(filename_old):
file_new = open("download1.jpg", "wb")
file_old = open(filename_old, "rb")
while True:
data = file_old.read(1024)
if not data:
break
file_new.write(data)
file_new.close()
file_old.close()
copy_file("download.jpg")
1.2.6 读写缓冲区
- 定义
系统自动的在内存中为每一个正在使用的文件开辟一个空间,在对文件读写时都是先将文件内容加载到缓冲区,再进行读写。 - 作用
- 减少和磁盘的交互次数,保护磁盘。
- 提高了对文件的读写效率。
- 缓冲区设置
类型 | 设置方法 | 注意事项 |
系统自定义缓冲区大小 | buffering=-1 | 一般不容易写满 |
行缓冲 | buffering=1 | 当遇到\n时会刷新缓冲 |
指定缓冲区大小(多少字节) | buffering>1 | 必须以二进制方式打开 |
- 刷新缓冲区条件
- 缓冲区被写满
- 程序执行结束或者文件对象被关闭
- 程序中调用flush()函数
file_obj.flush()
# file = open("file5.txt", "w",buffering=-1) # 系统默认缓冲值-1
# file = open("file5.txt", "w", buffering=1) # 行缓冲
file = open("file5.txt", "wb", buffering=5) # 制定缓冲区大小
while True:
message = input(">>")
if not message:
break
# file.write(message + "\n") # 换行缓冲
file.write(message.encode())
# file.flush() # 主动刷新缓冲区
1.2.7 文件偏移量(本质是整数)
- 定义
打开一个文件进行操作时系统会自动生成一个记录,记录每次读写操作时所处的文件位置,每次文件的读写操作都是从这个位置开始进行的。
注意:
- r或者w方式打开,文件偏移量在文件开始位置
- a方式打开,文件偏移量在文件结尾位置
- 文件偏移量控制 tell() 功能:获取文件偏移量大小(字节为单位) 返回值:文件偏移量 seek(offset,[whence]) 功能: 移动文件偏移量位置 参数:offset 代表相对于某个位置移动的字节数(因此要用二进制方式打开)。负数表示向前移动,正数表示向后移动。 whence是基准位置的默认值为 0,代表从文件开头算起,1代表从当前位置算起,2 代表从文件末尾算起。
注意:1.必须以二进制方式打开文件时,基准位置才能用上是1或者2,不然报错
seek(0,0)表示偏移位置移动到开头,可以不用以二进制方式打开
2.如果偏移位置在内容之中再写入内容就是覆盖方式写入
"""
文件偏移量演示
可以提前预占空间的作用
"""
# 读写方式打开 打开一个文件,共用一个偏移量,
# 因此你要保证读取东西的偏移位置,找错位置读就容易读错
file = open("file6.txt", "wb+")
file.write("今天天气好晴朗".encode())
file.flush()
print("偏移量:", file.tell()) # 21 记录偏移量位置(按照字节来表示的)
# 修改偏移量位置 必须以字节方式打开与读写
file.seek(-15, 2) # 从末尾算起,往前移动15个字节(5个汉字)
data = file.read()
print(data.decode()) # 天气好晴朗
print("偏移量:", file.tell())
file.seek(0, 0)
file.write("哈哈".encode())#是覆盖插入
file.close()
小应用:提前预占内存
"""
练习03 :
编写一个程序,向一个 文件中循环写入如下内容
每隔2秒写入一行 直到强行退出
1. Mon Mar 29 16:46:42 2021
2. Mon Mar 29 16:46:44 2021
3. Mon Mar 29 16:46:46 2021
4. Mon Mar 29 16:46:48 2021
5. Mon Mar 29 16:51:22 2021
6. Mon Mar 29 16:51:24 2021
要求: 每条占一行,并且每次写入实时可以看到
当程序退出后,如果重新启动,序号可以衔接
提示函数 : time.ctime() time.sleep(2)
"""
import time
file = open("file7.txt", "a+", buffering=1)
file.seek(0, 0)
line = len(file.readlines())
while True:
line = line + 1
file.write(str(line) + ". " + time.ctime() + "\n")
time.sleep(1)
1.3 os模块
os模块是Python标准库模块,包含了大量的文件处理函数。
- 获取文件大小
os.path.getsize(file) 功能: 获取文件大小 参数: 指定文件 返回值: 文件大小
- 查看文件列表
os.listdir(dir) 功能: 查看文件列表 参数: 指定目录 返回值:目录中的文件名列表
- 判断文件是否存在
os.path.exists(file) 功能: 判断文件是否存在 参数: 指定文件 返回值: 布尔值
- 删除文件
os.remove(file) 功能: 删除文件 参数: 指定文件
"""
os模块下的几个文件处理小函数
"""
import os
# 获取文件大小 字节数
print(os.path.getsize("file3.txt"))
# 获取文件夹中所有文件名称
print(os.listdir("."))
# 判断一个文件是否存在 返回值bool
print(os.path.exists("file3.txt"))
#删除文件
os.remove("file33.txt")
3.txt课堂随记
------------------------------------------------------------------------------------------------------------------
前情回顾
1. Linux命令
权限 : sudo chmod
其他 : shutdown ln
通配符 * 管道 | 输出重定向 > >>
2. 服务器环境
vi 编辑器
用户管理: useradd passwd
软件管理: apt install apt remove
远程登录: ssh 秘钥对
程序运行: #!/usr/bin/python3
-----------------------------------------------------------------------------
练习 01 : 使用dict.txt文件完成
编写一个函数,参数传入一个单词,返回值是
这个单词对应的解释,如果这个单词不存在则
返回 Not Found 即可
提示: split()
练习 02 :
编写一个函数 复制一个文件
参数是要复制的文件 ,没有返回值
具体功能就是将要复制的文件复制一份到主目录下
plus : 文件不能一次读取,需要循环读写操作
def copy(filename):
pass
copy("./3.txt")
练习03 :
编写一个程序,向一个 文件中循环写入如下内容
每隔2秒写入一行 直到强行退出
1. Mon Mar 29 16:46:42 2021
2. Mon Mar 29 16:46:44 2021
3. Mon Mar 29 16:46:46 2021
4. Mon Mar 29 16:46:48 2021
5. Mon Mar 29 16:51:22 2021
6. Mon Mar 29 16:51:24 2021
要求: 每条占一行,并且每次写入实时可以看到
当程序退出后,如果重新启动,序号可以衔接
提示函数 : time.ctime() time.sleep(2)
知识要点 : open() read() write() close()
文件拷贝练习
作业 : 1. 熟练使用文件读写操作函数
2. 编写一个函数,传入一个目录(假设该
目录中全是文本文件),函数的功能是将这些文本
文件合并为一个大文件
def union_files(dir):
pass
"""
编写一个函数,传入一个目录(假设该
目录中全是文本文件),函数的功能是将这些文本
文件合并为一个大文件
def union_files(dir):
pass
"""
import os
def copy_file(filename_old):
file_new = open("file_union.txt", "a")
file_old = open("./dir/" + filename_old, "r")
while True:
data = file_old.read(1024)
if not data:
break
file_new.write(data)
file_new.close()
file_old.close()
def union_files(dir):
list_dir = os.listdir(dir)
for item in list_dir:
copy_file(item)
union_files("./dir/")