zoukankan      html  css  js  c++  java
  • Python基础_文件读写

    一、I/O操作概述

    I/O概述:

        I/O在计算机中时指Input/Output,也就是Stream的输入与输出。我们通常说的输入与输出其实在操作系统中都是相对于内存而言的,InputStream(输入流)是指数据从外部(网络、键盘、I/O设备)流进内存,OutputStream正好与之相反,数据从内存流出到外部。程序运行时,数据都是在哎内存中驻留,由CPU这个超级快的计算核心来执行,涉及到数据交换的地方就需要IO接口。

    IO接口的提供以及高级编程语言中的IO操作的实现:

        操作系统十个通用的软件程序,其通用目的如下:
        硬件驱动、进程管理、内存管理、网络管理、安全管理、I/O管理
        操作系统屏蔽了底层硬件,向上提供通用接口。因此,操作I/O的能力是由操作系统提供的,每一种编程语言都会把操作系统提供的低级C接口封装起来供开发者使用,Python也不例外。

    二、文件读写实现原理和操作步骤

    1.文件读写实现原理:

        由于操作I/O的能力是由操作系统提供的,且操作系统不允许普通程序直接操作磁盘,所以读写文件时需要操作系统打开一个对象,这个对象通常被称之为文件描述符--file descriptor,简称fd,这个就是我们在程序中要操作的文件对象。
        通常高级编程语言会提供一个内置的函数,通过接收‘文件路径’、‘文件打开模式’等参数来打开一个文件对象,并返回该文件对象的文件描述符。因此通过这个函数我们就可以获取到要操作的文件对象,在Python中这个函数叫open(),在PHP中叫fopen()

    2.文件读写操作步骤:

    不同编程语言读写文件的操作步骤大体都一样,都分为以下几步:
        1)打开文件,获取文件描述符;
        2)操作文件描述符--读/写;
        3)关闭文件。

    3.需要注意的是:

    文件读写操作完成后,应该及时关闭。一方面,文件对象会占用操作系统的资源,另一方面,操作系统对同一时间能够打开的文件描述符的数量是有限的,在linux操作系统上可以通过ulimit -n来查看这个现实数量。如果不能及时关闭文件,还可能造成数据丢失,因为将数据写入文件时,操作系统不会立即把数据写入磁盘,而是先把数据放到内存缓存区异步写入磁盘。当调用close方法时,操作系统才会保证把没有写入磁盘的数据全部写入到磁盘,否则可能会丢失数据。

    三、Python3中文件打开模式

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

    打开文件的参数通常有:文件路径名称、mode参数(即打开模式)、编码模式...
    这里需要搞清楚的就是mode参数,也就是我们使用什么模式打开一个文件:
    Python3源码中时这样解释的:
    Python3源码文件其实对文件的打开模式进行了详细的英文阐述,这里非常建议大家自己打开builtins.py文件自行查看,我相信研究看懂的远远比看别人写的文章描述的更加深刻。
    这里只是粘贴一部分打开模式的简单描述部分:
    ========= ===============================================================
    Character Meaning
    --------- ---------------------------------------------------------------
    'r'       open for reading (default)
    'w'       open for writing, truncating the file first
    'x'       create a new file and open it for writing
    'a'       open for writing, appending to the end of the file if it exists
    'b'       binary mode
    't'       text mode (default)
    '+'       open a disk file for updating (reading and writing)
    'U'       universal newline mode (deprecated)
    ========= ===============================================================
    接下来我们队几个常见且重要的模式进行中文解析:
    打开模式
    描述
    r
    以只读模式打开文件,并将文件指针指向文件开头;如果文件不存在则报错。
    w
    以只写模式打开文件,并将文件指针指向文件开头;如果文件存在则将其情况并写入,如果文件不存在则创建
    a
    以只追加写模式打开文件,并将文件指针指向文件末尾;如果文件不存在则创建。
    r+
    在r的基础上增加可写功能
    w+
    在w的基础上增加可读功能
    a+
    在a的模式上增加可读功能
    b
    读写二进制文件(默认是t,表示文本模式),需要与上面几种模式搭配使用,如:ab,wb,ab
    x
    创建一个新文件再打开它写入;如果文件已存在则报错。
    思考1:r+、w+和a+都可以对文件进行读写,他们有何区别?
        会覆盖当前文件指针所在位置的字符,如原来文件内容是“Hello World”,以r+模式打开文件写入“hi”则文件内容变成“hillo World”
    打开模式
    详细描述
    r+
    会覆盖当前文件指针所在位置的字符,如原来文件内容是“Hello World”,以r+模式打开文件写入“hi”则文件内容变成“hillo World”
    w+
    w+在打开文件时就会先将文件内清空,再进行写入。
    a+
    该模式只能写在文件末尾,也就是在文件末尾进行追加写入。
    思考2:为何要定义这些模式?为什么不能像word文档意义打开它之后既可读又可写还可以修改呢?
        问题答案参考网上:
        跟安全有关,有这种观点的大部分是做运维的朋友,他们认为这就像linux上的rwx(读、写、执行)权限。
        跟操作系统内核管理I/O的机制有关,有这种观点的大部分是做C开发的,特别是与内核相关的开发人员。为了提高读写速度,要写入磁盘的数据会先放进内存缓冲区,之后再回写。由于可能会同时打开很多文件,当要回写数据时,需要遍历以打开的文件判断是否需要回写。他们认为如果打开文件时指定了读写模式,那么需要回写时,只要去查找以“可写模式”打开的文件就可以了。

    四、Python文件操作实例

    读取文件open_test.py,该文件的字符编码为utf-8
    Python3实现:
    输出结果:
    这里需要注意一点就是,我们在读写文件时候,特别是在读的时候大部分情况,如果文件路径不正确或者文件不存在,也就是找不到文件,又或者是在进行文件操作时候出现I/O错误,就会报错。此时如果要保证代码的健壮性最好加上try...finally来实现错误捕捉以及及时关闭文件对象(优化代码如下):
    输出结果:
    上面关闭文件的代码有时候很容易忘记,所以我们接下来使用Python with方法来完成自动关闭文件:
    输出结果:
    可以看到在with语句中文件时没有关闭的,只有出了with语句后文件会自动关闭
    关于Python with上下文管理的用法可以查看文章了解: https://www.cnblogs.com/suguangti/p/11123515.html

    五、Python文件读取相关方法

    对文件的读取操作需要将文件中的数据加载到内存中,而在上面所用到的read()方法会一次性的把文件中所有的内容全部加载到内存中。这显然是不合理的,如果我们读取的是一个大文件,有几个G的文件时,必然会耗光机器的内存或者直接报错,所以肯定有一些其他的读取方法来解决:
     
    方法
    描述
    read()
    一次性读取文件所有内容
    read(size)
    每次最多读取指定长度内容,在Python2中size指定是字节长度,而在Python3中size指定为字符长度
    readlines()
    一次性读取文件所有内容,按行返回一个list
    readline()
    每次只读取一行内容
    此外还有两个关于文件指针位置的方法:
    方法
    描述
    seek()
    将文件指针移动到指定字节位置
    tell()
     

    实例一:

    输出结果:

    实例二:

    输出结果:
    readlines()方法跟read()方法一样,都会消耗大量内存空间。

    实例三:

    或者:
    输出结果:

    解决打印每一行换行符问题:

    方法一:
    方法二:
    输出结果:

    六、文件操作其他方法

    方法
    描述
    flush()
    刷新缓冲区数据,将缓冲区中的数据立刻写入文件
    next()
    返回文件下一行,这个方法也是file对象实例可以被当作迭代器使用的原因
    truncate(size)
    截取文件中指定字节数的内容,并覆盖保存到文件中,如果不指定size参数,则文件将被清空;Python2中无返回值,Python3返回新文件的内容字节数
    write(str)
    将字符写入文件,没有返回值
    writelines(sequence)
    向文件写入一个字符串货一个字符串列表,如果字符串列表中元素需要换行要自己加入换行符
    fileno()
    返回一个整型的文件描述符,可以用于一些底层I/O操作上(如os模块的read方法)
    issatty()
    判断文件是否被连接到一个虚拟终端,是则返回True,否则返回False
     
  • 相关阅读:
    交通综合改造工程EPC总承包项目
    二三维一体化地理信息平台
    NetCore3.1升级到Net5.0序列化方法过时问题
    windows server2012部署.net core IIS,页面报503,应用程序池自动停止。。。
    NetCore使用NPOI导入Word中的图片信息
    NetCore 使用 iTextSharp 读取 PDF 中的文字信息
    NetCore 在 Docker中文件路径找不到的问题
    Vue中数组list直接push的是对象而不是追加数据的问题
    netcore3.1增加阿里云OSS云存储服务
    Centos中Docker容器中程序访问宿主机Redis和Mysql
  • 原文地址:https://www.cnblogs.com/suguangti/p/12732966.html
Copyright © 2011-2022 走看看