• 第七章 -- 关于文件


    # open() 内置函数
    # 格式 open(file_name [,access_mode [, buffering]])

    """
    关于第三个参数 -- buffering
    1 如果参数为 0 ,打开的文件就不是带缓冲的
    2 如果参数为 1 或者 True ,打开的文件就是带缓冲的
    3 如果是一个 >1 的正数 ,则用于指定缓冲区的大小
    4 如果是任意负数,则代表使用默认的缓冲区大小
    PS --
    由于外设的读写速度远远小于内存的速度,为了更好的完成数据处理,会将数据首先
    传递到缓冲区,然后再进行操作
    """
    # 打开文件后,就可以调用文件对象的属性和方法
    """
    1 file.closed -- 返回文件是否已经关闭
    2 file.mode -- 返回被打开文件的访问模式
    3 file.name -- 返回文件的名称
    """
    # 注意 默认的打开模式是 r 只读

    # 文件的打开模式
    """
    1 r -- 只读模式
    2 w -- 写模式
    3 a -- 追加模式
    4 + -- 读写模式,可以与其它模式结合使用
    比如: r+ 代表读写模式 ; w+ 也代表读写模式
    5 b -- 二进制模式,可以与其它模式结合使用
    比如: br 代表二进制只读模式
    """
    # 注意
    """
    1 w / w+ 模式打开文件后,会进行清空处理
    2 使用 r / r+ 模式打开文件,要求打开的文件本身存在
    3 w / w+ 或者 a / a+ 模式打开文件 如果文件不存在会被自动创建
    4 b模式可以被追加到其他模式上,可用于以二进制的方式来读写文件内容
    """

    # 读取文件

    # 1 按字节或字符读取 -- read (到底是字节还是字符,取决于是否使用了b模式--字节)

    print("示范 字节或字符 来读取文件内容")

    f = open(r"镜像源安装.txt","r",True)

    while True :
    # 读取字符
    #ch = f.read(1) # 每次读取一个字符
    ch = f.read() # 如果没有指定参数,默认读取文件下的全部内容
    # 如果没有读到数据,则跳出循环
    if not ch :
    break
    # 输出
    print(ch,end=" ")

    f.close() # 读取完数据后,推荐立即使用 close 关闭文件,以避免资源泄露

    # 注意
    """
    1 默认情况下,open函数使用当前操作系统的字符集解析打开的文件,比如 Windows 的 GBK
    2 如果待读取的文件不是使用当前操作系统的字符集,则需要进行字符集处理
    """

    # 2 按行读取 -- 文本文件才有行的概念
    # 文件对象提供了两种方法来读取行
    """
    1 读取一行内容,如果指定了参数 n ,则只读取此行内的 n 个字符 -- readline([n])
    2 读取文件内所有行

    """

    # 示范 readline 方法来读取文件内容 -- 逐行读取
    # readline() 函数在读取文件中一行的内容时,会读取最后的换行符“ ”,再加上 print() 函数输出内容时默认会换行,
    # 所以输出结果中会看到多出了一个空行

    print("示范 行模式 来读取文件内容 ---- 逐行读取 ")

    import codecs
    # 指定 utf-8 字符集读取内容
    f = codecs.open(r"镜像源安装.txt",'r',"utf-8",buffering=True)
    while True:
    # 以行读取
    line = f.readline() # 未指定参数,代表读取完整的一行
    # 如果没有读取数据,则跳出循环
    if not line:
    break
    # 输出 line
    print(line,end="")

    f.close()

    # 示范 readlines 方法来读取文件内容 -- 一次读取所有行
    # readlines() 函数在读取每一行时,会连同行尾的换行符一块读取

    print("示范 行模式 来读取文件内容 ---- 一次读取所有行 ")


    import codecs

    # 指定 utf-8 字符集读取内容
    f = codecs.open(r"镜像源安装.txt",'r',"utf-8",buffering=True)

    # 使用 readlines 读取所有行,返回所有行组成的列表
    for i in f.readlines():
    print(i,end="")
    f.close()

    # 文件指针 -- 用于标明文件的读写位置
    """
    假如把文件看成一个水流,文件中的每个数据(以b模式打开,每个数据就是一个字节;以普通模式打开
    ,每个数据就是一个字符)就相当于水滴,而文件指针就标明了文件将要读到哪个位置
    """

    # -- 操作文件指针的常用方法
    """
    tell() -- 判断文件指针的位置
    seek(offset [,whence]) --该方法把文件指针移动到指定位置。
    当 whence 为 0 时(默认值) ,表明文件从开头开始计算 ;当 whence 为 1 时(默认值) ,表明文件
    从当前位置开始计算 ;当 whence 为 2 时(默认值) ,表明文件从结尾处开始计算
    offset:表示相对于 whence 位置文件指针的偏移量,正数表示向后偏移,负数表示向前偏移。

    例如,当whence == 0 &&offset == 3(即 seek(3,0) ),表示文件指针移动至距离文件开头处 3 个字符的位置;
    当whence == 1 &&offset == 5(即 seek(5,1) ),表示文件指针向后移动,移动至距离当前位置 5 个字符处。

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

    # 示范 -- 文件指针

    import codecs
    # 指定使用 UTF-8 字符集读取文件内容
    f = codecs.open(r"镜像源安装.txt",'rb','utf-8',buffering=True)

    # 判断文件指针的位置
    print(f.tell())

    # 将文件指针移动到第3处
    f.seek(3)
    print(f.tell())

    # 读取一个字节,文件指针自动后移1个数据
    print(f.read(1))
    print(f.tell())

    # 将文件指针移动到第5处
    f.seek(5)
    print(f.tell())

    #将文件指针向后移动5个数据
    f.seek(5,1)
    print(f.tell())

    # 将文件指针移动到倒数第10处
    f.seek(-10,2)
    print(f.tell())

    # 输出内容
    # 文件对象提供的写文件的方法主要有两种
    """
    write(str或bytes) -- 输出字符串或字节串 ,只有以二进制的模式打开的文件才能写入字节串
    writelines(可迭代对象) -- 输出多个字符串或字节


    在写入文件完成后,一定要调用 close() 函数将打开的文件关闭,否则写入的内容不会保存到文件中。
    这是因为,当我们在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 函数时,操作系统才会保证把没有写入的数据全部写入磁盘文件中。
    除此之外,如果向文件写入数据后,不想马上关闭文件,也可以调用文件对象提供的 flush() 函数,它可以实现将缓冲区的数据写入文件中

    需要注意的是,使用 writelines() 函数向文件中写入多行数据时,不会自动给各行添加换行符,在实际操作过程中如果想添加换行可是使用 os.linesep 实现


    """

    import os
    f = open("demo.txt",'w+')

    # os.linesep 代表当前操作系统的换行符
    f.write('我爱Python'+os.linesep)
    f.writelines(('窗前明月光'+os.linesep,
    '疑是地上霜'+os.linesep,
    '举头望明月'+os.linesep,
    '低头思故乡'+os.linesep))

    f.close()

    ff = open(r"demo.txt",'r')
    print(ff.read())

    ff.close()

    # 注意
    """
    采用上面的方法输入文件时,程序会使用当前操作系统默认的字符集
    如果需要指定的字符集来输出文件,则可以采用二进制形式--程序先将
    所输出的字符串转换为指定的字符集对应的二进制数据(字节串),然后输出二进制数据
    """

    print("-----------------------------------------")

    import os
    f = open("test2.txt",'wb+')

    # os.linesep 代表当前操作系统的换行符
    f.write(('我爱Python'+os.linesep).encode('utf-8'))
    f.writelines((('窗前明月光'+os.linesep).encode('utf-8'),
    ('疑是地上霜'+os.linesep).encode('utf-8'),
    ('举头望明月'+os.linesep).encode('utf-8'),
    ('低头思故乡'+os.linesep).encode('utf-8')))

    f.close()

    ff = open(r"test1.txt",'rb')
    print(ff.read())

    ff.close()

    # 解决字符集不匹配的方式
    """
    1 使用二进制模式读取,然后用 bytes 的 decode()方法恢复字符集
    2 利用 codecs 模块的 open()函数来打开文件,该函数允许在打开文件时进行字符集指定
    """

    print("-------------------指定二进制模式读取文件内容--------------------")

    # 指定二进制模式读取文件内容

    f = open(r"镜像源安装.txt",'rb',True)

    # 直接读取全部文件内容,并调用 bytes 的 decode() 方法将字节回复成字符串
    print(f.read().decode('utf-8'))

    f.close()


    print("--------------------使用 codecs 模块的 open() 函数来打开文件-------------------")

    # 使用 codecs 模块的 open() 函数来打开文件 , 以显示模式指定字符集

    import codecs

    # 指定使用 utf-8 字符集读取文件

    f = codecs.open(r"镜像源安装.txt",'r','utf-8',buffering=True)

    while True :
    # 每次读取一个字符
    ch = f.read(1)
    # 如果没有读到数据,则跳出循环
    if not ch :
    break
    # 输出
    print(ch,end='')

    f.close()

    # 使用 with 语句
    """
    前面的程序中,我们都采用了程序主动关闭文件。实际上,Python提供了With语句来管理资源。比如
    可以把打开的文件放在with语句中,这样wIth就会帮我们主动关闭文件。
    with 的语法格式如下:
    with content_expression [as targer(s)]:
    with 代码块
    -- content_expression 用于创建可自动关闭的资源
    """


    import codecs
    # 使用 with 语句打开文件,该语句会负责关闭文件
    with codecs.open(r"镜像源安装.txt",'r','utf-8',buffering=True) as f :
    for line in f :
    print(line,end="")

    print("---------------------------------------------")

    # 程序也可以使用 with 语句来处理通过 fileput.input 合并的多个文件
    import fileinput
    # 使用with语句打开文件,该语句会负责关闭文件
    with fileinput.input(files=(r"镜像源安装.txt",r'‪C:Usersduty1DesktopPython--教学Python疯狂讲义Python_Code33.3append_test.py'),openhook=fileinput.hook_encoded('utf-8')) as ff :
    for line in ff :
    print(line,end="")

    # 补充 ---
    # 关于 fileinput 读取多个输入流
    # fileinput 模块提供了如下函数可以把多个输入流合并在一起
    """
    1 fileinput.input(files=None,inplace=False,backup='',bufsize=0,mode='r',openbook=None)
    -- 该函数中的 files 参数用于指定多个文件输入流。该函数返回一个 FileInput 对象
    -- 当程序使用该函数创建 FileInput 对象之后,便可以通过 for 循环进行行遍历
    files: # 文件的路径列表,默认是stdin方式,多文件['1.txt','2.txt',...]
    inplace: # 是否将标准输出的结果写回文件,默认不取代
    backup: # 备份文件的扩展名,只指定扩展名,如.bak。如果该文件的备份文件已存在,则会自动覆盖。
    bufsize: # 缓冲区大小,默认为0,如果文件很大,可以修改此参数,一般默认即可
    mode:      # 读写模式,默认为只读
    openhook:    # 该钩子用于控制打开的所有文件,比如说编码方式等;
    2 fileinput.filename() -- 返回正在读取的文件的文件名
    3 fileinput.fileno() -- 返回当前文件的文件描述符--实质就是一个文件代号,值为一个整数
    4 fileinput.lineno() -- 返回当前读取的行号
    5 fileinput.filelineno() -- 返回当前读取的行在其文件中的行号
    6 fileinput.isfirstline() -- 返回当前读取的行在其文件中是否为第一行
    7 fileinput.isstdin() -- 返回最后一行是否从 sys.stdin 读取
    8 fileinput.nextfile() -- 关闭当前文件,开始读取下一个文件
    9 fileinput.close() -- 关闭 FileInput 对象
    """

    # 示例程序

    import fileinput
    # 一次读取多个文件
    for line in fileinput.input(files=(r'镜像源安装.txt',r"C:Usersduty1DesktopPython--教学教学课件unit01-认识Python和程序的编写方法StarDraw.txt")):
    # 输出文件名,以及当前行在当前文件中的行号
    print(fileinput.filename(),fileinput.filelineno(),line,end=" ")

    # 关闭文件流
    fileinput.close()

    # 文件迭代器
    # -- 文件对象本身就是可遍历的(就像序列一样),因此,程序完全可以使用 for 循环来遍历文件内容

    # 示范 -- for 循环读取文件内容
    import codecs
    # 指定使用 UTF-8 字符集读取文件内容
    f = codecs.open(r"镜像源安装.txt",'r','utf-8',buffering=True)
    # 使用 for 循环遍历文件对象
    for line in f :
    print(line,end="")
    f.close()

    print("----------------------------------------------------------")
    # 如果有需要,程序也可以使用 list()函数将文件转换为 list 列表 ,就像文件对象的 readlines()方法的返回值

    # 将文件对象转换为list列表
    f = codecs.open(r"镜像源安装.txt",'r','utf-8',buffering=True)
    print(list(f))
    f.close()


    print("----------------------------------------------------------")
    # sys.stdin 也是一个类文件对象,因此可以通过 for 循环遍历 sys.stdin

    # 这就意味着 程序可以通过 for 循环来获取用户的键盘输入

    import sys
    # 使用 for 循环遍历标准输入
    for line in sys.stdin: # 使用 for 循环遍历 sys.stdin
    print('用户输入: ',line,end="")

    print("*************")

    # 程序通过 for 循环来读取用户的键盘输入 -- 用户每输入一行,程序就会输出用户输入的这行

    # 管道输入 -- 将前一个命令的输出,当作下一个命令的输入
    # 语法格式 : cmd1 : cmd2 : cmd3
    # 作用 -- cmd1命令的输出,将会作为cmd2命令的输入;cmd2命令的输入,又将作为cmd3的输入

    # 管道输入 示范
    type ad.txt | python pipein_test.py

    """
    type ad.txt 该命令使用 type 读取文件 ad.txt 的内容,并将内容输出到控制台;但由于使用了管道
    因此该命令的输出会传递到下一个命令
    python pipein_test.py 该命令使用 python 执行 pipein_test.py 程序 。由于该命令前面有管道,
    因此他会把前一个命令的输出当作输入
    """

  • 相关阅读:
    JS调试时返回结果有内容却显示数组长度为0或对象内容为空
    python模块学习之six模块
    python学习之ansible api
    python模块学习之collections
    python模块学习之json
    Tomcat闲聊第二话
    HTTP解读
    实用的工具
    mysql数据库记录
    python模块学习之__future__
  • 原文地址:https://www.cnblogs.com/Skypeduty1225/p/13973473.html
Copyright © 2020-2023  润新知