• python入门(八):文件操作


    1、数据的保存:

      1) 内存:常用的变量都是在内存里面的

      缺点:关机或进程死掉数据丢失

      解决方法:将数据保存至文件中

      2 )文件:文本内容、二进制的文件内容
      3 )数据库:保存 
     

    2、读文件:
      1 )要读取的文件,路径一定要存在。 如果不存在,会报异常

      2 )打开存在的文件:open函数

    参数1:文件的路径,可以是相对的,也可以是绝对的

    参数2:打开文件的模式。rwa,如果未写,默认是r模式,也就是读模式

    参数3:编码,encoding=”utf-8” ,如果未写,那么就是gbk编码

      3 )操作文件的内容,

        r:读文件

        w:把原有内容清空再写入内容

        a:原有内容不变,会把写入的内容追加到文件的最后一行

        r+:保留原有内容后,启动读模式和写模式。覆盖写。

        w+:清空原有内容后,启动读模式和写模式。

        a+:保留原有内容后,进行读写的模式,且写入内容永远在文件的最后一行。

      4 )文件关闭掉。

          小知识:

      open函数参数3指的是要打开文件的保存的编码格式

      例如:D:\a.txt文件是以utf-8方式保存的,但是open函数时,使用gbk的话,当时不会报错,但是当再次读取a.txt文件时,会提示报错

      >>> fp=open("e:\a.txt","r",encoding="gbk")      #文件编码方式写错

      >>> fp.read()

      Traceback (most recent call last):

        File "<stdin>", line 1, in <module>

      UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence

      UnicodeDecodeError: 'gbk' codec无法解码字节0xbf在位置2:非法多字节序列

    3、新建文件的时候,默认保存是ANSI编码(gbk),然后也可以选择utf-8。 

    4、判断文件在不在
    >>> import os.path

    >>> os.path.exists("d://a.txt")
    True
    >>> os.path.exists("a.txt")
    True

    5、判断当前工作环境在哪个路径

    >>> os.getcwd()
    'C:\Users\binbin'

    >>> if os.path.exists("a.txt"):
    ... print ("存在")
    ...

    6、 绝对路径与相对路径:

    1)       绝对路径:从盘符开始完整的路径, 例如:c: est est1a.txt 

    2)       相对路径:在当前的目录下,以它为根目录,使用相对路径进行查找

        例如:在e: est est1下执行某个py程序,程序里面使用了相对路径a.txt,那么对应的绝对路径:e: est est1a.txt 

    路径需要使用\,想使用,需要前面加r

      >>> os.path.exists(r"e:a.txt")
      False

    7、句柄:指向磁盘文件在内存或磁盘上的位置指针。

    8、打开文件

    要有个变量存文件句柄,句柄:指向磁盘文件在内存或者磁盘上的位置指针,fp就是句柄

     fp=open("d:\a.txt","w+",encoding="utf-8")  #新建一个句柄变量,用来当做文件

    第一个参数是文件路径

    第二个参数是读取方式

    第三个参数encoding:用文件存储的编码打开文件

    >>> fp  #查看fp文件信息
    <_io.TextIOWrapper name='d:\a.txt' mode='r' encoding='utf-8'>
    >>> dir(fp)  #文件具备的属性值
    ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines']

    9、 读取文件所有内容

    >>> fp.read()
    'ufeffui 功能 性能 安全 易用性 兼容性 '

    #ufeff  utf-8格式保存时,会有BOM文件头,便是ufeff

    去掉文件头解决方法:

    需要用notepad++等选择无BOM格式编码

    安装notepad++(sublime text3)->编码->utf-8BOM格式编码(UTF-8编码)保存

     

     

     

      读完以后,需要把游标重新指到开头,才能再读内容

      >>> fp.seek(0,0)
      0

     fp.read()输出无头文件

    10、游标

    文件中有一个游标的概念,记录当前读取文件的位置。查看当前游标位置的语句是:

    >>> fp.tell()
    32

    位置根据字节数来的,一个汉字在utf-8中占3个字节

    fp.tell()

    >>> fp.tell()

    43                            #当前游标位置在第43 个字节处

    >>> fp.read(1)                 #只读第一个字节内容

    'u'

    >>> fp.tell()                   #当前游标在1

    1

    >>> fp.readline()   #输出游标在第一个字节1处的一整行

    'i 功能 性能 安全 易用性 兼容性'

    >>> content = fp.read()  #将读到的文件内容赋值到content变量中
    >>> type(content)  #文件读到的内容是字符串
    <class 'str'>
    >>> print(content)  #打印文件内容

    ui 功能 性能 安全 易用性 兼容性

    11、按行读文件

    >>> fp=open('D:\study\a.txt','r',encoding='utf-8')
    >>> fp.readline()  #读第一行数据

    'ufeff功能 '

    >>> fp.readline()  #读取当前游标的下一行数据

    '性能 '

    >>> fp.readline()  #读取当前游标的下一行数据

    '安全 '
    >>> fp.readline()  #读取当前游标的下一行数据

    '易用性 兼容性 '
    >>> fp.readline()  #读取当前游标的下一行数据

    'ui'
    >>> fp.readline()  #读到最后没有内容,显示为空
    ''

    12、遍历句柄中的所有行

    >>> fp=open('D:\study\a.txt','r',encoding='utf-8')
    >>> for i in fp:  #遍历读所有文件内容的方式
    ...         print(i,end='')  #如果不加end=“”,会输出空行
    ...

    功能
    性能
    安全
    易用性 兼容性
    ui

    -------------------------------------------------------------------------------

    不加end=“”,空行效果

    功能

    性能

    安全

    易用性 兼容性

    ui

    13、比较fp.read()和fp.readline()

    fp.read():读取文件的全部内容 ,文件太大fp.read()进程会死,操作系统不会死
    fp.readline():读取一行,一行一行读
     
    数据量不大:read()
    优点:把数据读到内存,操作起来很快,速度快
    缺点:占内存 
     
    数据量大:readline()
    优点:省内存
    缺点:速度慢,每读一行,就执行一次I/O

    14、按行读取所有文件

    fp.readlines(),读取全部,每一行做为列表的元素,返回结果是个列表

    >>> fp.readlines()
    ['ufeff功能 ', '性能 ', '安全 ', '易用性 兼容性 ', 'ui']

    >>> lines=fp.readlines()

    >>> lines  #lines的返回结果是个列表

    ['ufeff功能 ', '性能 ', '安全 ', '易用性 兼容性 ', 'ui']

    >>> lines[1]   #使用位置坐标可实现读取指定行

    '性能 '

    >>> lines[3]   #使用位置坐标可实现读取指定行

    '易用性 兼容性 '  

    15、关闭文件

    >>> fp.close()

    1)为什么要close:

      a.文件不关闭,写入的内容太少,实际写的内容并不会立刻写到磁盘,其他打开文件操作可能会受限 
      b.写入场景:一次写不多的内容,比如:100个字。操作系统会把内容存到内存中,不写入文件,什么时候写入呢?要等待写入的内容到一定的量,64k才会写入,如果想立刻写入文件,需要fp.flush()方法#立刻写入文件的方法
              close之后,这个会把所有待写入的内容保存到文件中。
      c.程序中不close会有什么影响:
        1.python程序执行完毕了,会自动close
        2.对于服务器端,不close,可能造成数据不真正写入到文件里
        3对于服务器端,每次打开一个文件都不close,会把文件句柄(node)占用光,操作系统上打开文件是有限制的:
    65535个,达到65535个node被占用的时候,句柄耗尽,操作系统就死掉了。      
     
    结论:读写文件一定要close
     
    2)问:服务器端的程序是一直在执行?还是一会执行一会不执行?

      答:服务器端的程序是一直在执行

      服务器端的服务宗旨:尽管你可能不来,但是我们一定死等

      服务器端的服务进程不会自动close

     
    16、写
      1) “w”方式写入,w清空再写

      >>> fp=open("D:\study\a.txt","w",encoding="utf-8")  #支持类型是写,打开时已将文件清空

      >>> fp.write(123)  #写入数字

      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      TypeError: write() argument must be str, not int  #参数必须是str,而不是int
      >>> fp.write(str(123))  #将数字类型转换成str类型写入
      3

      >>> fp.flush()  

       查看a.txt文件。显示123,因为”w”是清空写
      ***

      一般的文件流操作都包含缓冲机制,write方法并不直接将数据写入文件,而是先写入内存中特定的缓冲区。

      flush方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区。

      正常情况下缓冲区满时,操作系统会自动将缓冲数据写入到文件中。

      至于close方法,原理是内部先调用flush方法来刷新缓冲区,再执行关闭操作,这样即使缓冲区数据未满也能保证数据的完整性。

      如果进程意外退出或正常退出时而未执行文件的close方法,缓冲区中的内容将会丢失。

      ***

      2)“a”方式写入,a追加

      >>> fp=open("D:\study\a.txt","a",encoding="utf-8")  #追加写
      >>> fp.write("hello,sunshine")  #写入内容时,没有回车
      14
      >>> fp.write("hello,sunshine123")  #写入内容时,没有回车
      17
      >>> fp.write("hello,sunshine789 ")  #写入内容时,有输入回车
      18
      >>> fp.write("hello,sunshine0 ")  #写入内容时,有输入回车
      16
      >>> fp.close()

      查看文件a.txt

      hello,sunshinehello,sunshine123hello,sunshine789  #前3次写入的内容均在一行
      hello,sunshine0  #有换行

      a+:保留原有内容后,进行读写的模式,且写入内容永远在文件的最后一行 

      3)r+方式,保留原有内容后,进行读写的模式

      >>> fp=open("D:\study\a.txt","r+",encoding="utf-8")  #r+模式
      >>> fp.readline()                  #r+模式支持读
      'hello,sunshinehello,sunshine123hello,sunshine456hello,sunshine789 '
      >>> fp.write("how's the weather today?")      #r+模式支持写
      24
      >>> fp.close()

      查看a.txt文件 

      hello,sunshinehello,sunshine123hello,sunshine456hello,sunshine789
      hello,sunshine0
      hello,sunshine666000how's the weather today?  #在文件最后写入成功

      >>> fp=open("D:\study\a.txt","r+",encoding='utf-8')
      >>> fp.write("早上好")
      3  
      >>> fp.close() 

      查看a.txt文件

      早上好shinehello,sunshine123hello,sunshine456hello,sunshine789  ##直接覆盖
      hello,sunshine0
      hello,sunshine666000how's the weather today?

      4)w+方式,清空原有内容后,进行读写的模式

      >>> fp=open("D:\study\a.txt","w+",encoding='utf-8')  #w+模式

      >>> fp.read()                                 #w+支持读,但是a.txt文件已经被清空

      ''

      >>> fp.write("检查有没有清空呀?")

      9

      >>> fp.close()

      查看a.txt文件:

      检查有没有清空呀?                          #之前内容已清空

     
    小练习:
    1.统计文件的行数:

    第1种方法:

    >>> fp=open("D:\study\a.txt",'r',encoding='utf-8')
    >>> len(fp.readlines())  #使用len(fp.readlines())直接返回列表长度!!!即文件行数
    5

    该方法的弊端是:当文件行数过大。使用readlines速度和性能便会下降,使用局限性较大。

    第2种方法:

    不使用readlines的解法:   #该方法使用情况较多,推荐

    >>> fp=open('D:\study\a.txt','r',encoding='utf-8')
    >>> count=0

    >>> for line in fp:  #遍历句柄中的所有行
    ...     count+=1
    ...
    >>> print(count)
     

    遍历取每一行

     >>> for line in fp:
    ...     print (line,end="")
    ... 
     
     第3种方法:  #当文件过大时,此方法受限
    >>> fp=open('D:\study\a.txt','r',encoding='utf-8')

    >>> len(fp.read().split(" "))

    第4种方法:
    >>> fp=open('D:\study\a.txt','r',encoding='utf-8')
    >>> count =0
    >>> while fp.readline():  #while循环,遍历行
    ...     count+=1
    ...

    fp.close()

    >>> print(count)
     

    >>> fp.readline()  #读到最后返回的是空字符串
    ''
    >>> bool('')  #空字符串在条件判断时是False
    False

     

    2.文件中插入写,自己实现
     >>> fp = open("e:\a.txt","r+",encoding="utf-8")
    >>> two_word=fp.read(2)
    >>> two_word
    '你好'
    >>> last_two_word=fp.read(2)
    >>> last_two_word
    '阳光'
    >>> fp.seek(0,0)
    0
    >>> fp.write(two_word+"gr"+last_two_word)
    6
    >>> fp.close()
    >>> 
     查看a.txt文件:
  • 相关阅读:
    异步加载技术实现瀑布流效果
    点击向下展开的下拉菜单特效
    几个个实用的PHP代码片段【自己备份】
    cache和buffer区别探讨
    windows 文本文件放到linux下使用
    制作rpm包
    mariadb在线热备份做主从
    检查目录下备份文件的脚本
    different between method and function
    mysql忘记root密码解决
  • 原文地址:https://www.cnblogs.com/suitcases/p/10274355.html
Copyright © 2020-2023  润新知