Python学习笔记【第七篇】:编码、文件、文件夹操作
介绍
我们用pytthon、C#、Java等这些编程语言,想要把文件(文字、视频....)永久保存下来就必须将文件写入到硬盘中,这就需要我们应用程序去操作硬件,我们这些编程语言是无法直接操作硬件的。就需要操作系统把复杂的硬件操作封装成接口给应用程序调用。这样用户\应用程序就能对文件进行操作了。
字符编码:
1:python读/写文本文件会涉及到编码 2:python关于识别到定义变量的时候
ASCII:只支持英文字符串 采用8位二进制对应一个英文字符粗
GBK: 支持英文、中文字符串 采用8位(8bit=1Bytes)二进制数对应一个英文字符串 采用16位(16bit=2Bytes)二进制对应一个中文字符串
unicode:兼容万国字符串 采用16位(16bit=2Bytes)二进制对应一个中文字符串,个别生僻字采用4Bytes、8Bytes
现代计算机统一使用Unicode编码。
utf-8 :unicode transform (精简)版
文本文件存取乱码问题:
存乱了:编码格式因该设置成支持的文件内字符串
取乱了:文本以什么编码存,就因该以什么编码取
文件路径说明:
1:windows路径 如:C:\a\b\c\d.txt
使用 open(r'C:\a\b\c\d.txt') 在路径字符串前面加一个r
使用 open('C:/a/b/c/d.txt')
使用 open('d.txt') 绝对路径
操作文件
在Python中内置一个open对象是操作文件的方法。
def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
文件操作流程
#1. 打开文件,得到文件句柄并赋值给一个变量 #2. 通过句柄对文件进行操作 #3. 关闭文件
#1. 打开文件,得到文件句柄并赋值给一个变量 f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r #2. 通过句柄对文件进行操作 data=f.read() #3. 关闭文件 f.close()
注意!!!
#第一点:
打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
1、f.close() #回收操作系统级打开的文件
2、del f #回收应用程序级的变量
推荐傻瓜式操作方式:使用with关键字来帮我们管理上下文
with open('a.txt','w') as f:
pass
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
data=read_f.read()
write_f.write(data)
#第二点:
f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。
文件以什么方式存的,就要以什么方式打开。
f=open('a.txt','r',encoding='utf-8')
打开文件的模式
访问模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
操作文件的方法
f.read() # 读取所有内容,光标移动到文件末尾
f.readline() # 读取一行的内容,光标移动到第二行首部
f.readlines() # 读取每一行内容,返回列表
data = '写入内容'
f.write(data) # 写入文件,需要自己添加换行
f.write(data,encoding='utf-8')# 写入文件并且指定写入文件的编码格式
f.writeline(['1','2','3']) # 文件以列表形式写入
f.readable() # 文件是否可读
f.writeable() # 文件是否可写
f.closed # 文件是否关闭
f.encoding # 如果文件打开模式为b ,则没有该属性
f.flush() # 立刻将文件内容从内存刷到硬盘上
f.name # 文件名称
文件内光标移动
一: read(3):
1. 文件打开方式为文本模式时,代表读取3个字符
2. 文件打开方式为b模式时,代表读取3个字节
二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate
注意:
1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
文件的修改
文件是存在硬盘上的,因而只存在覆盖,不存在修改如果想要修改文件就如下两种方式。
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘
方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件
# -*- coding: utf-8 -*- # 声明字符编码 # coding:utf-8 import os # with open('../files/a.txt', 'r', encoding='utf-8') as a_f, open('../files/b.txt', 'w', encoding='utf-8') as b_f: # a_data = a_f.read() # a_data = a_data + "方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件" # b_f.write(a_data) # os.remove('../files/a.txt') # os.rename('../files/b.txt', '../files/a.txt') with open('../files/a.txt', 'r', encoding='utf-8') as a_f, open('../files/b.txt', 'w', encoding='utf-8') as b_f: for line in a_f: b_f.write(line) b_f.write("方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件") os.remove('../files/a.txt') os.rename('../files/b.txt', '../files/a.txt')
文件操作练习
# -*- coding: utf-8 -*- # 声明字符编码 # coding:utf-8 # 文件全类容 file_list = [] # 定义文件生成器 def file_generator(): with open('../files/haproxy.conf', 'r', encoding='utf-8') as f: for row in f: yield row # 判断当前内容是否包含 def is_contain(str): str = "backend %s" % str flag = False # 获取读取文件生成器 generator = file_generator() for row in generator: r = row.strip() file_list.append(r) if r == str: flag = True print(file_list) return flag # 查询 def fetch(): # 是否查到标识 flag = False print('=========欢迎进入查询功能=========') content = input('请输入您要查询的内容:') # 获取读取文件生成器 generator = file_generator() backend_data = "backend %s" % content for row in generator: r = row.strip() # 查到了,如果开头为"backend"说明已经结束了。 if flag is True and r.startswith('backend'): break if r == backend_data or flag is True: flag = True # 打印查询到的信息 print(r) else: if flag is False: print('未查到当前节点下的内容。。。。') # 新增 def insert(): # 直接在文件中新加内容 print('=========欢迎进入新增功能=========') content = input('请输入您要新增的内容:') if content is None: print("新增内容不能为空") # 思路也是先查询出原内容,组成列表,通过索引添加内容,在重写到原来的文件中 pass # 修改 def update(): print('=========欢迎进入修改功能=========') # data = [{'backend': 'www.oldboy1.org', 'record': {'server': '2.2.2.4', 'weight': 20, 'maxconn': 3000}},{'backend': 'www.oldboy1.org', 'record': {'server': '3.3.3.3', 'weight': 30, 'maxconn': 1000}}] content = input('请输入您要查询的内容:').strip() # eval 转为列表结构 data = eval(content) if is_contain(data[0]['backend']) is True: # 获取要修改的源数据 old_server_record = '%sserver %s %s weight %s maxconn %s\n' % (' ' * 8, data[0]['record']['server'], data[0]['record']['server'], data[0]['record']['weight'], data[0]['record']['maxconn']) # 要修改的数据 new_server_record = '%sserver %s %s weight %s maxconn %s\n' % (' ' * 8, data[1]['record']['server'], data[1]['record']['server'], data[1]['record']['weight'], data[1]['record']['maxconn']) old_server_record = old_server_record.strip() new_server_record = new_server_record.strip() print(old_server_record) print(new_server_record) print('修改前列表:') print(file_list) if old_server_record not in file_list: print('你要修改的记录不存在') else: index = file_list.index(old_server_record) file_list[index] = new_server_record print('修改后列表:') print(file_list) # 重新覆盖文件 with open('../files/haproxy.conf', 'w+', encoding='utf-8') as f: # 写入后就变成一行了??? f.writelines(file_list) else: print('对不起你要修改的内容不存在。。。') # 删除 def delete(): # 思路也是先查询出原内容,组成列表,通过索引删除内容,在重写到原来的文件中 pass if __name__ == "__main__": msg = """ 1:查询 2:新增 3:修改 4:删除 5:退出 """ msg_dic = { '1': fetch, '2': insert, '3': update, '4': delete } while True: print(msg) # 接收用户输入并且去除空格 choice = input("请输入功能选择:").strip() if choice == '5': break operation = msg_dic.get(choice) # print(operation) # 打印的是函数地址 if operation is not None: # 调用函数 operation() else: print("系统暂无此功能。。。")
文件夹及路径操作方法
对于文件夹的操作,首先我们要导入os模块
import os =====OS模块==== os.getcwd():获取当前路径 os.listdir():展示当前目录内容 返回一个列表 os.chdir():改变当前路径 os.mkdir():创建目录 os.rmdir():删除目录 os.remove():删除文件 os.rename():重命名 os.path.isdir():判断是否是一个目录 os.path.isfile():判断是否是一个文件 os.path.join():路径拼接 os.path.dirname():所在目录/父及目录 os.path.abspath():绝对路径 os.path.relpath():相对路径 os.path.normpath():规范化路径 os.path.getsize():资源大小 os.path.getctime/getatime/getmtime:资源时间 os.path.exists():路径是否存在 os.path.isabs():是否是绝对路径 '''