Python进阶(八)文件操作

读写文件是程序经常需要做的事情,Python内置函数提供了简单的读写文件方式,os模块、io模块提供了一些较复杂的对象。

本章重点学习一下内置函数操作文件,对其他内置模块的文件操作对象会简要的介绍,如果需要使用复杂的文件对象,可以查看相关的对象说明。

文件的相关概念

文件、目录和路径是计算机中非常重要的概念,我们这里只做简单的介绍,如果需要详细了解,可以查阅相关的文档。

文本文件和二进制文件

在计算机中,把存储数据的单元成为文件。文件中的数据可以是文本数据,例如源代码,没有任何格式的数据,有格式的xml数据等等;数据也可以是“二进制”数据,这种数据人很难识别,要靠编程后由计算机来读取(或写入),如视频数据、图片数据、数据流等等,这些数据人看到的只是一些0和1的二进制数据流,不借助于计算机,很难看出来这些数据是什么内容,因此被称呼为“二进制”数据。有些二进制数据是有结构的,也就是它的数据内容的位置是固定的,有一些数据是没有结构的,它完全是流式的,需要通过一些特殊的标记来识别当前数据流表示的含义。

目录和路径

计算机里有很多很多文件,比如你现在正在使用的计算机,一般为windows或者mac,上面有几十万,甚至几百万个文件。这么多文件需要有一套方法去管理,计算机一般采用树形结构进行管理。树形结构里每个树枝下面可以有多个文件和多个子树枝,树叶就是文件,树枝在计算机里被称为“目录”,树干在计算机里称呼为“根目录”。mac和linux等系统都只有一个根目录,windows系统没有根目录的概念,它有一个特殊的概念“盘符”,例如c:,d:,与根目录的概念接近。

文件的目录下面可以是子目录,文件的目录可以嵌套,多个嵌套的目录通过斜杠分割开来,可以写成如下的形式:

/User/my/PycharmProjects/pythonProject/main.py

前面的/User/my/PycharmProjects/pythonProject/都是目录,只有main.py是文件。

通常把/User/my/PycharmProjects/pythonProject/称呼为存放main.py的路径,只有通过“路径”我们才能找到这个文件。

上面的路径中,第一个斜杠就是根路径,这种带根路径的路径称呼为绝对路径

如果我们的工作路径是/User/my,那PycharmProjects/pythonProject/就是相对路径,相对路径是相对于某个路径(通常就是工作路径)而言的。

在计算机中,使用.表示当前的工作路径,所以上面的相对路径也可以写成./PycharmProjects/pythonProject/

当前路径的上一级目录,称呼为父目录,使用…来表示,…/my/PycharmProjects/pythonProject/与上面的路径是相同的。

在描述一个文件的时候,可以只给文件名,也可以文件名和路径名一起给出(称呼为带路径的文件),在编程时,通常都是要带上文件的路径,或绝对路径,或相对路径,因为编程的时候,我们是要程序去使用文件,只有带路径的文件,程序才能方便的去寻找它。

文件的主要操作

文件的主要操作分为创建、读、写和删除。

创建文件就是从无到有的新建一个文件,需要给予文件名字,以及写入一部分内容。

文件读是指从打开一个文件,从里面把内容读出来,一般是把文件里的数据读入到程序变量中。注意,文件中的数据是“静态的”,它自己是不能做出任何动作的,一个文件(如可执行文件)它能做出动作或者指令,是因为读取它的程序,按照文件里的数据进行了相对应的动作。

一般来说,文件都是“顺序”的,就跟我们的“读”文章一样,从开头到结尾,要一个个字的去读。

文件写分为两种情况,一种是覆盖写,一种是追加写。

所谓覆盖写就是只我不管文件里的内容是什么,我就从文件开头开始写,会把以前写的内容“覆盖”掉。你可以理解为纸上已经有一段文章了,我们再文章上面再写一篇文章,与在纸上书写不一样,覆盖写会把原来的内容“擦除”掉,写上新的内容,并不是原有数据和新数据的交叠。

追加写,就是我们直接跳过前面已经写过的内容,从原来内容的结尾处开始,写入新的内容。

删除文件,就是销毁文件,文件被删除后,其内容就被销毁了,需要谨慎进行删除操作。

那有没文件的修改呢?

有啊,就是前面的覆盖写,可以移动要覆盖写的起始位置,覆盖写入新的内容,就是修改了。但要注意,只能修改等量的数据,如果待修改的数据比新数据长,那就会留下一部分待修改数据,如果新数据比待修改数据长,那信数据就会写不全(或者把不需要覆盖写的数据给覆盖了)

