python 基础 day9文件与文件系统

文件

关于文件,它有两个关键属性,分别是“文件名”和“路径”。其中,文件名指的是为每个文件设定的名称,而路径则用来指明文件在计算机上的位置。例如,我的 Windows 7 笔记本上有一个文件名为 projects.docx(句点之后的部分称为文件的“扩展名”,它指出了文件的类型),它的路径在D:\demo\exercise,也就是说,该文件位于 D 盘下 demo 文件夹中 exercise 子文件夹下。

绝对路径和相对路径

  • 当前工作目录
    每个运行在计算机上的程序,都有一个“当前工作目录”(或 cwd)。所有没有从根文件夹开始的文件名或路径,都假定在当前工作目录下。但是,虽然文件夹是目录的更新的名称,但当前工作目录(或当前目录)是标准术语,没有当前工作文件夹这种说法。

在 Python 中,利用 os.getcwd() 函数可以取得当前工作路径的字符串,还可以利用 os.chdir()
改变它。

  • 绝对路径与相对路径
  • 绝对路径:总是从根文件夹开始,Window 系统中以盘符(C:、D:)作为根文件夹,而 OS X 或者 Linux 系统中以 /
    作为根文件夹。
  • 相对路径:指的是文件相对于当前工作目录所在的位置。例如,当前工作目录为 “C:\Windows\System32”,若文件demo.txt 就位于这个 System32 文件夹下,则 demo.txt 的相对路径表示为 “.\demo.txt”(其中 .\就表示当前所在目录)。
  • python处理绝对路径与相对路径
    Python os.path 模块提供了一些函数,可以实现绝对路径和相对路径之间的转换,以及检查给定的路径是否为绝对路径
  • 调用 os.path.abspath(path) 将返回 path 参数的绝对路径的字符串,这是将相对路径转换为绝对路径的简便方法。
  • 调用 os.path.isabs(path),如果参数是一个绝对路径,就返回 True,如果参数是一个相对路径,就返回 False。
  • 调用 os.path.relpath(path, start) 将返回从 start 路径到 path 的相对路径的字符串。如果没有提供
    start,就使用当前工作目录作为开始路径。
  • 调用 os.path.dirname(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之前的所有内容;调用os.path.basename(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之后的所有内容。

打开文件

在python中使用open()打开文件并返回文件对象,基本语法:

file = open(file_name [, mode[, buffering]])

  • file_mode:要创建或打开文件的文件名称,该名称要用引号(单引号或双引号都可以)括起来。需要注意的是,如果要打开的文件和当前执行的代码文件位于同一目录,则直接写文件名即可;否则,此参数需要指定打开文件所在的完整路径。
  • mode:可选参数,用于指定文件的打开模式。可选的打开模式如表 1 所示。如果不写,则默认以只读(r)模式打开文件。
  • buffing:可选参数,用于指定对文件做读写操作时,是否使用缓冲区.

在这里插入图片描述
在这里插入图片描述

文件打开模式,直接决定了后续可以对文件做哪些操作

f=open('record.txt','w')

使用 open() 打开文件时,默认采用 GBK 编码。但当要打开的文件不是 GBK 编码格式时,可以在使用 open() 函数时,手动指定打开文件的编码格式

f=open('record.txt','w',encoding="utf-8")
print(f)#<_io.TextIOWrapper name='record.txt' mode='w' encoding='utf-8'>
  • open()是否使用缓冲区
  • 计算机外设(比如硬盘、网络)的 I/O 速度远远低于访问内存的速度,而程序执行 I/O
    时要么将内存中的数据写入外设,要么将外设中的数据读取到内存,如果不使用缓冲,就必须等外设输入或输出一个字节后,内存中的程序才能输出或输入一个字节,这意味着内存中的程序大部分时间都处于等待状态
  • 内存中程序的读写速度很快,如果不使用缓冲,则程序必须等待外设进行同步读写。打个形象的比喻,就像在一条堵车的马路上开着跑车,必须等前面的车开一点,跑车才能前进一点。
  • 在打开缓冲之后,当程序执行输出时,程序会先将数据输出到缓冲区中,而不用等待外设同步输出,当程序把所有数据都输出到缓冲区中之后,程序就可以去干其他事情了,留着缓冲区慢慢同步到外设即可;反过来,当程序执行输入时,程序会先等外设将数据读入缓冲区中,而不用等待外设同步输入。

open()文件对象常用的属性

成功打开文件之后,可以调用文件对象本身拥有的属性获取当前文件的部分信息

  • file.closed:判断文件是否己经关闭。
  • file.mode:返回被打开文件的访问模式。
  • file.name:返回文件的名称。
f=open('record.txt','w',encoding="utf-8")
print(f.encoding)#utf-8
print(f.mode)#w
print(f.closed)#False
print(f.name)#record.txt

文件对象的方法

文件的对象的方法执行操作
close()关闭文件
read(size=-1)从文件读取size个字符,当未给定size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回
readine()从文件中读取一整行字符串
write(str)将字符串str写入文件
writelines(seq)向文件写入字符串序列seq,seq应该是一个返回字符串的可迭代对象
seek(offsets,from)在文件中移动文件指针,从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)偏移offset个字节
tell()返回当前在文件中的位置

文件的关闭

close()用来关闭文件,python拥有垃圾收集机制,会在文件对象的引用计数降至零的时候自动关闭文件

文件的读取与定位

文件的读取方法有许多,可以使用文件对象的read()和readline()方法,也可以直接使用list(f),或者使用迭代来读取

read()是按字节为单位读取,如果不设置参数,那么会全部读取出来,文件指针指向文件末尾。tell()方法可以告诉你当前文件指针的位置:

  • read()函数抛出UnicodeDecodeError异常的解决方法
f=open('record.txt', 'r', True)
print(f.read())#UnicodeDecodeError: 'gbk' codec can't decode byte 0xa2 in position 8: illegal multibyte sequence
f.close()

当使用 open() 函数打开文本文件时,默认会使用当前操作系统的字符集,比如 Windows 平台,open() 函数默认使用 GBK 字符集。因此,上面程序读取的 a.txt 也必须使用 GBK 字符集保存;否则,程序就会出现UnicodeDecodeError错误。

如果要读取的文件所使用的字符集和当前操作系统的字符集不匹配,则有两种解决方式:

  • 使用二进制模式读取,然后用 bytes 的 decode() 方法恢复成字符串。
  • 利用 codecs 模块的 open() 函数来打开文件,该函数在打开文件时允许指定字符集。

下面程序使用二进制模式来读取文本文件

# 指定使用二进制方式读取文件内容,a.txt 以 utf-8 编码存储
f=open('record.txt', 'rb', True)
# 直接读取全部文件,并调用bytes的decode将字节内容恢复成字符串
print(f.read().decode('utf-8'))#我喜欢你就像你喜欢着我
f.close()

上面程序在调用 open() 函数时,传入了 rb 模式,这表明采用二进制模式读取文件,此时文件对象的 read() 方法返回的是 bytes 对象,程序可调用 bytes 对象的 decode() 方法将它恢复成字符串。由于此时读取的 a.txt 文件是以 UTF-8 的格式保存的,因此程序需要使用 decode() 方法恢复字符串时显式指定使用 UTF-8 字符集

下面程序使用 codes 模块的 open() 函数来打开文件,此时可以显式指定字符集

# 指定使用二进制方式读取文件内容,a.txt 以 utf-8 编码存储
import codecs
#指定使用utf-8 字符集读取文件内容
f = codecs.open("record.txt", 'r', 'utf-8', buffering=True)
while True:
    #每次读取一个字符
    ch = f.read(1)
    #如果没有读取到数据,则跳出循环
    if not ch : break
    #输出ch
    print (ch, end='')
f.close()
#我喜欢你就像你喜欢着我

上面程序在调用 open() 函数时显式指定使用 UTF-8 字符集,这样程序在读取文件内容时就完全没有问题了。

  • readline()和readlines()
    逐行读取只适应于以文本个是打开的文件,因为只有文本才有行的概念,但是二进制文件是没有的readline()用来读取一行的内容,readlines()读取所用行的内容

和 read() 函数一样,此函数成功读取文件数据的前提是,使用 open() 函数指定打开文件的模式必须为 r(只读模式)或r+(读写模式)。

readline()的基本格式:
file.readline([size]
size为可选参数,用于指定读取每一行时,一次最多读取的字符数。

readline() 函数在读取文件中一行的内容时,会读取最后的换行符“\n”,再加上 print() 函数输出内容时默认会换行,所以输出结果中会看到多出了一个空行。

readlines()的基本语法
file.readlines()
其中,file 为打开的文件对象。和 read()、readline() 函数一样,它要求打开文件的模式使用 r(只读)或者 r+(读写)

文件的写入

使用write() 函数,可以向文件中写入指定内容。

注意,在使用 write() 向文件中写入数据,需保证使用 open() 函数是以 r+、w、w+、a 或 a+ 的模式打开文件,否则执行 write() 函数会抛出 io.UnsupportedOperation 错误。

但是注意使用"w"时,此前文件的内容会被全部删除,如果是在原文件后添加内容,使用"a"
在这里插入图片描述
在这里插入图片描述

  • writelines()
    writelines() 函数,可以实现将字符串列表写入文件中。

注意,写入函数只有 write() 和 writelines() 函数,而没有名为 writeline 的函数。

以 a.txt 文件为例,通过使用 writelines() 函数,可以轻松实现将 a.txt 文件中的数据复制到其它文件中

f=open("record.txt","r",1)
n=open('b.txt','w')
n.writelines(f.readlines())
n.close()
f.close()

使用 writelines() 函数向文件中写入多行数据时,不会自动给各行添加换行符

seek()和tell()函数

  • 使用 open() 函数打开文件并读取文件中的内容时,总是会从文件的第一个字符(字节)开始读起。但是可以移动文件指针的位置,自定指定读取的起始位置。
  • 通过移动文件指针的位置,再借助 read() 和 write()函数,就可以轻松实现,读取文件中指定位置的数据(或者向文件中的指定位置写入数据)。

注意,当向文件中写入数据时,如果不是文件的尾部,写入位置的原有数据不会自行向后移动,新写入的数据会将文件中处于该位置的数据直接覆盖掉。

实现对文件指针的移动,文件对象提供了 tell() 函数和 seek() 函数。tell() 函数用于判断文件指针当前所处的位置,而 seek() 函数用于移动文件指针到文件的指定位置。

  • tell()
    用来读取指针当前的位置
f=open("record.txt","r")
print(f.tell())#0
print(f.read(4))#http
print(f.tell())#4

当程序使用文件对象读写数据时,文件指针会自动向后移动:读写了多少个数据,文件指针就自动向后移动多少个位置。

  • seek()
    seek() 函数用于将文件指针移动至指定位置,基本语法:

file.seek(offset[, whence])

  • file:表示文件对象;
  • whence:作为可选参数,用于指定文件指针要放置的位置,该参数的参数值有 3 个选择:0 代表文件头(默认值)、1 代表当前位置、2代表文件尾。
  • offset:表示相对于 whence 位置文件指针的偏移量,正数表示向后偏移,负数表示向前偏移。例如,当whence == 0&&offset == 3(即 seek(3,0) ),表示文件指针移动至距离文件开头处 3 个字符的位置;当whence == 1&&offset == 5(即 seek(5,1) ),表示文件指针向后移动,移动至距离当前位置 5 个字符处。

注意,当 offset 值非 0 时,Python 要求文件必须要以二进制格式打开,否则会抛出 io.UnsupportedOperation 错误

f=open("record.txt","r")
print(f.tell())#0
print(f.read(4))#http
print(f.tell())#4
f.seek(0)
print(f.read(2))#ht
print(f.tell())#2
f.close()

文件系统

OS模块

对于文件系统的访问时,python一般是通过OS模块来实现的,Python作为跨平台的语言,也就是同样的源代码在不同操作系统不需要修改就可以实现

函数名使用方法
os.chdir(path)改变当前工作目录
os.getcwd()返回当前工作目录
os.listdir(path=‘.’)列举指定文件的目录名(’.‘表示当前目录,’…'表示上一级目录)
os.mkdir(path)创建单层目录,如该目录已存在则抛出异常
os.makedirs(path)递归创建多层目录,如果该目录已经存在抛出异常
os.remove(path)删除文件
os.rename(src, dst)重命名文件或目录,从 src 到 dst
os.system(command)运行系统的shell命令
以下是支持路径操作中常用的一些定义,支持所有平台
os.curdir指代当前目录
os.pardir指代上一级目录
os.sep输出操作系统特定的路径分隔符
os.linesep当前平台使用的行终止符
os.name指代当前使用的操作系统

os.path模块

方法说明
os.path.abspath(path)返回绝对路径
os.path.basename(path)返回文件名
os.path.commonprefix(list)返回list(多个路径)中,所有path共有的最长的路径
os.path.dirname(path)返回文件路径
os.path.exists(path)如果路径 path 存在,返回 True;如果路径 path 不存在,返回 False。
os.path.lexists路径存在则返回True,路径损坏也返回True
os.path.expanduser(path)把path中包含的""和"user"转换成用户目录
os.path.expandvars(path)根据环境变量的值替换path中包含的" n a m e " 和 " name"和" name""{name}"
os.path.getatime(path)返回最近访问时间(浮点型秒数)
os.path.getmtime(path)返回最近文件修改时间
os.path.getctime(path)返回文件 path 创建时间
os.path.getsize(path)返回文件大小,如果文件不存在就返回错误
os.path.isabs(path)判断是否为绝对路径
os.path.isfile(path)判断路径是否为文件
os.path.isdir(path)判断路径是否为目录
os.path.islink(path)判断路径是否为链接
os.path.ismount(path)判断路径是否为挂载点
os.path.join(path1[, path2[, …]])把目录和文件名合成一个路径
os.path.normcase(path)转换path的大小写和斜杠
os.path.normpath(path)规范path字符串形式
os.path.realpath(path)返回path的真实路径
os.path.relpath(path[, start])从start开始计算相对路径
os.path.samefile(path1, path2)判断目录或文件是否相同
os.path.sameopenfile(fp1, fp2)判断fp1和fp2是否指向同一文件
os.path.samestat(stat1, stat2)判断stat tuple stat1和stat2是否指向同一个文件
os.path.split(path)把路径分割成 dirname 和 basename,返回一个元组
os.path.splitdrive(path)一般用在 windows 下,返回驱动器名和路径组成的元组
os.path.splitext(path)分割路径,返回路径名和文件扩展名的元组
os.path.splitunc(path)把路径分割为加载点与文件
os.path.walk(path, visit, arg)遍历path,进入每个目录都调用visit函数,visit函数必须有3个参数(arg, dirname, names),dirname表示当前目录的目录名,names代表当前目录下的所有文件名,args则为walk的第三个参数
os.path.supports_unicode_filenames设置是否支持unicode路径名

pickle模块

pickle模块能够实现任意对象与文本之间的相互转化,也可以实现任意对象与二进制之间的相互转化。也就是说,pickle 可以实现 Python 对象的存储及恢复。
pickle 模块提供了以下 4 个函数供我们使用:

  • dumps():将 Python 中的对象序列化成二进制对象,并返回;
  • loads():读取给定的二进制对象数据,并将其转换为 Python 对象;
  • dump():将 Python 中的对象序列化成二进制对象,并写入文件;
  • load():读取指定的序列化数据文件,并返回对象。
  • pickle.dump()函数
    用于将 Python 对象转换成二进制文件,其基本语法格式为:

dump (obj, file)
obj:要转换的 Python 对象
file:转换到指定的二进制文件中,要求该文件必须是以"wb"的打开方式进行操作。

import pickle
list=['a','kg','money']
pickle_file=open('E:\\list_pkl','wb')
#使用dump方法保存数据
pickle.dump(list,pickle_file)
pickle_file.close()
  • pickle.load()函数
    和 dump() 函数相对应,用于将二进制对象文件转换成 Python 对象。该函数的基本语法格式为:

load(file)
file 参数表示要转换的二进制对象文件(必须以 “rb” 的打开方式操作文件)

import pickle
pickle_file=open('E:\\list_pkl','rb')
#使用load方法加载数据
print(pickle.load(pickle_file))
pickle_file.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值