• Python笔记_第一篇_面向过程_第一部分_7.文件的操作(.txt)


      在平时,我们不光要对程序内的代码进行输入和输出的操作,还要对程序外的文件进行和语言之间的交换、操作和运算。在基础部分,先讲解对于外部的.txt文件的操作。

    第一部分 基本内容讲解

    1.   什么是文件操作?

      平时在进行操作的时候,都是在内存层面进行操作,但是随着程序的关闭,信息也将小时。文件操作的方式就是把操作的内容保存在硬盘上,方便随时进行增、删、改、查的操作。

    2.   操作流程

      (1) 打开文件,得到文件句柄并赋值给一个变量(有一个函数f.fileno(),查看当前的操作句柄编码)。在这里我们要有句柄的概念,在语言中,文件从外部获取后,通过句柄取拿取文件想要的内容。

      (2) 通过句柄对文件进行操作。

      (3) 关闭文件(这个操作是必须的)。

    3.   注意:

      (1) 比如在window系统,一个hello.txt文件是utf8保存的,打开文件是open函数是通过操作系统打开文件,而windows操作系统默认是gbk编码,所以直接打开会乱码,需要f = open('hello.txt', encoding = 'utf-8'),这样打开。

      (2) 文件的操作还要有指针的概念,通过指针读写光标的位置(内部指针的移动)。

    第二部分 相关函数和操作演示

    1.   基本函数  

      函:f.fileno

        语:f.fileno()

          用:获得当前函数句柄的编号。

     1 f = open("咏梅", "r", encoding="utf-8")
     2 fno = f.fileno()
     3 print(fno)
     4 # print(f.fileno()) # 也可以直接打印观察
     5 # 输出结果:3
     6 
     7 f1 = open("咏梅", "r", encoding="utf-8")
     8 fno1 = f1.fileno()
     9 print(fno1)
    10 # print(f1.fileno()) # 也可以直接打印观察
    11 # 输出结果:4

      函:f.name

        语:f.name()

          用:获得当前文件的文件名。

      举例:略

    2.   四个基本操作:开、读、写、关

      “开”:

      函:open

        语:open("file", "mode", buffering =None , encoding = None, errors = None, newline = None, closefd = True)

          用:

      (1) "file"----文件名/路径+文件名 (如果是相对路径直接填写文件名即可),需要加引号

      (2) "mode"----读取模式:

          "r"---- 只读模式

          "w"---- 写模式

          "a"---- 追加内容模式(光标位置在最后)

          "x" ---- 打开一个单独创作的文件,如果失败将会返回。

          "t" ---- 以文本模式打开(缺省模式)

          "b" ---- 二进制模式

          "U" ---- 通用换行符

          "rb" ---- 读取二进制文件

          "wb" --- 写二进制文件

          "ab" ---- 追加二进制文件

          "+" ---- 加模式用于下面的几种组合:

          "r+"---- 读写/写读模式(光标位置不同), 属于加模式下

          "w+"---- 写读/读写模式(光标位置不同), 属于加模式下

          "a+"---- 追读/读追模式(光标位置不同), 属于加模式下

      (3) buffering = ---- 可取的值有0、1、>1 三种,0表示buffer关闭(只适用于二进制模式),1代表line buffer(只适用于文本模式),>1表示初始化的buffer大小。

      (4) encoding = ---- 编码模式

      (5) errors = ---- 错误忽略模式(取值一般有strict、ignore,replace,当取strict的时候,字符编码出现问题的时候会报错,当取ignore的时候,编码出现问题,程序会忽略而过,绩效执行下面的程序。选择replace的时候,使用某字符进行替代模式,比如使用?来替代出错。)

      (6) newline = ---- 可取的值有None, 、 、"、' ',用于区分换行符,但是这个参数只对文本有效。

      (7) closefd = ---- 默认情况下是True。是与传入的文件参数有关,传入file参数为文件的文件名,取值为false的时候,file只能是文件描述符,什么是文件描述?就是一个非负的整数,在Unix内核的系统中,打开一个文件,变回返回一个文件描述。

      

      “读”:

      函:f.read、f.readline、f.readlines、f.readable

        语:f.read(n)、f.readline(n)、f.readlines(n)、f.readable

          用:f.read(n):默认为读取文本中所有的内容,n为从开始读几个字符。输出为字符串格式。

            f.readline(n):默认为读取文本的第一行内容,n为某一行开始读几个字符。输出为字符串格式。

            f.readlines(n):默认按照行的排列,读取所有的行,n为对应所有字符的位置,如果当前字符位在某一行内,直接返回读取到当前的行。输出为列表类型。

            f.readable():判断句柄文字是否可读,返回真True或者False。

      

      “写”:

      函:f.write、f.writelines、f.writeable

        语:f.write("str")、f.writelines(list)、f.writeable()

          用:f.write("str"):写入括号字符串中的内容。

            f.writelines(list):根据一个列表内容添加到文本中。跟上面的f.realines一样,f.realines是把内容读出到列表中;f.writelines是把列表添加到文本中。

            f.writeable:返回值为False或者True,表示当前句柄内容是否可写。

      “关”:

      函:f.close

        语:f.close()

          用:关闭一个文档。

    3.   根据上面的四类函数进行详细的讲解

    3.1   一个最简单的操作并读取文件的过程。

      代码如下:

     1 # 一个简单的打开和操作 #
     2 # 第一种打开方式:"r":只读模式
     3 data = open("咏梅", "r", encoding="utf-8").read()
     4 print(data)
     5 print(type(data), "
    ")
     6 # 输出结果:
     7 # 风雨送春归,
     8 # 飞雪迎春到。
     9 # 已是悬崖百丈冰,
    10 # 犹有花枝俏。
    11 #
    12 # 俏也不争春,
    13 # 只把春来报。
    14 # 待到山花烂漫时,
    15 # 她在丛中笑。
    16 # <class 'str'>
    17 
    18 # 第二种打开方式:采用函数句柄的方式打开文件。"r":只读模式
    19 f = open("咏梅", "r", encoding="utf-8")
    20 data = f.read()
    21 print(data)
    22 print(type(data), "
    ")
    23 # 输出结果:
    24 # 风雨送春归,
    25 # 飞雪迎春到。
    26 # 已是悬崖百丈冰,
    27 # 犹有花枝俏。
    28 #
    29 # 俏也不争春,
    30 # 只把春来报。
    31 # 待到山花烂漫时,
    32 # 她在丛中笑。
    33 # <class 'str'>

      分析知识点:

      (1) 第一种方式为用只读方式简单的打开了一个文件,采用面向对象类的访问方式.read()的方式打开文件。

      (2) 第二种方式,用open函数打开文件后,赋值到一个句柄f当中,后面的所有操作都是根据句柄f展开的。我们看到这两种方式效果一样,但是建议采用后者,逻辑更清晰。

      (3) open函数一种最常用的格式为open("文件名", "读取模式", “编码格式”),这个必须记住。

      (4) 在这里我们用到了f.read的函数,根据另外两个read函数进行演示,以第二种方式为例。

      代码如下:

     1 # 例子1:只读取前三个字符(英文1个单词一个字符,中文1个字两个字符)
     2 # 方法一:
     3 f = open("咏梅", "r", encoding="utf-8")
     4 data = f.read(3)
     5 print(data)
     6 print(type(data))
     7 # 输出结果:
     8 # 风雨送
     9 # <class 'str'>
    10 
    11 # 方法二:
    12 f = open("咏梅", "r", encoding="utf-8")
    13 data = f.readline(3)
    14 print(data)
    15 print(type(data))
    16 # 输出结果:
    17 # 风雨送
    18 # <class 'str'>
    19 
    20 # 例子2:用列表形式读取所有的内容
    21 f = open("咏梅", "r", encoding="utf-8")
    22 data = f.readlines()
    23 print(data)
    24 print(type(data))
    25 # 输出结果:
    26 # ['风雨送春归,
    ', '飞雪迎春到。
    ', '已是悬崖百丈冰,
    ', '犹有花枝俏。
    ', '
    ', '俏也不争春,
    ', '只把春来报。
    ', '待到山花烂漫时,
    ', '她在丛中笑。']
    27 # <class 'list'>
    28 
    29 # 例子3:用列表的形式只读取前两行内容
    30 f = open("咏梅", "r", encoding="utf-8")
    31 data = f.readlines()
    32 print(data[0:2])
    33 print(type(data))
    34 # 输出结果:
    35 # ['风雨送春归,
    ', '飞雪迎春到。
    ']
    36 # <class 'list'>
    37 
    38 # 例子4:用列表的形式只读取前两行内容,并把内容转换成字符串形式。
    39 f = open("咏梅", "r", encoding="utf-8")
    40 data = f.readlines()
    41 data1 = data[0]
    42 data2 = data[1]
    43 data3 = data1 + data2
    44 print(str(data3))
    45 print(type(data3))
    46 # 输出结果:
    47 # 风雨送春归,
    48 # 飞雪迎春到。
    49 # 
    50 # <class 'str'>

      分析知识点

      (1) 从f.readlines和f.readline函数中我们可以看到f.readlines这个函数返回的结果是list(列表)类型,然后再通过查找列表的第几个元素,就是对应的第几行。

      (2) python对于选取行数的方式用转移成list的方式进行实习,通过list的下标再找到第几行

    3.2    借用上面的例子,把读取的文件在最后光标位添加内容

      代码如下:

     1 # 例子1:在咏梅这首诗光标最后位置添加一段内容。
     2 f = open("咏梅", "a+", encoding="utf-8")
     3 data = f.write("大将生来胆气寒")
     4 f.seek(0)        # 这个函数下面会讲
     5 data1 = f.read()  # 这个时候文件指针放到最后一个字符,要用seek恢复指针。
     6 print(data1)
     7 f.close()
     8 # 输出结果:
     9 # 风雨送春归,
    10 # 飞雪迎春到。
    11 # 已是悬崖百丈冰,
    12 # 犹有花枝俏。
    13 #
    14 # 俏也不争春,
    15 # 只把春来报。
    16 # 待到山花烂漫时,
    17 # 她在丛中笑。大将生来胆气寒 # 在结尾出添加了一句话。
    18 
    19 # 例子2:在结尾处的下一行添加一段内容。
    20 f = open("咏梅", "a+", encoding="utf-8")
    21 data = f.write("
    大将生来胆气寒")   # 在开始添加一个换行符
    22 f.seek(0)        # 这个函数下面会讲
    23 data1 = f.read()  # 这个时候文件指针放到最后一个字符,要用seek恢复指针。
    24 print(data1)
    25 f.close()
    26 # 输出结果:
    27 # 风雨送春归,
    28 # 飞雪迎春到。
    29 # 已是悬崖百丈冰,
    30 # 犹有花枝俏。
    31 #
    32 # 俏也不争春,
    33 # 只把春来报。
    34 # 待到山花烂漫时,
    35 # 她在丛中笑。
    36 # 大将生来胆气寒  # 添加在这里
    37 
    38 # 例子3:观察打开的文件是否可写,如果可写用f.writelines的方式添加另外一首诗进去。
    39 # 然后判断句柄是否可读,如果可读把文章读出来。
    40 f = open("咏梅", "a+", encoding="utf-8")
    41 if f.writable() == True:   # 判断文章是否可写
    42     list = ["
    锄禾日当午,", "
    汗滴禾下土。", "
    谁知盘中餐,", "
    粒粒皆辛苦。"]
    43     f.writelines(list)
    44 f.seek(0)
    45 if f.readable() == True:  # 判断文章是否可读
    46     data = f.read()
    47     print(data)
    48 f.close()
    49 # 输出结果:
    50 # 风雨送春归,
    51 # 飞雪迎春到。
    52 # 已是悬崖百丈冰,
    53 # 犹有花枝俏。
    54 #
    55 # 俏也不争春,
    56 # 只把春来报。
    57 # 待到山花烂漫时,
    58 # 她在丛中笑。
    59 #
    60 # 锄禾日当午,
    61 # 汗滴禾下土。
    62 # 谁知盘中餐,
    63 # 粒粒皆辛苦。

      分析知识点:

      (1) f.writelines对应上面的f.readlines返回的值都是list列表类型,通过写一个list列表可以多行来进行添加。

      (2) f.seek移动光标位置,如果不移动的话,将读取不了文件。

      (3) f.close()这个千万不要忘记。

    3.3   回过头来我们在把open的其他几个填充参数讲解一下

      buffering:

      buffering选项是一个可选参数,平时很少用到。但是这里进行讲解一下。

      buffering用来表示缓冲区的策略选择。设置为0时,表示不使用缓冲区,直接读写,尽在二进制模式下有效。设置为1时,表示在文本模式下使用行缓冲区方式。设置为大于1时,表示缓冲区的设置大小,如果参数buffering没有给出,会使用默认策略进行选择,方式如下:

      (1) 对于二进制模式时,采用固定块内缓冲区方式,内存块的大小根据系统设置的分配磁盘块来决定,如果获取系统磁盘块的大小失败,就是用内部常量io.DEFAULT_BUFFER_SIZE定义大小。一般的操作系统上,快的大小是4096或者8192自己大小。

      (2) 对于交互式的文本采用isatty()(检测当期设备函数)来判断为True时,采用一行缓冲区的方式。其他文本文件使用跟二进制一样的方式。

      总结:换句话说基本没用。

      errors:

       errors选项是用来知名编码和解码错误时怎么处理。不能再二进制的模式下使用。

      (1) 当指明为  strict  时,编码出错则跑出异常ValueError

      (2) 当指明为  ignore 时,忽略错误。

      (3) 当指明为  replace 时,使用某字符进行替代模式,比如使用?来替换出错。

      我们还是用咏梅那首诗,我们开始采用的编码是utf-8编码,如果我们替换成ASCII码的解码方式,肯定是个错误,如果错误的话,分别对应这三种结果会产生什么效果。

      代码如下:

     1 # errors
     2 # 使用strict 严格方式。
     3 f = open("咏梅", "r", errors="strict", encoding="ASCII")
     4 data = f.read()
     5 print(data)
     6 # 输出结果:
     7 # 产生一个报错,不应是用ASCII码来进行解码
     8 # Traceback (most recent call last):
     9 #   File "C:/Users/Administrator/Desktop/Python-1704/day5/文件操作.py", line 221, in <module>
    10 #     data = f.read()
    11 #   File "F:UsersAdministratorPycharmProjectsuntitledvenvlibencodingsascii.py", line 26, in decode
    12 #     return codecs.ascii_decode(input, self.errors)[0]
    13 # UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)
    14 
    15 # 使用 ignore 忽略方式。
    16 f = open("咏梅", "r", errors="ignore", encoding="ASCII")
    17 data = f.read()
    18 print(data)
    19 # 输出结果:
    20 # 啥都没有显示,这个解码错误被忽略了。
    21 
    22 # 使用 replace 替换方式。
    23 f = open("咏梅", "r", errors="replace", encoding="ASCII")
    24 data = f.read()
    25 print(data)
    26 # 输出结果:
    27 # 一堆问号,错误解码用?来替代
    28 # ������������������
    29 # ������������������
    30 # ������������������������
    31 # ������������������
    32 # 
    33 # ������������������
    34 # ������������������
    35 # ������������������������
    36 # ������������������

      newline:

      newline是用来控制文本模式之下一行的结束字符。可以是None,'  ', , , 等。在当读取模式下,如果新行符为None,那么就作为通用换行符模式工作,一是是说当遇到 ,  或者 都可以作为换行标识,并统一转换为 作为文本输入换行符。当设置为空'  ' 时,也就是通用换行符模式工作,但不作转换为 ,输入什么样,就保持原样全输入。当设置为其他相应字符时,就会判断到相应的字符作为换行符,并保持原样输入到文本。

      当输出模式时,如果新行符为None,那么所有输出文本都是采用 作为换行符。如果设置为'  '空或者 时,不做任何替换动作。如果是其他字符,会出现在字符后面添加 作为换行符。

      这个功能也是不太常用的,而且python3中,只能用f.readlines进行演示演示代码如下:

     1 # 如果默认None状态
     2 f = open("咏梅", "r+", encoding="utf-8", newline=None)
     3 data = f.readlines()
     4 print(data)
     5 # 输出结果:正常显示
     6 # ['风雨送春归,
    ', '飞雪迎春到。
    ', '已是悬崖百丈冰,
    ', '犹有花枝俏。
    ', '
    ', '俏也不争春,
    ', '只把春来报。
    ', '待到山花烂漫时,
    ', '她在丛中笑。
    ']
     7 
     8 # 如果"
    "的状态
     9 f = open("咏梅", "r+", encoding="utf-8", newline="
    ")
    10 data = f.readlines()
    11 print(data)
    12 # 输出结果:用
    替代换行符
    ,而
    提到前面去了。
    13 # ['风雨送春归,
    ', '
    飞雪迎春到。
    ', '
    已是悬崖百丈冰,
    ', '
    犹有花枝俏。
    ', '
    
    ', '
    俏也不争春,
    ', '
    只把春来报。
    ', '
    待到山花烂漫时,
    ', '
    她在丛中笑。
    ', '
    ']
    14 
    15 # 如果"
    "的状态
    16 f = open("咏梅", "r+", encoding="utf-8", newline="
    ")
    17 data = f.readlines()
    18 print(data)
    19 # 输出结果:
    都表示换行
    20 # ['风雨送春归,
    ', '飞雪迎春到。
    ', '已是悬崖百丈冰,
    ', '犹有花枝俏。
    ', '
    ', '俏也不争春,
    ', '只把春来报。
    ', '待到山花烂漫时,
    ', '她在丛中笑。
    ']
    21 
    22 # 如果"
    "的状态
    23 f = open("咏梅", "r+", encoding="utf-8", newline="
    ")
    24 data = f.readlines()
    25 print(data)
    26 # 输出结果:
    都表示换行跟上面一样
    27 # ['风雨送春归,
    ', '飞雪迎春到。
    ', '已是悬崖百丈冰,
    ', '犹有花枝俏。
    ', '
    ', '俏也不争春,
    ', '只把春来报。
    ', '待到山花烂漫时,
    ', '她在丛中笑。
    ']
    28 
    29 # 如果""的状态
    30 f = open("咏梅", "r+", encoding="utf-8", newline="")
    31 data = f.readlines()
    32 print(data)
    33 # 输出结果:与上面一个一样。
    34 # ['风雨送春归,
    ', '飞雪迎春到。
    ', '已是悬崖百丈冰,
    ', '犹有花枝俏。
    ', '
    ', '俏也不争春,
    ', '只把春来报。
    ', '待到山花烂漫时,
    ', '她在丛中笑。
    ']

      

      closefd:

      是否关闭,用来给当一个文件句柄传进来时,而当退出文件使用时,而不对文件句柄进行关闭。如果传递一个文件名进来,这个参数无效,必定为True方式。

      如果为True时:传入的file参数为文件的文件名

      如果为False时:传入的file参数只能是文件描述符。

      如果Ps:文件描述,就是一个非负整数,在Unix内核的系统中,打开一个文件,变回返回一个文件描述。

    4.    剩下一点儿就是对于mode的模式几种进行一下说明

    4.1   基本模式:

      "r"----只读模式,代码如下:

     1 # 只读模式
     2 f = open("咏梅", "r", encoding="utf-8")
     3 data = f.read()
     4 print(data)
     5 f.close()
     6 # 输出结果:
     7 # 风雨送春归,
     8 # 飞雪迎春到。
     9 # 已是悬崖百丈冰,
    10 # 犹有花枝俏。
    11 #
    12 # 俏也不争春,
    13 # 只把春来报。
    14 # 待到山花烂漫时,
    15 # 她在丛中笑。

      分析知识点:没啥可说的,也就是打开文件只能读

      "w"----只写模式

     1 # 只写模式
     2 f = open("二进制文件.txt", "w", encoding="utf-8")
     3 data = f.read()
     4 print(data)
     5 f.close()
     6 # 输出结果:
     7 # Traceback (most recent call last):
     8 #   File "C:/Users/Administrator/Desktop/Python-1704/day5/文件操作.py", line 308, in <module>
     9 #     data = f.read()
    10 # io.UnsupportedOperation: not readable

      分析知识点

      (1) 如果原文件不存在,文件名作为新建文件名且创建一个新的文件。

      (2) 如果源文件存在,会把原文件的内容全部覆盖掉,作为一个空文件以供添加内容。

      (3) 由于是只写模式,所以下面输出结果会报错。

      "a"----追加模式

     1 # 追加模式
     2 f = open("咏梅", "a", encoding="utf-8")
     3 data = f.write("作者:毛主席")
     4 print(data)
     5 f.close()
     6 # 输出模式:
     7 # 6
     8 # 文件中显示:
     9 # 风雨送春归,
    10 # 飞雪迎春到。
    11 # 已是悬崖百丈冰,
    12 # 犹有花枝俏。
    13 # 
    14 # 俏也不争春,
    15 # 只把春来报。
    16 # 待到山花烂漫时,
    17 # 她在丛中笑。("a"模式打开后,指针位与这个位置)作者:毛主席   

      分析知识点:注意一点"a"模式,指针开始会停留在最后一个字符的后面,也就是说,不添加换行等命令。是在最后一个位置进行添加。

      "U" ---- 通用换行符模式打开,---也就是rU简写是r等。

      "t" ---- 以文本模式打开(缺省模式)----也就是rt简写是r, wt简写是w,这个字符可以省略

      "b" ---- 二进制模式如下:

      "rb" ---- 读取二进制文件:

      "wb" --- 写二进制文件:

      "ab" ---- 追加二进制文件:

     1 # rb模式
     2 f = open("咏梅", "rb")
     3 # f.read()
     4 data = f.read()
     5 print(data)
     6 #print(f)    # 直接打印句柄,会显示描述文件<_io.BufferedReader name='咏梅'>
     7 # print(f.read())  # 这样还直接打印不了,显示为:b''
     8 f.close()
     9 # 输出结果:
    10 # b'xe9xa3x8exe9x9bxa8xe9x80x81xe6x98xa5xe5xbdx92xefxbcx8c
    xe9xa3x9exe9x9bxaaxe8xbfx8exe6x98xa5xe5x88xb0xe3x80x82
    xe5xb7xb2xe6x98xafxe6x82xacxe5xb4x96xe7x99xbexe4xb8x88xe5x86xb0xefxbcx8c
    xe7x8axb9xe6x9cx89xe8x8axb1xe6x9ex9dxe4xbfx8fxe3x80x82
    
    xe4xbfx8fxe4xb9x9fxe4xb8x8dxe4xbax89xe6x98xa5xefxbcx8c
    xe5x8fxaaxe6x8ax8axe6x98xa5xe6x9dxa5xe6x8axa5xe3x80x82
    xe5xbex85xe5x88xb0xe5xb1xb1xe8x8axb1xe7x83x82xe6xbcxabxe6x97xb6xefxbcx8c
    xe5xa5xb9xe5x9cxa8xe4xb8x9bxe4xb8xadxe7xacx91xe3x80x82'
    11 # 一连串的二进制地址位。
    12 
    13 # wb模式
    14 f = open("二进制文件", "wb")
    15 f.write(b'xe9xa3x8exe9x9bxa8')
    16 f.close()
    17 # 文本中的输出结果:
    18 # 风雨         这两个汉字
    19 
    20 # ab模板
    21 f = open("二进制文件", "ab")
    22 f.write(b"xe9x80x81xe6x98xa5")
    23 f.close()
    24 # 文本中的输出结果:
    25 # 风雨送春      在风雨的后面又追加两个汉字

      分析知识点

      (1) 从这三个例子可以看出,二进制的输入要用二进制地址格式进行输入,像b"地址"  或者 b'地址' 这样才能去写,写到文本中后,会自动变为字符。

      (2) 二进制读取读取出来的也是像b"地址"  或者 b'地址'这样的二进制地址位。

      (3) 如果在某一个模式下,直接print(f)句柄,会得到os.BufferedReader缓冲区对于文件的简要描述

      (4) 如果直接打印print(f.write())这样的句柄模式,会得到输入了多少个字符。如果打印print(f.read())会全部内容。

      "+" ---- 加模式如下

      "r+"---- 读写/写读模式,先读后写

     1 # r+模式 两种变化
     2 # 第一种:先写后读,指针从0行0位开始进行写,之前写的不动,会根据添加的字符进行不断的覆盖。
     3 f = open("二进制文件", "r+", encoding="utf-8")
     4 f.write("作者:毛主席
    作者:毛主席
    ")
     5 print(f.read())
     6 f.close()
     7 # 文本显示结果:
     8 # 作者:毛主席   # 把前两行覆盖了
     9 # 作者:毛主席
    10 # 已是悬崖百丈冰,
    11 # 犹有花枝俏。
    12 #
    13 # 俏也不争春,
    14 # 只把春来报。
    15 # 待到山花烂漫时,
    16 # 她在丛中笑。
    17 
    18 # 第二种:先读后写,指针从0行0位读到最后一个字符的后, 这个时候写的话,变成追加模式了。
    19 f = open("二进制文件", "r+", encoding="utf-8")
    20 print(f.read())
    21 f.write("作者:毛主席")
    22 f.close()
    23 # 文本显示结果:
    24 # 风雨送春归,
    25 # 飞雪迎春到。
    26 # 已是悬崖百丈冰,
    27 # 犹有花枝俏。
    28 # 
    29 # 俏也不争春,
    30 # 只把春来报。
    31 # 待到山花烂漫时,
    32 # 她在丛中笑。作者:毛主席   # 此时指针读完,放到最后,进行追加了。

      分析知识点

      (1) r+模式是r + w 模式的组合。

      (2) r+模式注意指针的变化

      "w+"---- 写读/读写模式

    1 # w+ 模式
    2 f = open("二进制文件", "w+", encoding="utf-8")
    3 f.write("作者:毛主席")
    4 f.close()
    5 # 文本中显示结果:
    6 # 作者:毛主席

      分析知识点

      (1) w+模式是w + r 模式的组合。

      (2) w+模式注意指针的变化

      "a+"---- 追读/读追模式

    1 # a+ 模式
    2 f = open("二进制文件", "a+", encoding="utf-8")
    3 str = ["
    风雨送春归,", "
    飞雪迎春到"]
    4 f.writelines(str)
    5 f.close()
    6 # 文本中显示结果:
    7 # 作者:主席
    8 # 风雨送春归,
    9 # 飞雪迎春到

      分析知识点

      (1) a+模式是a + r 模式的组合。

      (2) a+模式注意指针的变化

    第三部分 其他文件的操作方法

     1.   遍历打印方式

      之前我们知道用f.readlines()是输出了一个列表的形式,我们前面的代码访问具体的内容是用下标的方式,其实我们也可以用for遍历的方式也是一样的。

      用简单for循环的方式进行遍历,代码如下:

     1 # 遍历的方式打印所有的行
     2 f = open("咏梅", "rt", encoding="utf-8")
     3 for i in f.readlines():
     4    print(i.strip())   # 如果不加strip,会多换一行,一般要加上一个strip()保持和原先文章一致
     5 # 输出结果:
     6 # 风雨送春归,
     7 # 飞雪迎春到。
     8 # 已是悬崖百丈冰,
     9 # 犹有花枝俏。
    10 # 
    11 # 俏也不争春,
    12 # 只把春来报。
    13 # 待到山花烂漫时,
    14 # 她在丛中笑。

      用列表的方式进行遍历,代码如下:

    1 # 用列表的方式 进行遍历
    2 f = open("咏梅", "rt", encoding="utf-8")
    3 f = f.readlines()
    4 num = 0
    5 while num < len(f):
    6     print(f[num].strip())
    7     num += 1

      用枚举的方式进行遍历,代码如下

     1 # 用枚举的方式进行遍历
     2 f = open("咏梅", "rt", encoding="utf-8")
     3 for i, v in enumerate(f.readlines(), 1): # 这是for 内部将f对象做成一个迭代器,用一行取一行
     4     print(i, v.strip())
     5 print(type(i))
     6 print(i)  # 迭代到最后一行
     7 # 显示结果:
     8 # 1 风雨送春归,
     9 # 2 作者:毛主席
    10 # 3 飞雪迎春到。
    11 # 4 已是悬崖百丈冰,
    12 # 5 犹有花枝俏。
    13 # 6
    14 # 7 俏也不争春,
    15 # 8 只把春来报。
    16 # 9 待到山花烂漫时,
    17 # 10 她在丛中笑。
    18 # <class 'int'>
    19 # 10

      分析知识点:在这里遍历打印的时候i.strip()是常用的一种技巧,目的是为了在strip前后无效的 这些位置去除掉。

    2.   我们把咏梅的诗歌,第二行显示“作者:毛主席”,然后把第二行的毛主席显示一个字符串,用两种方式:

      代码如下:

     1 # 方法一:传统方法
     2 f = open("咏梅", "rt", encoding="utf-8")
     3 num = 0
     4 for i in f.readlines():
     5     num += 1
     6     if num == 2:   # 如果读到第二行
     7         print(i.strip(), end="  你回答的很正确")
     8     else:
     9         print(i.strip())
    10 f.close()
    11 # 显示结果:
    12 # 风雨送春归,
    13 # 作者:毛主席  你回答的很正确飞雪迎春到。
    14 # 已是悬崖百丈冰,
    15 # 犹有花枝俏。
    16 #
    17 # 俏也不争春,
    18 # 只把春来报。
    19 # 待到山花烂漫时,
    20 # 她在丛中笑。
    21 
    22 # 方法2:用join链接字符串的方式
    23 f = open("咏梅", "rt", encoding="utf-8")
    24 number = 0
    25 for i in f.readlines():
    26     number += 1
    27     if number == 2:
    28         i = "".join([i.strip(), "  你回答的很正确"])  # 取代万恶的加号,字符串拼接
    29     print(i.strip())
    30 # 显示结果:
    31 # 风雨送春归,
    32 # 作者:毛主席  你回答的很正确
    33 # 飞雪迎春到。
    34 # 已是悬崖百丈冰,
    35 # 犹有花枝俏。
    36 #
    37 # 俏也不争春,
    38 # 只把春来报。
    39 # 待到山花烂漫时,
    40 # 她在丛中笑。

    3.   文件操作的其他几个内建函数

      函:f.tell

        语:f.tell(n)

          用:检测光标(指针)当前的位置。注意:tell中文对应的光标和英文对应的光标占用位不一样(中文一般2个字符,英文一般一个字符)

      函:f.seek

        语:f.seek(n)

          用:调整或移动光标(指针)当前的位置。注意seek和tell是意义对应的关系。通过seek调整光标的位置。起始位为:0

       举例如下:

     1 # tell(n)
     2 # 作用:检测光标(指针)当前的位置
     3 # 注意:tell中文对应的光标和英文对应的光标显示位置不一样
     4 f = open("咏梅", "rt", encoding="utf-8")
     5 print(f.tell())  # 刚开始光标在0的位置
     6 print(f.read(4))
     7 print(f.tell())  # read了5个位置光标移动到12,中文占三个字符,英文是1个字符
     8 # 显示结果:
     9 # 0
    10 # 风雨送春   中文字符占2个位。
    11 # 12        现在光标到12的位置。
    12 
    13 # seek(n)
    14 # 作用:调整光标(指针)当前的位置
    15 # 注意 seek和tell是一一对应的关系。通过seek调整光标的位置。
    16 f = open("咏梅", "rt", encoding="utf-8")
    17 print(f.read(1))
    18 print(f.read(2))
    19 print(f.read(3))
    20 f.seek(0) # 重新调整光标位置到第一个,重新读
    21 print(f.read(1))
    22 # 显示结果:
    23 # 风  开始读取一个中文字
    24 # 雨送  然后再继续读两个中文字
    25 # 春归,然后再继续读3个中文字(含1个字符)
    26 # 风   # 回复到第一的位置

      函:flush

        语:f.flush()

          用:这个函数的作用是把缓存里面的数据转存到硬盘里面(一般用于进度条制作)。方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要被动的等待输出缓冲区写入。一般情况下,文件关闭后会自动刷新缓冲区,但是有时候你需要在关闭前刷新他,这时就可以用f.flush的方法。注意:可以理解为:平时都是执行完一段代码滞后才能看见。用这个方法,可以边看边执行。

      举例代码如下:

     1 f = open("helloworld", "w")
     2 f.write("Thomas is 35")
     3 print(f.name)
     4 f.write('hello 
    ')  # 执行一条
     5 f.flush() # 刷新到文件中一条
     6 f.write('world
    ') # 执行一条
     7 f.close() # 刷新到文件中一条
     8 # 文件中显示的结果:
     9 # Thomas is 35hello
    10 # world
    11 
    12 import sys,time
    13 f = open("hello001", "w", encoding="utf-8")
    14 f.write("hello")
    15 for i in range(10):
    16     sys.stdout.write("*")
    17     sys.stdout.flush()
    18     time.sleep(0.5) # 按照0.5秒的速度刷新
    19 # 显示内容:
    20 # **********
    21 # Process finished with exit code 0

      分析知识点:这里运用了库文件sys和time,这个后面会讲到。

      函:truncate

        语:truncate(n)

          用:截断功能、默认是光标从第一个位置开始全部删除。如果设定参数设定,可以从设定的位置后面的所有内容都给截断。注意:这里打开文件的内容不能用w模式,因为w模式本身先进行一遍truncate过程。所以再用truncate会出错的。括号当中的n为从第几个字符进行截断,这里的中文字符再truncate函数中为3个字符为一个汉字。默认是从0开始,等同于w模式。

      举例如下:

     1 # truncate() 函数
     2 # 作用:截断功能、默认是光标是从第一个位置开始全部删除。如果设定参数设定,可以从设定的位置
     3 #      后面的所有内容都给接触
     4 # 注意:这里打开文件模式不能用w模式。w本身要先进行一遍truncate过程。所以再用truncate会出错。
     5 # 原文章:
     6 # 风雨送春归,
     7 # 飞雪迎春到。
     8 # 已是悬崖百丈冰,
     9 # 犹有花枝俏。
    10 #
    11 # 俏也不争春,
    12 # 只把春来报。
    13 # 待到山花烂漫时,
    14 # 她在丛中笑。
    15 f = open("咏梅", "a", encoding="utf-8")
    16 f.truncate(3)
    17 f.close()
    18 # 显示结果:
    19 #

    4.   文件的修改问题

      针对上面的内容,如果对一个文件进行修改是比较麻烦的,其实可以通过重写一份的方式进行文件的修改,类似于深拷贝的形式。很像一遍拿着课本,抄一遍,然后把要修改的地方记录下来。

      举例代码:

     1 # 文件的修改问题 #
     2 # 把一整行进行替换
     3 f_read = open("咏梅", "r", encoding="utf-8")
     4 f_write = open("咏梅2", "w", encoding="utf-8")
     5 
     6 number = 0
     7 for line in f_read:
     8     number += 1
     9     if number == 5:
    10         line = "hello 毛主席
    "   # 这样把第五行进行替换了
    11     f_write.write(line)
    12 f_write.close()
    13 f_read.close()
    14 # 显示结果:
    15 # 风雨送春归,
    16 # 飞雪迎春到。
    17 # 已是悬崖百丈冰,
    18 # 犹有花枝俏。
    19 # hello 毛主席
    20 # 俏也不争春,
    21 # 只把春来报。
    22 # 待到山花烂漫时,
    23 # 她在丛中笑。
    24 
    25 # 在一段后面添加字符串
    26 f_read = open("咏梅", "r", encoding="utf-8")
    27 f_write = open("咏梅2", "w", encoding="utf-8")
    28 
    29 number = 0
    30 for line in f_read:
    31     number += 1
    32     if number == 5:
    33         line = "".join([line.strip(), "hello 毛主席
    "])
    34         # line = "hello 毛主席
    "   # 这样把第五行进行替换了
    35     f_write.write(line)
    36 f_write.close()
    37 f_read.close()
    38 # 显示结果:
    39 # 风雨送春归,
    40 # 飞雪迎春到。
    41 # 已是悬崖百丈冰,
    42 # 犹有花枝俏。
    43 # hello 毛主席
    44 # 俏也不争春,
    45 # 只把春来报。
    46 # 待到山花烂漫时,
    47 # 她在丛中笑。

    5.   一个重要的知识点 with... as ...在文件操作中的应用

       为了避免打开文件后忘记关闭,可以通过with语句管理上下文。with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源。比如文件使用后自动关闭、线程中的会自动获取和释放等。而且用with... as...的方式还可以同时打开多个文件

      语法:with  context_expression  [as target(s)]:

            with_body

     1 # with
     2 # 作用:为了避免打开文件后忘记关闭,可以通过with语句管理上下文。
     3 # with 语句适用于对资源进行访问的场合,确保不管使用过程中是否
     4 # 发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、
     5 # 线程中锁的自动获取和释放等。
     6 # 语法:
     7 # with context_expression [as target(s)]:
     8 #     with-body
     9 with open("咏梅", "r", encoding="utf-8") as f:
    10      f.readline()
    11      f.read()
    12 print("成功打开")
    13 # 显示结果:成功打开
    14 
    15 
    16 # 同样with语句在python3当中可以打开多个文件
    17 with open("咏梅", "r", encoding="utf-8") as f, open("咏梅2", "w", encoding=
    18      "utf-8") as f_write:
    19     for i in f.readlines():
    20         print(i.strip())
    21 # 显示结果:
    22 # 风雨送春归,
    23 # 飞雪迎春到。
    24 # 已是悬崖百丈冰,
    25 # 犹有花枝俏。
    26 # 
    27 # 俏也不争春,
    28 # 只把春来报。
    29 # 待到山花烂漫时,
    30 # 她在丛中笑。

    6.   其他补充

      记得在标准化输入输出当中,print函数中有个参数为file = file.name。其实我们也可以通过print的函数来替代f.write函数把想要写的内容,打印到文件中。但是要注意的是,必须先要建立文件。

      举例如下:

    1 with open("李白", "w", encoding="utf-8") as f:
    2     print("长风破浪会有时,直挂云帆济沧海", file=f)
    3 # 文件中的显示结果:
    4 # 长风破浪会有时,直挂云帆济沧海  # 是不是也是一样呢?

    总结

      关于文件的操作,这里是基本操作,还有一些csv,png(图片),mp4(图像),wmv(声音)等高级文件操作方式,后面会有相关专题来进行讲解。

     

  • 相关阅读:
    iOS NSNotificationCenter 最基本使用
    iOS SDK 从配置文件里读SDK。转化成class 可同时加载多个SDK
    NSString json 车NSDictionary
    在C#中使用.NET SDK创建控制
    推荐几款制作网页滚动动画的 JavaScript 库
    CSS选择器、优先级与匹配原理
    为ASP.NET控件加入快捷菜单
    如何使用ASP.NET开发基于推技术的聊天室?
    ASP.NET Web API queryString访问的一点总结
    ASP.net 控件实现数据级联
  • 原文地址:https://www.cnblogs.com/noah0532/p/8437997.html
Copyright © 2020-2023  润新知