另外,现代计算机系统将文件的访问、读、写设置了权限,如果你只有访问权限没有读写权限,只能对看到文件名,不能读写文件内容,如果有读文件权限,可以读出文件内容,但不能写入文件数据。

open()

无论是读或是写一个文件,都需要先打开一个文件,open()函数就是打开文件,并创建一个文件对象返回。

语法为:

open(
    file,
    mode='r',
    buffering=-1,
    encoding=None,
    errors=None,
    newline=None,
    closefd=True,
    opener=None,
)

参数说明:

  • file:file 是带路径的文件
  • mode:默认为 ‘r’,指定打开文件的模式,支持的模式见下表。
  • buffering:设置缓冲策略
  • encoding:是用于解码或编码文件的编码的名称,这只能在文本模式下使用,默认编码依赖于平台,但 Python 支持的任何编码都可以传递。
  • errors:指定如何处理编码和解码错误,不能在二进制模式下使用。
  • newline:控制如何换行
  • closefd:如果 closefd 为 False 且给出的不是文件名而是文件描述符,那么当文件关闭时,底层文件描述符将保持打开状态。如果给出的是文件名,则 closefd 必须为 True (默认值),否则将触发错误。
  • opener: 可以通过传递可调用的 opener 来使用自定义开启器。然后通过使用参数( file,flags )调用 opener 获得文件对象的基础文件描述符。 opener 必须返回一个打开的文件描述符(使用 os.open as opener 时与传递 None 的效果相同)。

支持的模式:

模式描述
t文本模式 (默认)。
x写模式,新建一个文件,如果该文件已存在则会报错。
b二进制模式。
+打开一个文件进行更新(可读可写)。
U通用换行模式(不推荐)。
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

Python读写文件区分文本文件和二进制文件,读文本文件时,返回内容是字符串,二进制模式返回的类型是bytes对象。

buffering 是用于设置缓冲策略的可选整数。规则有:

缓冲是用于设置缓冲策略的可选整数。规则有:

  • 传递 0 以关闭缓冲(仅在二进制模式下允许)
  • 传递 1 以选择行缓冲(仅在文本模式下可用)
  • 传递大于1的整数以指示固定大小块缓冲区的字节大小
  • 如果取负值,寄存区的缓冲大小则为系统默认

如果未给出缓冲参数(使用默认的或者负值),默认缓冲策略的工作方式如下:

  • 二进制文件缓冲在固定大小的块中; 缓冲区的大小使用启发式选择,试图确定底层设备的默认缓冲区块大小(block size)和 回溯到
    io.DEFAULT_BUFFER_SIZE 和回溯到io。默认缓冲区大小。在许多系统上,缓冲区的长度通常为4096或8192字节。
  • “交互式”文本文件( satty() 返回 True的文件)使用行缓冲。其他文本文件使用上述策略用于二进制文件。

errors 是一个可选的字符串参数,用于指定如何处理编码和解码错误 - 这不能在二进制模式下使用。可以使用各种标准错误处理程序(列在 错误处理方案 ),但是使用 codecs.register_error() 注册的任何错误处理名称也是有效的。标准名称包括:

  • 如果存在编码错误,‘strict’ 会引发 ValueError 异常。 默认值 None 具有相同的效果。
  • ‘ignore’ 忽略错误。请注意,忽略编码错误可能会导致数据丢失。
  • ‘replace’ 会将替换标记(例如 ‘?’ )插入有错误数据的地方。
  • ‘surrogateescape’ 将把任何不正确的字节表示为 U+DC80U+DCFF 范围内的下方替代码位。 当在写入数据时使用
  • surrogateescape 错误处理句柄时这些替代码位会被转回到相同的字节。 这适用于处理具有未知编码格式的文件。
  • 只有在写入文件时才支持 ‘xmlcharrefreplace’。编码不支持的字符将替换为相应的XML字符引用 &#nnn;
  • ‘backslashreplace’ 用Python的反向转义序列替换格式错误的数据。
  • ‘namereplace’ (也只在编写时支持)用 \N{...} 转义序列替换不支持的字符。

