文章目录
前言
为了方便以后自己方固复习,想把以前的笔记整理出来也与大家分享以下,可能以代码为主,都是手敲的,希望与友友们一起进步~
以下是本篇文章正文内容
一、文件操作流程及文件的概念
1.2什么是文件:
文件是操作系统提供给用户/应用程序操作硬盘的一种虚拟的概念/接口。
1.2为何要用文件:
用户\应用程序可以通过文件将数据永久保存到硬盘中。
用户\应用程序直接操作的是文件,对文件进行的所有的操作,都是在向操作系统发送系统调用,然后再由操作系统将其转换成具体的硬盘操作
1.3文件操作流程:
1、打开文件
2、操作文件:读/写,应用程序对文件的读写请求都是在向操作系统发送系统调用,然后由操作系统控制硬盘把数据读入内存,或者写入硬盘
3、关闭文件
二、文件路径写法
代码如下(示例):
# Windows路径分隔问题
# open('C:\a\b\d.txt')#Windows是'\',但在python中'\'为转义符
# 正确写法:
# open(r'C:\a\b\d.txt') r为原生字符串(推荐)
# 或写成open('C/a/b/d.txt')
三、代码笔记
1、首先你要了解基本的东西如下代码
#Windows路径分隔问题
#open('C:\a\b\d.txt')#Windows是'\',但在python中'\'为转义符
# 正确写法:
# open(r'C:\a\b\d.txt') r为原生字符串(推荐)
# 或写成open('C/a/b/d.txt')
# 变量占用的都是应用程序的内存空间
# 默认的操作模式为r操作类型为t==>rt
# f = open(r'text.txt', mode='rt') # f的值是一种变量,占用的是应用程序的内存空间(和操作系统)
# x=int(10)#只占应用程序内存
# print(f)
# res = f.read()
# print(res)
# f.close() # 回收操作系统资源
# print(f)
# f.read()#(变量f任然存在,但是不能再读)
# del f # 回收应用程序资源(也可不写,当f指向其它内存地址时,python的引用计数机制可自动回收)
2、t模式操作:
# t文本 必须指定encoding=utf-8
# 没有指定encoding参数操作系统会使用自己默认的编码
# Linux系统默认 utf-8
# Windows系统默认 gbk
# 文件对象又叫文件句柄
# with open('text.txt', mode='rt',encoding='utf-8')as f, \
# open('text1.txt', mode='rt',encoding='utf-8')as f1:
# res1 = f.read()#t模式会将f.read()读出的结果解码成unicode
# res2 = f1.read()
# print(res1)
# print(res2)
# with 上下文管理 不用写f.close(),会自动调用
# 内存:utf-8格式的二进制-----解码----》unicode
# 硬盘(text.txt内容:utf-8格式的二进制)
3、t模式下的----r操作
# r(默认的操作):只读模式,当文件不存在时报错,当文件存在时指针跳到开始位置
# 缺点 把所有内容从硬盘读入内存(特别是内容比较大时)
# with open(r'text1.txt', mode='rt', encoding='utf-8')as f:
# print('第一次读'.center(50, '*'))
# res = f.read()
# print(res)
# # 因没有重新打开文件,读完第一次时,指针指向末尾,再读时没有内容
# print('第二次读'.center(50, '*'))
# res = f.read()
# print(res)
# inp_username = input('your name>>').strip()
# inp_password = input('your passwoed>>').strip()
# with open('user.txt', mode='rt', encoding='utf-8')as f:
# res = f.read()
# username, password = res.split(':')
# if inp_username == username and inp_password == password:
# print('login success')
# else:
# print('username or passwod error')
# 当user.txt存有多个账户信息时
# inp_username = input('your name>>').strip()
# inp_password = input('your passwoed>>').strip()
#
# with open('user.txt', mode='rt', encoding='utf') as f:
# for line in f: # 读取每一行信息
# # print(line, end='')
# username, password = line.strip().split(':')
# # print(username,password)
# if inp_username == username and inp_password == password:
# print('login success')
# break
# else:
# print('username or passwod error')
4、t模式下的----w操作
# w:只写模式,当文件不存在时会创建一个空文件,当文件存在时会清空文件,指针位于开始位置
# with open('text1.txt', mode='wt', encoding='utf-8')as f:
# f.write('哈哈哈哈哈哈哈1\n') # 每次运行时,会重新清空文件重新写值
# f.write('哈哈哈哈哈哈哈2\n')
# f.write('哈哈哈哈哈哈哈3\n')
# f.write('哈哈哈哈哈哈哈4\n')
# 当文件没关时,会顺着上一次指针停的位置接着写
# 在以w模式打开文件没有关闭的情况下,连续写入,新的内容总是跟着旧的内容之后
5、t模式下-----a操作
# a:只追加写,当文件不存在时会创建空文件,在文件存在时,文件指针会直接跳到末尾
# with open('text.txt', mode='at', encoding='utf-8') as f:
# f.write('hello\n')
# f.write('world\n')
6、总结(不同与相同):
# w与r 相同点:在文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
# 不同的:a模式重新打开文件不会清空文件,会将文件的指针移到到文件的最后一行
# w模式一般用来创建全新的文件
# a模式一般用来针对老文件 如日志文件
7、w模式案例案例与a模式案例
# w模式案例
# 拷贝文本文件
# src_file = input('源文件路径>>').strip()
# dst_file = input('源文件路径>>').strip()
# with open('r{}'.format(src_file), mode='rt', encoding='utf-8')as f1, \
# open('r{}'.format(dst_file), mode='wt', encoding='utf-8')as f2:
# res = f1.read()
# f2.write(res)
# + 不能单独使用,必须配合r,w,a 可读可写
# with open('text1.txt', mode='rt+', encoding='utf-8') as f:
# # print(f.read())
# f.write('hahahhahaha') # 在文件开头写,会覆盖开头的内容
# with open('text1.txt', mode='wt+', encoding='utf-8') as f:
# f.write('11\n')
# f.write('22\n')
# f.write('33\n')
# f.write('44\n')
# print('=============', f.read()) # 此时的读会从写完后的位置开始读(因为此时的指针指在末尾)
# with open('text1.txt', mode='at+', encoding='utf-8') as f:
# print('=============', f.read()) # 此时也不能读,因为a模式指针一直指向文件末尾
# f.write('11\n')
# f.write('22\n')
# f.write('33\n')
# f.write('44\n')
# print('=============', f.read()) # 此时的读会从写完后的位置开始读(因为此时的指针指在末尾)
# a模式案例
# 注册功能
# username = input('your name>>').strip()
# password = input('your passwoed>>').strip()
# with open('user.txt', mode='at', encoding='utf-8') as f:
# f.write('{}:{}\n'.format(username, password))
8、x模式(了解)
# x模式(控制文件操作的模式),只写模式,不可读,不存在则创建,存在则报错
# python中的\n==>在windows平台中为\r\n(\r为文件指针到首行,\n为换行)
提示:
# 错误演示:t模式只能读文本文件
# with open.(r'movie.mp4',mode='rt')as f:
# f.read()# 硬盘的二进制读入内存-》t模式会将读入内存的内容进行decode解码操作
# with open.(r'movie.mp4',mode='rb')as f:
# f.read()# 硬盘的二进制读入内存-》b模式下,不做任何转换,直接读入内存
9、结论:
# b;binary模式
# 1、读写都是以bytes为单位
# 2、可以针对所有文件
# 3、一定不能指定字符编码
# t模式:
# 1、读写的都是以字符串(unicode)为单位
# 2、只能针对文本文件
# 3、必须指定字符编码,即必须指定encoding参数
# 总结
# 1、在操作纯文本文件方面,t模式帮助我们省去了编码与解码的环节,b模式则需要解码
# 2、针对非文本文件(如图片、视频、音频等)只能用b模式
10、b模式小案例
# with open(r'text1.txt',mode='rb')as f:
# res=f.read()#utf-8的二进制
# print(res,type(res))
# print(res.decode('utf-8'))#解码成字符
# with open(r'text1.txt',mode='wb')as f:
# f.write('hello 你好'.encode('utf-8'))
11、t与b模式小案例及补充
# 文件拷贝工具
# src_file = input('源文件路径>>').strip()
# dst_file = input('源文件路径>>').strip()
# with open('r{}'.format(src_file), mode='rb')as f1, \
# open('r{}'.format(dst_file), mode='wb')as f2:
# # res = f1.read()#内存占用过大
# # f2.write(res)
# for line in f1:
# f2.write(f1)
# 循环读取文件
# 方式一 自己控制每次读取数据量
# with open(r'text1.txt',mode='rb')as f:
# while True:
# res=f.read(4)#每次读四个字节
# if len(res)==0:
# break
# print(len(res))
# 方式二 以行为单位读,当以行内容过长时会导致一次性读入内容的数据量过大
# with open(r'text1.txt',mode='rb')as f:
# for line in f:
# print(line)
# readline(): 一次读取一行内容文件指针移动到下一行的首行位置
# with open(r'text1.txt', mode='rt', encoding='utf-8')as f:
# # res = f.readline() # 一次读取一行内容文件指针移动到下一行的首行位置
# # print(res)
# # res2=f.readline()
# # print(res2)
# while True:
# line=f.readline()
# if len(line)==0:
# break
# print(line)
# readlines:将每一行内容读取出来放进列表
# with open(r'text1.txt', mode='rt', encoding='utf-8')as f:
# res = f.readlines() # 一次读取一行内容文件指针移动到下一行的首行位置
# print(res)
# f.read()与f.readlines()都是将内容一次性的读入内存,如果内容过大会导致内存溢出,若还想将内容全读入内存,则必须分多次读
# f.writelines()
# with open(r'text1.txt', mode='wt', encoding='utf-8')as f:
# l=['aaaa\n','bbbbb\n','ccccc\n','ddddd\n']
# f.writelines(l)
# #writelines()相当于下面的功能
# # for line in l:
# # f.write(line)
# with open(r'text1.txt', mode='wb')as f:
# b模式下,方式一:
# l=[
# 'aaaa\n'.encode('utf-8'),
# 'bbbbb\n'.encode('utf-8'),
# 'ccccc\n'.encode('utf-8'),
# 'ddddd\n'.encode('utf-8')
# ]
# f.writelines(l)
# 方式二:(前提是纯英文字符),可以直接加前缀b得到bytes
# l = [
# b'aaaa\n',
# b'bbbbb\n',
# b'ccccc\n',
# b'ddddd\n'
# ]
# f.writelines(l)
# 补充:'上'.encode('utf-8')等同于bytes('上',encoding='utf-8')
# l=[
# bytes('上啊\n',encoding='utf-8'),
# bytes('冲啊\n',encoding='utf-8'),
# bytes('萨哈\n',encoding='utf-8'),
# bytes('妈耶\n',encoding='utf-8')
# ]
# f.writelines(l)
# with open(r'text1.txt', mode='wt', encoding='utf-8')as f:
# f.write('哈哈哈哈')#直接写入硬盘
#
# # f.flush()#立刻将文件内容从内存刷到硬盘,一般情况下不用
# print(f.readable())#判断是否可读
# print(f.writable())#判断是否可写
# print(f.closed)#判断是否关闭(此时为False)
# print(f.encoding)#查看文件的编码
# print(f.name)#查看文件名
# print(f.closed)#判断是否关闭(此时为True)
12、文件指针
# 指针移动的单位都是以bytes/字节为单位
# 只有一种特殊情况:t模式下的read(n),n代表的是字符个数
# utf-8中一个中文字体是3个字节,一个数字和英文字符是1个字节
# f.seek(n,模式):n指的是移动的字节个数
# 模式:0:参照物是文件开头位置 1:参照物是当前指针所在位置 2:参照物是文件末尾位置,应该倒着移动
# f.tell();获取文件指针当前位置
# 强调:只有0模式可以在t模式下用,1、2模式只能在b模式下用
13、文件指针操作了解操作
# with open(r'text1.txt', mode='rb')as f:
# f.seek(3, 0)
# print(f.tell()) # 3
# f.seek(9, 0)
# print(f.tell()) # 9
# res = f.read() # 当指针指在1个字节的中文字符时(一个中文字符有3个字节),会报错
# print(res.decode('utf-8'))
# f.seek(3, 1)
# print(f.tell()) # 3
# f.seek(9, 1)
# print(f.tell()) # 12
# res = f.read() # 当指针指在1个字节的中文字符时(一个中文字符有3个字节),会报错
# print(res.decode('utf-8'))
# f.seek(-3, 2)
# print(f.tell()) # 倒数第3个字节
# f.seek(-4, 2)
# print(f.tell()) # 倒数第4个字节
# res = f.read() # 当指针指在1个字节的中文字符时(一个中文字符有3个字节),会报错
# print(res.decode('utf-8'))
14、文件指针操作案例
# f.seek()案例
# with open('access.log', mode='at', encoding='utf-8') as f:
# for i in range(3):
# f.write('20211022 dad赚了200w\n')
# import time
# 一般调用f.seek()时用b模式,因为f.seek()指针移动以字节为单位,而b模式也是以字节来读取内容
# with open('access.log', mode='rb') as f:
# # 1、将指针跳到文件末尾,读日志文件末尾每次新加的内容
# f.seek(0, 2)
# while True:
# line = f.readline()
# if len(line) == 0:
# time.sleep(0.4)
# else:
# print(line.decode('utf-8'))
# 文件修改操作
# with open('user.txt', mode='r+t', encoding='utf-8')as f:
# # 一个中文字符占3个字节
# f.seek(9, 0)
# f.write('高级程序员') # 会覆盖后面的内容
# # 文件的修改不能修改硬盘的内容只能该内存的内容
# # 因此这种方式不行
# 方式一:文本编辑器采用的就是这种方式(若文件过大,会占资源)
# with open('user.txt', mode='rt', encoding='utf-8') as f:
# res = f.read()
# data = res.replace('夹克', '哈哈') # 将文件读入内存修改
# print(data)
#
# with open('user.txt', mode='wt', encoding='utf-8') as f:
# f.write(data) # 将文件写入硬盘保存
# 方法二
# .user.txt.swap Linux下 '.'代表隐式文件,swap:交换的意思
# import os
#
# with open('user.txt', mode='rt', encoding='utf-8') as f, \
# open('.user.txt.swap', mode='wt', encoding='utf-8')as f2:
# for line in f:
# f2.write(line.replace('檀木', '小明'))
# os.remove('user.txt') # 移除原文件
# os.rename('.user.txt.swap', 'user.txt') # 将新文件名字改为原文件
# 方式一没有浪费硬盘空间但浪费内存空间
# 方式二没有浪费内存空间但浪费硬盘空间