文件(File)
- r 表示只读
- w 表示可以写 所以我们可以使用w来写入文件,如果文件不存在会创建文件,如果文件存在则会覆3. 盖原文件的内容
- a 表示追加内容 如果文件不存在会创建文件,如果文件存在则会像文件中追加内容
-
- 为操作符增加功能
- r+ 既可读又可写,文件不会报错
- x 用来创建文件,如果文件不存在就创建,如果存在就报错
打开文件
- 通过python对计算机中的各种文件进行增删改查的操作
- I/O(Input/Output)
操作步骤
- 打开文件
- 对文件进行操作(读、写)
- 关闭
open()方法
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- 调用open()来打开一个文件,可以分为两种类型
- 一种是纯文本文件(使用utf-8、gkb等编写的文本文件)
- 一种是用二进制编写的文件(图片、音频、ppt等)
- open()这个函数默认使用文本文件的方式打开,如果定义encoding打开中文文档会报错
- 处理文件时,需要制定文件的编码
参数:
- file 要打开文件的名字(路径)
- open有一个返回值,返回的是一个对象,这个对象就代表了当前打开的文件
- 如果目标文件和当前文件在同一级目录下,则直接使用文件名即可打开
读取文件
如果目标文件和当前文件在同一级目录下,则直接使用文件名即可打开
read()
- read 方法用来读取文件的内容,它会将内容全部保存到一个字符串中返回
file_op = open(r'F:\my_dream\documentation.txt')
content = file_op.read() # read方法读取,并将内容全部保存
print(content)
我新创建了一个text文件,里面的内容是python官方文档的内容,我没有放到同级目录下,所以用的是绝对路径
关闭文件
close()
- close方法用来关闭文件
记得要关闭文件,否则会一直占用内存
file_op = open(r'F:\my_dream\documentation.txt')
content = file_op.read()
print(content)
file_op.close()
你有可能忘记关闭文件
推荐你使用 with…as 语句
with open(file_name) as file_bgj:
print(file_obj.read())
# Open file and return a corresponding file object. If the file cannot be opened, an OSError is raised.
# file is a path-like object giving the pathname (absolute or relative to the current working directory)
#
# of the file to be opened or an integer file descriptor of the file to be wrapped.
# (If a file descriptor is given, it is closed when the returned I/O object is closed, unless closefd is
# set to False.)
此时这个文件只能在with中使用,一旦with结束文件,文件则会自动关闭close()
如果用上面的代码我打开一个存储中文的文件
file_name = '中文.txt'
with open(file_name) as file_obj:
print(file_obj.read())
# Traceback (most recent call last):
# File "f:/my_dream/text.py", line 3, in <module>
# print(file_obj.read())
# UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 8: illegal multibyte sequence
修改一下,定义编码形式
file_name = '中文.txt'
with open(file_name, encoding='utf-8') as file_obj:
print(file_obj.read())
# “我是小妖怪,逍遥又自在,杀人不眨眼,吃人不放盐,一口七八个,肚皮要撑破,茅房去拉屎,想起忘带纸。
# 生活你全是泪,没死就得活受罪,越是折腾越倒霉,越有追求越悲催,垂死挣扎你累不累,不如瘫在床上睡。
# 来来回回千百遍,小爷也是很疲倦”
拓展:
cp936是GKB的一种
当我们读一个中文文档时
较大的文件
- 如果读取的文件比较大(按T算的),会一次将全部内容加载到内存中,容易导致内存泄漏
- read()函数可以接受一个size作为参数,该参数用来指定读取的字符的数量
- size默认值是-1,它会读取文件中所有的字符
先看看size参数
file_name = '中文.txt'
with open(file_name, encoding='utf-8') as file_obj:
help(file_obj.read)
# read(size=-1, /) method of _io.TextIOWrapper instance
# Read at most n characters from stream.
# Read from underlying buffer until we have n characters or we hit EOF.
# If n is negative or omitted, read until EOF.
翻译一下就是
- 从流中做多读取n个字符
- 从底层缓冲区读取,知道我们指定的n个字符或达到EOF(我猜是“最后”)
- 如果n为负或省略,一直读取到最后
file_name = '中文.txt'
with open(file_name, encoding='utf-8') as file_obj:
# help(file_obj.read)
c = file_obj.read
print(c(6))
print(c(12))
print(len(c()))
# “我是小妖怪
# ,逍遥又自在,杀人不眨眼
# 97
注意,”(符号)也是占1个字符的,如果反复调用,并不会重复读取,而是继续向下读取12个字符串(我设置的12)
当len放在read后面的时候,读取的是剩余字符穿的长度,原文长115,返回的是97,因为我已读18个字符
假设这个文件很大,我们想一次读完,直接使用read是不行的,但一部分一部分的读,就要一行一行的复制,很难受
不如写个循环
file_name = '中文.txt' # 对目标文件命名,同级目录下
with open(file_name, encoding='utf-8') as file_obj: # 用with...as...打开,命名为file_obj
c = file_obj.read # 讲读到的对象复制给c
while True: # while循环
a = c(12) # c是函数read对象,不是调用函数,所以这里要加括号,读到第12个字符,并赋值给a
if len(a) == 0: # 设置终止语句,因为读了12个,这12个字符就没有了,len检测的是剩下字符的长度
break # 满足条件即停止读取,否则成了死循环
print(a) # 打印读到的数据
# “我是小妖怪,逍遥又自在
# ,杀人不眨眼,吃人不放盐
# ,一口七八个,肚皮要撑破
# ,茅房去拉屎,想起忘带纸
# 。
# 生活你全是泪,没死就
# 得活受罪,越是折腾越倒霉
# ,越有追求越悲催,垂死挣
# 扎你累不累,不如瘫在床上
# 睡。
# 来来回回千百遍,小
# 爷也是很疲倦”
其他的读取方式
readline()
- 可以用来读取一行内容
file_name = '中文.txt'
with open(file_name, encoding='utf-8') as file_obj:
c = file_obj.readline()
print(c)
# “我是小妖怪,逍遥又自在,杀人不眨眼,吃人不放盐,一口七八个,肚皮要撑破,茅房去拉屎,想起忘带纸。
readlines()
- 一行一行的读取,知道读完,它会将读取的内容封装到列表中,并且每一行后会有一个\n
file_name = '中文.txt'
with open(file_name, encoding='utf-8') as file_obj:
c = file_obj.readlines()
print(c)
# ['“我是小妖怪,逍遥又自在,杀人不眨眼,吃人不放盐,一口七八个,肚皮要撑破,茅房去拉屎,想起忘带纸。\n', '生活你全是泪,没死就得活受罪,越是折腾越倒霉,越有追求越悲催,垂死挣扎你累不累,不如瘫在床上睡。\n',
# '来来回回千百遍,小爷也是很疲倦”']
文件的写入
write()
- 使用open()函数打开文件时,需要指定打开文件所要的操作,读、写、追加,读是默认的,但不能写入
- 要对文件进行写入的时候,write()函数需要我们传递一个字符串作为参数
- w 表示可以写,如果文件不存在则会创建文件,如果存在则会覆盖原文件
with open(r'C:\Users\vcc\Desktop\text.txt', 'w', encoding='utf-8') as file_write:
r = file_write.write('如果有来生要做一棵树')
print(r) # 返回的是字符串的长度
# 10
二进制文件
- b 读取二进制文件
- 读取二进制文件时,read()的size参数是以字节为单位
- 读取文本文件时,size以字符为单位(一个汉字=3个字符)
读取一个音乐文件
with open(r'C:\Users\vcc\Desktop\Kalimba.mp3', 'rb') as file_music:
r = file_music.read()
print(r) # 我只截取部分,比较多
#xa5\x1dlr1\xa64\xc9\x1d\r$X\'\x16\x12\x8a\x90B\xa2\
是以二进制形式读取,十六进制显示的
将读到的文件再写入新的文件
with open(r'C:\Users\vcc\Desktop\Kalimba.mp3', 'rb') as file_music:
r = file_music.read(100)
with open(r'C:\Users\vcc\Desktop\new_music.mp3','wb') as file_new:
c = 1024*10 # 1024是1KB,每次写入10KB
while True:
c = file_music.read()
# 设置终止条件当剩余内容长度为0时,终止循环
if len(c) == 0:
break
file_new.write(c)
读取文件的位置
tell()
- tell()方法用来检查当前读取的位置
with open(r'C:\Users\vcc\Desktop\nezha.txt', 'rb') as file_r:
file_r.seek(10)
file_r.read()
print(file_r.tell())
# 224
seek()
- 可以修改当前读取的位置
- 参数:0 从头开始(默认)
- 1 从当前位置开始
- 从最后位置计算
with open(r'C:\Users\vcc\Desktop\nezha.txt', 'rb') as file_r:
file_r.seek(0)
r = file_r.read(10)
print(r)
print(file_r.tell())
# b"I'm a litt"
# 10
文件的其他操作
import os
- os.listdir()获取当前目录的结构,listdir(’…’)获取上一级目录
- os.chdir(‘c:/’) 切换盘符
- os.getcwd()获取当前所在的目录
- os.mkdir(‘casul’)创建目录,在当前目录创建
- os.rmdir(‘casul’)删除目录
import os
r = os.getcwd()
print(r)
# E:\python\code\learn\python基础