newline 控制 universal newlines 模式如何生效(它仅适用于文本模式)。它可以是 None,'','\n','\r' 和 '\r\n'。它的工作原理:

  • 从流中读取输入时,如果 newline 为 None,则启用通用换行模式。输入中的行可以以 ‘\n’,‘\r’ 或 ‘\r\n’ 结尾,这些行被翻译成 ‘\n’ 在返回呼叫者之前。如果它是 ‘’,则启用通用换行模式,但行结尾将返回给调用者未翻译。如果它具有任何其他合法值,则输入行仅由给定字符串终止,并且行结尾将返回给未调用的调用者。
  • 将输出写入流时,如果 newline 为 None,则写入的任何 ‘\n’ 字符都将转换为系统默认行分隔符 os.linesep。如果 newline 是 ‘’ 或 ‘\n’,则不进行翻译。如果 newline 是任何其他合法值,则写入的任何 ‘\n’ 字符将被转换为给定的字符串。

文件对象

一个文件被open()函数打开后,将返回文件对象,可以通过文件对象进行各种操作。

文件对象的属性:

属性描述
file.closed返回true如果文件已被关闭,否则返回false。
file.mode返回被打开文件的访问模式。
file.name返回文件的名称。
file.softspace如果用print输出后,必须跟一个空格符,则返回false。否则返回true。
file = open('test.txt', 'r')
print(f"文件名:{file.name=}”) #文件名:file.name='test.txt'
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=False
print(f"访问模式:{file.mode=}”) #访问模式:file.mode='r'
print(f"{file.buffer=}”) #file.buffer=<_io.BufferedReader name='test.txt'>
print(f"{file.encoding=}”) #file.encoding='UTF-8'
print(f"{file.errors=}”) #file.errors='strict'

文件对象的常见方法:

方法方法及描述
file.close()关闭文件。关闭后文件不能再进行读写操作。
file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
file.fileno()返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。
file.isatty()如果文件连接到一个终端设备返回 True,否则返回 False。
file.next()返回文件下一行。
file.read([size])从文件读取指定的字节数,如果未给定或为负则读取所有。
file.readline([size])读取整行,包括 “\n” 字符。
file.readlines(sizeint])读取所有行并返回列表,若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力。
file.seek(offset[,whence])设置文件当前位置
file.tell()返回文件当前位置。
file.truncate([size])截取文件,截取的字节通过size指定,默认为当前文件位置。
file.write(str)将字符串写入文件,返回的是写入的字符长度。
file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。
for line in file:
print(line)通过迭代器访问文件内容

关闭文件

使用open()函数打开的文件,必须要关闭。

语法为:

file.close()

close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。

文件必须被正常关闭,否则可能会引发文件锁或者文件句柄数太多等系统问题。

file = open('test.txt', 'r')
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=False
file.close()
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=True

为了保证在异常情况下关闭文件,一般要把close()方法写到try…finally里,也可以通过上下文管理器进行自动管理:

with open('test.txt', 'r') as file:
    print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=False
    pass

print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=True

向文件中写入数据

向文件中写入数据有多个方法:

file.write(str)
file.writelines(list)

file.write(str)将字符串str写文件

file.writelines(list)将一个字符串list写入文件,注意默认是没有换行符的,需要自己在行尾增加换行符。

读取文件数据

读取文件数据有多种方法:

file.read([count])
file.readline([size])
file.readlines()

count是要读取的字节数

size是读取一行的最大字节数。

with open('test.txt', 'w') as file:
    file.write('I love Python!')
    file.writelines(['one\n', 'two\n', 'three'])

with open('test.txt', 'r') as file:
    print(file.read(14))
    print(file.readline())
    print(file.readlines())

‘''
I love Python!
one

['two\n', 'three']
‘''

注意写入文件如果使用w模式,每次都是重头开始覆盖写文件。

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

也可以通过for…in…的方式读取文件:

with open('test.txt', 'w') as file:
    file.write('I love Python!')
    file.writelines(['one\n', 'two\n', 'three'])

with open('test.txt', 'r') as file:
    for line in file:
        print(line)

‘''
I love Python!one

two

three

‘''

文件位置定位

也可以指定位置开始读写。

tell()方法可以告诉我们当前文件的位置,seek(offset [,from])方法改变当前文件的位置。

offset变量表示要移动的字节数。from变量指定开始移动字节的参考位置。

如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。

with open('test.txt', 'w') as file:
    file.write('I love Python!')
    file.writelines(['one\n', 'two\n', 'three'])
    print(file.tell()) 
    file.seek(0, 0)
    file.write('I hate Python!')

with open('test.txt', 'r') as file:
    print(file.read())

‘''
27
I hate Python!one
two
three
‘''

os模块中的常见文件操作

os 模块提供了非常丰富的函数用来处理文件和目录。

函数描述
os.access(path,mode)检验权限模式
os.chdir(path)改变当前工作目录
os.chflags(path,flags)设置路径的标记为数字标记。
os.chmod(path,mode)更改权限
os.chown(path,uid,gid)更改文件所有者
os.chroot(path)改变当前进程的根目录
os.close(fd)关闭文件描述符 fd
os.closerange(fd_low,fd_high)关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略
os.dup(fd)复制文件描述符 fd
os.dup2(fd,fd2)将一个文件描述符 fd 复制到另一个 fd2
os.fchdir(fd)通过文件描述符改变当前工作目录
os.fchmod(fd,mode)改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。
os.fchown(fd,uid,gid)修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。
os.fdatasync(fd)强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。
os.fdopen(fd[,mode[,bufsize]])通过文件描述符 fd 创建一个文件对象,并返回这个文件对象
os.fpathconf(fd,name)返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。
os.fstat(fd)返回文件描述符fd的状态,像stat()。
os.fstatvfs(fd)返回包含文件描述符fd的文件的文件系统的信息,像 statvfs()
os.fsync(fd)强制将文件描述符为fd的文件写入硬盘。
os.ftruncate(fd,length)裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。
os.getcwd()返回当前工作目录
os.getcwdu()返回一个当前工作目录的Unicode对象
os.getenv()读取环境变量
os.getlogin()返回进程的控制终端上登录的用户的名称。
os.putenv()设置环境变量
os.isatty(fd)如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。
os.lchflags(path,flags)设置路径的标记为数字标记,类似 chflags(),但是没有软链接
os.lchmod(path,mode)修改连接文件权限
os.lchown(path,uid,gid)更改文件所有者,类似 chown,但是不追踪链接。
os.link(src,dst)创建硬链接,名为参数 dst,指向参数 src
os.listdir(path)返回path指定的文件夹包含的文件或文件夹的名字的列表。
os.lseek(fd,pos,how)设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效
os.lstat(path)像stat(),但是没有软链接
os.major(device)从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。
os.makedev(major,minor)以major和minor设备号组成一个原始设备号
os.mkedirs(path[,mode])递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。
os.minor(device)从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。
os.mkdir(path[,mode])以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。
os.mkfifo(path[,mode])创建命名管道,mode 为数字,默认为 0666 (八进制)
os.mknod(filename[,mode=0600,device])创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。
os.open(file,flags[,mode])打开一个文件,并且设置需要的打开选项,mode参数是可选的
os.openpty()打开一个新的伪终端对。返回 pty 和 tty的文件描述符。
os.pathconf(path,name)返回相关文件的系统配置信息。
os.pipe()创建一个管道. 返回一对文件描述符(r, w) 分别为读和写
os.popen(command[,mode[,bufsize]])从一个 command 打开一个管道
os.read(fd,n)从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。
os.readlink(path)返回软链接所指向的文件
os.remove(path)删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。
os.removedirs(path)递归删除目录。
os.rename(src,dst)重命名文件或目录,从 src 到 dst
os.renames(old,new)递归地对目录进行更名,也可以对文件进行更名。
os.rmdir(path)删除path指定的空目录,如果目录非空,则抛出一个OSError异常。
os.stat(path)获取path指定的路径的信息,功能等同于C API中的stat()系统调用。
os.stat_float_times([newvalue])决定stat_result是否以float对象显示时间戳
os.statvfs(path)获取指定路径的文件系统统计信息
os.symlink(src,dst)创建一个软链接
os.system()运行shell命令
os.exit()终止当前进程
os.tcgetgrp(fd)返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组
os.tcsetpgrp(fd,pg)设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。
os.tempnam([dir[,prefix]])返回唯一的路径名用于创建临时文件。
os.tmpfile()返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。
os.tmpnam()为创建一个临时文件返回一个唯一的路径
os.ttyname(fd)返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。
os.unlink(path)删除文件
os.utime(path,times)返回指定的path文件的访问和修改的时间。
os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]])输出在文件夹中的文件名通过在树中游走,向上或者向下。
os.write(fd,str)写入字符串到文件描述符 fd中. 返回实际写入的字符串长度
os.path获取文件的属性信息。

子模块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(path)路径存在则返回 True,路径损坏也返回 True
os.path.expanduser(path)把 path 中包含的 ~ 和 ~user 转换成用户目录
os.path.expandvars(path)根据环境变量的值替换 path 中包含的 $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路径名
import os 
 
# 获取文件路径 
file_path = "/Users/username/Documents/test.txt" 
dir_path = os.path.dirname(file_path) 
 
print("文件路径为:", file_path) 
print("文件所在目录为:", dir_path) 

‘’’
文件路径为: /Users/username/Documents/test.txt 
文件所在目录为: /Users/username/Documents 
’’’

file_path = "/Users/username/Documents/test.txt" 
file_name = os.path.basename(file_path) 
 
print("文件路径为:", file_path) 
print("文件名为:", file_name) 

‘’’
文件路径为: /Users/username/Documents/test.txt 
文件名为: test.txt 
’’’

# 获取文件扩展名 
file_path = "/Users/username/Documents/test.txt" 
file_ext = os.path.splitext(file_path)[1] 
 
print("文件路径为:", file_path) 
print("文件扩展名为:", file_ext) 
‘’’
文件路径为: /Users/username/Documents/test.txt 
文件扩展名为: .txt 
’‘’

检测文件或目录是否存os.access()

检查文件或目录是否存在和可访问,语法为:

os.access(path, mode)

参数:

  • path – 要用来检测是否有访问权限的路径。

  • mode – mode为F_OK,测试存在的路径,或者它可以是包含R_OK, W_OK和X_OK或者R_OK, W_OK和X_OK其中之一或者更多。

  • os.F_OK: 作为access()的mode参数,测试path是否存在。

  • os.R_OK: 包含在access()的mode参数中 , 测试path是否可读。

  • os.W_OK 包含在access()的mode参数中 , 测试path是否可写。

  • os.X_OK 包含在access()的mode参数中 ,测试path是否可执行。

如果允许访问返回 True , 否则返回False。

import os
 
print(os.access('test.txt', os.F_OK)) 
print(os.access('test.txt', os.W_OK))

os.open()

用于打开一个文件,并且设置需要的打开选项,模式参数mode参数是可选的,默认为 0777。

语法格式如下:

os.open(path, flags, mode=0o777, *, dir_fd=None)

参数:

  • file – 要打开的文件

  • flags – 该参数可以是以下选项,多个使用 “|” 隔开:

  • os.O_RDONLY: 以只读的方式打开

  • os.O_WRONLY: 以只写的方式打开

  • os.O_RDWR : 以读写的方式打开

  • os.O_NONBLOCK: 打开时不阻塞

  • os.O_APPEND: 以追加的方式打开

  • os.O_CREAT: 创建并打开一个新文件

  • os.O_TRUNC: 打开一个文件并截断它的长度为零(必须有写权限)

  • os.O_EXCL: 如果指定的文件存在,返回错误

  • os.O_SHLOCK: 自动获取共享锁

  • os.O_EXLOCK: 自动获取独立锁

  • os.O_DIRECT: 消除或减少缓存效果

  • os.O_FSYNC : 同步写入

  • os.O_NOFOLLOW: 不追踪软链接

  • mode 可用以下选项按位或操作生成, 目录的读权限表示可以获取目录里文件名列表, ,执行权限表示可以把工作目录切换到此目录 ,删除添加目录里的文件必须同时有写和执行权限 ,文件权限以用户id->组id->其它顺序检验,最先匹配的允许或禁止权限被应用。

  • stat.S_IXOTH: 其他用户有执行权0o001

  • stat.S_IWOTH: 其他用户有写权限0o002

  • stat.S_IROTH: 其他用户有读权限0o004

  • stat.S_IRWXO: 其他用户有全部权限(权限掩码)0o007

  • stat.S_IXGRP: 组用户有执行权限0o010

  • stat.S_IWGRP: 组用户有写权限0o020

  • stat.S_IRGRP: 组用户有读权限0o040

  • stat.S_IRWXG: 组用户有全部权限(权限掩码)0o070

  • stat.S_IXUSR: 拥有者具有执行权限0o100

  • stat.S_IWUSR: 拥有者具有写权限0o200

  • stat.S_IRUSR: 拥有者具有读权限0o400

  • stat.S_IRWXU: 拥有者有全部权限(权限掩码)0o700

  • stat.S_ISVTX: 目录里文件目录只有拥有者才可删除更改0o1000

  • stat.S_ISGID: 执行此文件其进程有效组为文件所在组0o2000

  • stat.S_ISUID: 执行此文件其进程有效用户为文件所有者0o4000

  • stat.S_IREAD: windows下设为只读

  • stat.S_IWRITE: windows下取消只读

  • dir_fd基于目录描述符的相对路径: 如果 dir_fd 不是 None,它就应该是一个指向目录的文件描述符,这时待操作的 path 应该是相对路径,相对路径是相对于前述目录的。如果 path 是绝对路径,则 dir_fd 将被忽略。

import os, sys

# 打开文件
fd = os.open( "foo.txt", os.O_RDWR|os.O_CREAT )

# 写入字符串
os.write(fd, "This is test")

# 关闭文件
os.close( fd )

os.fdopen()

通过文件描述符 fd 创建一个文件对象,并返回这个文件对象。

法格式如下:

os.fdopen(fd, [, mode[, bufsize]]);

参数:

  • fd – 打开的文件的描述符,在Unix下,描述符是一个小整数。
  • mode – 可选,和bufsize参数和Python内建的open函数一样,mode参数可以指定『r,w,a,r+,w+,a+,b』等,表示文件的是只读的还是可以读写的,以及打开文件是以二进制还是文本形式打开。这些参数和C语言中的<stdio.h>中fopen函数中指定的mode参数类似。
  • bufsize – 可选,指定返回的文件对象是否带缓冲:bufsize=0,表示没有带缓冲;bufsize=1,表示该文件对象是行缓冲的;bufsize=正数,表示使用一个指定大小的缓冲冲,单位为byte,但是这个大小不是精确的;bufsize=负数,表示使用一个系统默认大小的缓冲,对于tty字元设备一般是行缓冲,而对于其他文件则一般是全缓冲。如果这个参数没有制定,则使用系统默认的缓冲设定。

通过文件描述符返回的文件对象。

import os, sys

# 打开文件
fd = os.open( "foo.txt", os.O_RDWR|os.O_CREAT )
# 获取以上文件的对象
fo = os.fdopen(fd, "w+")

# 获取当前文章
print(f"Current I/O pointer position :{fo.tell()}")

# 写入字符串
fo.write( "Python is a great language.\nYeah its great!!\n");

# 读取内容
os.lseek(fd, 0, 0)
str = os.read(fd, 100)
print("Read String is : ", str)

# 获取当前位置
print(f"Current I/O pointer position :{fo.tell()}")

# 关闭文件
os.close( fd )
print("关闭文件")

open()、os.open()、os.fdopen()

open() 函数用于打开一个文件,创建一个文件对象

os.open()创建操作系统级文件描述符

os.fdopen()从文件描述符中创建一个文件对象。也就是说,os.fdopen()是以os.open()返回的基础上得到一个文件对象。

os.close()

关闭指定的文件描述符 。

语法格式如下:

os.close(fd);

该方法没有返回值。

os.read()

用于从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。

在Unix,Windows中有效

语法格式如下:

os.read(fd,n)

参数:

  • fd – 文件描述符。
  • n – 读取的字节。

返回包含读取字节的字符串

os.write()

语法格式如下:

os.write(fd, str)

参数:

  • fd – 文件描述符。
  • str – 写入的字符串。

该方法返回写入的实际位数。

os.rename()

rename() 方法需要两个参数,当前的文件名和新文件名。

语法:

os.rename(current_file_name, new_file_name)

例子:

下例将重命名一个已经存在的文件test1.txt。

import os
 
# 重命名文件test1.txt到test2.txt。
os.rename( "test1.txt", "test2.txt" )

os.remove()

可以用remove()方法删除文件,需要提供要删除的文件名作为参数。

语法:

os.remove(file_name)

例子:

下例将删除一个已经存在的文件test2.txt

import os
 
# 删除一个已经存在的文件test2.txt
os.remove("test2.txt")

os.mkdir()

语法:

os.mkdir("newdir")

例子:

下例将在当前目录下创建一个新目录test。

import os
 
# 创建目录test
os.mkdir("test")

os.rmdir()

删除目录,目录名称以参数传递。

在删除这个目录之前,它的所有内容应该先被清除。

语法:

os.rmdir('dirname')

例子:

以下是删除" /tmp/test"目录的例子。目录的完全合规的名称必须被给出,否则会在当前目录下搜索该目录。

import os

删除”/tmp/test”目录

os.rmdir( “/tmp/test” )

以上就是“Python进阶(八)文件操作”的全部内容,希望对你有所帮助。

关于Python技术储备**

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。
**

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值