• 15.python文件(file)方法详解


    文件的基本操作

    文件读写:

    文件的读写满足以下3个步骤:

    1).打开文件

    2).操作数据(读、写)

    3).关闭文件 --> 不要忘记

    1).打开文件:

    python的open() 方法用于打开一个文件,并返回文件对象,此文件对象在python中是一个特殊的类型,它用于在python程序中对外部的文件进行操作。在python中一切都是对象,file也不例外,file有file的方法和属性。先来看如何创建一个file对象:file(name[, mode[, buffering]]),file()函数用于创建一个file对象,它有一个别名叫open(),可能更形象一些,它们是内置函数。在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。

    【注意】:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

     1 # open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)
     2 open(file, mode='r')
     3 
     4 # 完整的语法格式为:
     5 open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

    参数说明:

    • file:             必需,文件路径(相对或者绝对路径)
    • mode:         可选,文件打开模式
    • buffering:    设置缓冲
    • encoding:    一般使用utf-8,确定字符集(编码、解码);如果不定义,默认使用gbk进行编码和解码使用
    • errors:         编码解码不一致报错时会报错,如果定义errors = 'ignore',不会报错但是会乱码,(相对友好)
    • newline:      区分换行符
    • closefd:      传入的file参数类型
    • opener:

    不同模式打开文件的完全列表(即mode参数有类型):

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


    File对象的属性:

    一个文件被打开后,会返回一个file对象,你可以得到有关该文件的各种信息。

    1.file.closed返回true如果文件已被关闭,否则返回false。

    2.file.mode:返回被打开文件的访问模式。

    3.file.name:返回文件的名称。

    4.file.softspace:如果用print输出后,必须跟一个空格符,则返回false。否则返回true。

    1 # 打开一个文件
    2 fo = open("foo.txt", "w")
    3 
    4 print(fo.name)        # 文件名:  foo.txt
    5 print(fo.closed) # 是否已关闭:False
    6 print(fo.mode) # 访问模式: w 7 print(fo.softspace) # 末尾是否强制加空格: 0

    2).读写文件:

    file对象提供了一系列方法,能让我们的文件访问更轻松。

    1.read([size])从文件读取指定的字符数,如果未给定或为负则读取所有。

    2.readline([size])从文件中的一行读取指定的字符数,如果未给定则读取整行,包括 " " 字符。(以字符串的形式返回)

    3.readlines()读取所有行并返回列表,若给定sizeint>0,则是设置一次读多少字符,这是为了减轻读取压力。(返回列表)

    4.tell()返回文件当前位置(返回文件描述符所定位到的已读字节数),注意是字节

    5.seek(num)设置文件当前位置(将文件描述符回到num个字节位置),注意是字节

    6.write(str)将字符串写入到文件中,python字符串可以是二进制数据,而不是仅仅是文字。

    7.writelines(seq):向文件中写入一序列的字符串,把seq的内容全部写到文件中(多行一次性写入)。

    演示读操作

     1 # 假设a.txt文件中的内容是 abcdefg1234567
     2 
     3 path = r'D:pythonproject文件读写a.txt'
     4 
     5 # 1.打开文件
     6 fr = open(path,'r')   
     7 
     8 # 2.读取文件中的数据
     9 print(fr.read(3))    # 得到 abc 读的是字符
    10 print(fr.read(4))    # 得到 defg 读的是字符
    11 print(fr.read())      # 得到 1234567(读取剩余的所有)
    12 
    13 # tell():返回已读的字节数
    14 print(fr.tell())        #接上面的代码的到 14
    15 
    16 # seek(num):将文件描述符移动到num字节位,返回新的文件位置,从num字节位开始
    17 fr.seek(4)         # 表示起始位置从第四位后面的开始
    18 print(fr.read())   #得到efg1234567
    19 
    20 # 3.关闭文件
    21 fr.close()

     

    演示read()tell()seek()此三个函数参数&返回值的理解

     1 #假设b.txt文件中的内容是 哈哈呵呵嘿嘿
     2 
     3 path = r'b.txt'
     4 
     5 fr = open(path,'r',encoding='gbk')    # 以gbk的方式进行解码
     6 
     7 #read(num): num记录的是字符数
     8 print(fr.read(2))         # 得到 哈哈
     9  
    10 #tell():返回已读的字节数    注意:不是字符
    11 print(fr.tell())          # 得到 4
    12 
    13 print(fr.read())          # 将内容全部读完  呵呵嘿嘿
    14 
    15 print(fr.tell())          # 得到 12
    16 
    17 # seek(num):num记录了字节数
    18 fr.seek(4)                # 标识符停在第二个‘哈’上   
    19 print(fr.read())          # 得到  呵呵嘿嘿
    20 
    21 # 以下代码会报错,相当于停在第三个字节上,把第二个哈字一分为二,不可以(一个汉字是占两个字节)
    22 # fr.seek(3)
    23 # print(fr.read())
    24 
    25 fr.close()

    演示写操作:

     1 # 打开一个文件
     2 fo = open("foo.txt", "w")
     3 # 写入内容
     4 fo.write( "www.runoob.com!
    Very good site!
    ")
     5  
     6 # 关闭打开的文件
     7 fo.close()
     8 
     9 # *******文件内容*********
    10 www.runoob.com!
    11 Very good site!
    12 

    【注意】:write()的特点

    1).如果需要写入的文件并不存在,先创建文件,再写入数据

    2).'w' 操作不能追加数据到文件中,只能覆盖之前的内容

    3).'a' 表示追加字符(保留原本的,不会覆盖掉)

    4).write()没有自动换行的功能,所以用

    【补充】:读取文件的三个方法:read()、readline()、readlines()的对比

     1 # read()方法读取整个文件,将文件内容放到一个字符串变量中。如果文件非常大,尤其是大于内存时,无法使用read()方法。
     2 # readline()方法每次读取一行;返回的是一个字符串对象,保持当前行的内存,但是比readlines慢得多。
     3 # readlines()方法一次性读取整个文件;自动将文件内容分析成一个行的列表,文件大时占内存。
     4 
     5 # 两种文件的遍历方法比较,for循环
     6 # 法一:
     7 for line in open('myfile.txt','r').readlines():
     8         print(line,end='')
     9 
    10 # 法二
    11 for line in open('myfile.txt','r'):
    12         print(line,end='')
    13 
    14 
    15 # 两种方法的运行结果是一样的,但是实际有很大的区别:
    16 # 法一通过readlines一次性把文件载入到行字符串列表中,然后再对字符串列表进行迭代;
    17 # 法二运行的原理有所不同,它并非一次性将所有的内容加载到内存中,而是在迭代的时候,循环到哪一行才将哪一行读入到内存的,
    18 # 这里涉及到迭代器。因此在这里法二是文本文件读取的最佳选择,简单,且对任意大小的文件都有效,不会产生内存压力过大的问题。

    3).关闭文件

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

    当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。

    1 # 关闭打开的文件
    2 fo.close()

    强大的文件操作之shutil模块

    pyhton的shutil模块是一个高级的文件,文件夹,压缩包的处理模块,它提供了一些针对文件和目录的高级操作,主要是拷贝、移动。对于单个文件的操作,还可参考os模块。

    Warning: 即使是高级别的拷贝函数(shutil.copy(),shutil.copy2())也不能拷贝所有的文件元数据。意思是:在POSIX系统中,文件所有者、属组以及ACL信息会丢失。在Windows平台上,文件所有者,ACL以及ADS(供选数据流)不会被复制。

    shutil模块常见的方法:

    1.shutil.copy("oldfile","newfile"):拷贝文件的内容和权限位,newfile可以是文件或目录;copy()使用copymode()拷贝权限位,使用copyfile()拷贝文件内容

    2.shutil.copy2("oldfile","newfile"):拷贝文件和状态信息;copy2()使用copystat()拷贝元数据,使用copyfile()拷贝文件内容,复制后的结果保留了原来的所有信息(包括状态信息)

    3.shutil.copyfile("oldfile","newfile"):拷贝(复制)文件,oldfile和newfile都只能是文件,如果newfile不存在则自动创建;特殊文件比如块设备、字符设备、管道不能使用此函数复制

    4.shutil.copyfileobj(fsrc,fdst[,length]):将一个文件的内容拷贝的另外一个文件当中,可以指定length长度进行拷贝(不常用)

    5.shutil.copymode(src,dst):仅拷贝权限,内容、组、用户均不变(不常用)

    6.shutil.copystat(src,dst):拷贝状态的信息,包括:mode bits,atime,mtime,flags(不常用)

    7.shutil.copytree("olddir","newdir"):复制整个文件夹(目录),无论文件夹是否为空,均可以复制,而且会复制文件夹中的所有内容,olddir和newdir都只能是目录,且newdir必须不存在,若newdir文件夹已经存在,就会返回一个FileExistsError错误

    8.shutil.move("oldpos","newpos"):移动文件/重命名文件

    9.shutil.rmtree("dir"): 删除文件夹(目录),空目录、有内容的目录都可以删(删除的是文件夹)

    【补充】:

     os.mkdir("file"):     创建目录

       os.rename("oldname","newname"):重命名文件(目录),文件或目录都是使用这条命令

       os.remove("file"):  删除文件

       os.rmdir("dir"):      删除目录,只能删除空目录    

       os.chdir("path") :  转换目录,换路径

     1 import shutil
     2 
     3 shutil.copy("src.txt", "dst.txt")      # 输出 'dst.txt'
     4 shutil.copy("src.txt", "/tmp/")        # 输出 '/tmp/src.txt'
     5 shutil.copy("src.txt", "/Dota2/")      # 传入一个不存在的目录,出现IsADirectoryError:
     6  
     7 shutil.copy2("src.txt", "dst.txt")
     8 
     9 shutil.copyfile("src.txt", "dst.txt")
    10 
    11 shutil.copyfileobj(open("fsrc.txt", "rb"), open("fdst.txt", "wb"))
    12 shutil.copymode('f1.log', 'f2.log')
    13 shutil.copystat('f1.log', 'f2.log')
    14 
    15 shutil.copytree('folder1', 'folder2')  # 如果folder2文件夹已经存在,就会返回一个FileExistsError错误
    16 
    17 shutil.rmtree('folder1')               # 删除文件夹folder1
    18 
    19 # 移动文件/重命名文件 shutil.move()
    20 shutil.move('E:\first\123.txt', 'E:\second') # 移动文件,输出结果'E:\second\123.txt' 21 shutil.move('E:\first\123.txt', 'E:\first\aaa') # 重命名文件,输出结果'E:\first\aaa'

    演示os.chdir("path") :

    1 # 使用os模块,将当前工作目录设置在E盘
    2 
    3 #假设当前路径 C:\Users\first
    4 
    5 import os
    6 
    7 os.chdir('E:\')    # 换路径
    8 
    9 os.getcwd()    # 即可看到输出结果为 'E:\'

     【补充】:

    演示自定义函数copyFile:实现文件复制有形参(2个物理地址)、没有返回值(复制完就复制完了))

           原始版:相当于一次性复制了,当文件容量过大的时候,一次性复制,内存受不了,有弊端

     1 def copyFile(src,dest):       # src表示原始文件,dest表示目标文件 
     2     # 1.打开两个文件:1个关联读操作、1个关联写操作
     3     fr = open(src,'rb')       # 打开字节文件  rb也可以读字符文件,是万能的打开方式,字节也没有编码的概念了
     4     fw = open(dest,'wb')
     5 
     6     # 2.实现读和写操作
     7     content = fr.read()       #读进来
     8     fw.write(content)         #写出去
     9 
    10     # 3.关闭两个文件
    11     fw.close()
    12     fr.close()
    13 
    14 copyFile(r'C:UsersAdministratorDesktopfirst.gif',r'C:UsersAdministratorDesktopfirst1.gif')
    16    

          升级版:可以分段慢慢复制,并不是一下子全读进去,不用担心文件容量过大

     1 def copyFile(src,dest):
     2     # 1.打开两个文件:1个关联读操作、1个关联写操作
     3     fr = open(src, 'rb')
     4     fw = open(dest, 'wb')
     5 
     6     # 2.实现读和写操作(无限循环的读写,并不是一下子全读进去)
     7     while 1:
     8         content = fr.read(1024)       # 每次读1024字节大小
     9         if not content:               # not取反(读完全部就退出)
    10             break
    11         else:
    12             fw.write(content)
    13 
    14     # 3.关闭两个文件
    15     fw.close()
    16     fr.close()
    17 
    18 copyFile(r'C:UsersAdministratorDesktopa.avi',r'C:UsersAdministratorDesktop.avi')
    
    
  • 相关阅读:
    idea 代码提交到gitee
    flink+nacos实现参数化配置
    循环依赖的学习
    protobuf学习
    idea重置试用期插件
    Idea git 指定回滚版本
    Tomcat8下的Redis会话共享
    建造者设计模式
    Servlet中跨域问题详解
    gRPC
  • 原文地址:https://www.cnblogs.com/bonheur/p/12359217.html
Copyright © 2020-2023  润新知