zoukankan      html  css  js  c++  java
  • Python基础之文件操作

    1. 文件操作基本流程

    计算机系统分为:计算机硬件,操作系统,应用程序三部分。
    我们用Python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序,要操作硬件。
    而应用程序是无法操作硬件的,这就用到了操作系统。
    操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用。
    其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。
    有了文件的概念,我们无需再去思考操作硬盘的细节,只需要关注操作文件的流程: ```Python #1. 打开文件,得到文件句柄并赋值给一个变量 f = open("a.txt", "r", encoding="utf-8") #默认打开模式为只读

    2. 通过句柄对文件进行操作

    data = f.read()

    3. 关闭文件

    f.close()

    <h2>2. 关闭文件的注意事项</h2>
    打开一个文件包含两部分资源:操作系统级打开的文件 + 应用程序的变量。<br>
    在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落的回收。<br>
    回收方法为:
    ```Python
    1. f.close()    #回收操作系统级打开的文件
    2. del f        #回收应用程序级的变量
    

    其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源。

    而python的自动垃圾回收机制决定了我们无需考虑del f
    这就要求我们,在操作完毕文件后,一定要记住f.close()

    但是,还是有的时候可能会忘记关闭文件,因此,我们可以使用另外一种操作方式。

    使用with关键字来管理上下文:

    with open("a.txt", "r", encoding="utf-8) as read_f:
        data = read_f.read()
    with open("a.txt, "w", encoding="utf-8) as write_f:
        write_f.write(data)
    

    3. 文件编码

    f = open(···)是由操作系统打开文件。
    那么如果我们没有为open指定编码,那么打开文件的默认编码很明显就是操作系统说了算。
    操作系统会用自己的默认编码去代开文件,在windows先是gbk, 在linux下是utf-8. ```Python f = open("a.txt", "r", encoding="utf-8) ``` 因此,若要保证不乱吗,文件以什么方式存的, 就要用什么方式去打开。

    4. 文件的打开方式

    打开文件的方式有:r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b。
    默认使用的是r(只读)模式。
    根据打开方式的不同能执行不同的操作,但是也会有相应的差异。

    4.1 只读操作(r, rb)

    ```Python f = open("a.txt", mode="r", encoding="utf-8) content = f.read() print(content) f.close() ``` 需要注意encoding表示编码集,根据文件的实际保存编码进行获取数据。
    我们更常使用的utf-8. rb,读取出来的数据是bytes类型,在rb模式下,不能选择encoding字符集 ```Python f = open("a.txt", mode="rb") content = f.read() print(content) f.close() ``` 执行结果为: ```Python b'xe6xafx85xe5x93xa5, xe5xa4xaaxe7x99xbd, wuse xe5x91xb5xe5x91xb5 xe6x97xa5xe5xa4xa9' ``` rb的作用:在读取非文本文件的时候,比如读取MP3,图像,视频等信息的时候就需要用到rb。因为这种数据是没办法直接显示出来的。例如网上直播,就是这种数据。

    4.2 读取文件的方法

    4.2.1 read()

    read():将文件中的内容全部读取出来。
    弊端:占内存,如果文件过大,容易导致内存崩溃。 ```Python open("a.txt", mode="r", encoding="utf-8") as f: content = f.read() print(content) ```

    4.2.2 read(n)

    读取n个字符。
    需要注意的是,如果再次读取,那么会在当前位置继续去读,而不是从头读。
    ```Python open("a.txt", mode="r", encoding="utf-8) as f: content = f.read(3) print(content) ``` 如果使用的是rb模式,则读取出来的是n个字节。 ```Python open("a.txt", mode="rb") as f: content = f.read(3) print(content) ``` 执行结果为: ```Python b'xe5x8fx8b' ```

    4.2.3 readline()

    一次读取一行数据。
    注意:readline()结尾,每次读出出来的数据都会有一个
    所以,需要先用strip()方法来去掉 或者空格。 ```Python open("a.txt", mode="r", encoding="utf-8) as f: content1 = f.readline() content2 = f.readline() content3 = f.readline() content4 = f.readline() print(content1) print(content2) print(content3) print(content4) ```

    4.2.4 readlines()

    readlines()将每一行形成一个元素,放到一个列表中,将所有的内容都读取出来。
    但是,容易出现内存崩溃的问题,不推荐使用。 ```Python open("a.txt", mode="r", encoding="utf-8) as f: lst = f.readlines() for line in lst: print(line.strip()) ```

    4.2.5 循环读取

    这种方式是组好的,每次读取一行内容,不会产生内存溢出的问题。 ```Python open("a.txt", mode="r", encoding="utf-8") as f: for line in f: print(line.strip()) ```

    4.3 写模式(w, wb)

    写的时候注意,如果没有文件,则会创建文件,如果文件存在,则将原件中原来的内容删除,再写入新内容。 ```Python open("a.txt", mode="w", encoding="utf-8") as f: f.write("哇哈哈哈") ``` 在wb模式下,可以不指定打开文件的编码,但是在写入文件的时候必须将字符串转换成utf-8的bytes数据。 ```Python open("a.txt", mode="wb") as f: f.write("哇哈哈哈".encoding="utf-8") ```

    4.4 追加(a, ab)

    在追加模式下,我们写入的内容会追加在文件的结尾 ```Python open("a.txt", mode="a", encoding="utf-8") as f: f.write("哇哈哈哈") ``` ab的用法和wb一样 ```Python open("a.txt", mode="ab") as f: f.writer("哇哈哈哈哈".encoding="utf-8") ```

    4.5 读写模式(r+, r+b)

    对于读写模式,必须是先读,因为默认光标是在开头的,准备读取的,当读完了之后,再进行写入,在进行读写文件时,使用频率最高的模式就是r+。 ```Python open("a.txt", mode="r+", encoding="utf-8") as f: content = f.read() print(content) f.write("诗和远方") ``` 一定要先读取,然后才能写入。如果先写入,那么开头的数据就会被后来写入的数据替换掉。

    4.6 写读(w+, w+b)

    先将所有的内容清空,然后写入,最后读取,但是读取的内容是空的,不常用。 ```Python open("a.txt", mode="w+", encoding="utf-8") as f: f.write("远方不可及") content = f.read() print(content) ``` 在w+模式下,一开始是读取不到数据,然后在写的时候再将原来的内容清空,所以很少使用。

    4.7 追加读(a+)

    a+模式下,不论先读还是后读,都是读取不到数据的。 ```Python open("a.txt", mode="a+", encoding="utf-8") as f: f.write("啦啦啦") content = f.read() print(content) ```

    5. 其他相关操作

    5.1 移动光标seek(n)

    seek(n),将光标移动到n位置,注意的是,移动的但是byte,所以如果是UTF-8的中文部分要是3的倍数。
    通常使用seek都是移动开开头或者结尾。
    移动到开头:seek(0)
    移动到结尾: seek(0, 2), seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾。 ```Python open("a.txt", mode="r+", encoding="utf-8") as f: f.seek(0) #光标移动到开头 content = f.read() #读取内容,此时光标移动到结尾 print(content) f.seek(0) #再次将光标移动到开头 f.seek(0, 2) #将光标移动到结尾 content2 = f.read() #读取内容,什么都读取不到 print(content2) f.seek(0) #移动光标到开头 f.write("番茄炒鸡蛋") ```

    5.2 tell()

    使用tell()可以定位当前光标所在的位置。 ```Python open("a.txt", mode="r+", encoding="utf-8") as f: f.seek(0) #光标移动到开头 f.write("周星驰") print(f.tell()) #此时光标的位置是9 ```

    5.3 truncate()截断文件

    ```Python open("a.txt", mode="w", encoding="utf-8") as f: f.write("哈哈") #写入两个字符 f.seek(3) #光标移动到3, 也就是两个字中间 f.truncate() #删除光标后面的所有内容 ```
    open("a.txt", mode="r+", encoding="utf-8") as f:
        content = f.read(3)     #读取12个字符
        f.seek(4)               
        print(f.tell())         #获取当前坐标的位置
        f.truntcat()            #后面的所有内容都删除
    

    注意:在r+模式下,如果读取了内容,不论读取内容多少,光标显示的是多少,再写入或者操作文件的时候都是在结尾进行的操作。

    所以如果想做阶段操作,要先挪动光标到想要截断的位置,然后再进行截断。
    关于truncate(n),如果给出了n,则从开头进行截断。
    如果不给n,则从当前位置截断,后面的内容将会被删除。

    6. 修改文件的方式

    文件的修改,只能将文件中的内容读取到内存中,将信息修改完毕,然后将源文件删除,将新文件的名字改成老文件的名字。 ```Python import os with open("a.txt", mode="r", encoding="utf-8") as f1, open("a_new.txt", mode="w", encoding="utf-8") as f2: content = f1.read() new_content = content.repalace("a", "b") #把a.txt中的所有a替换成b f2.write(new_content) os.remove("a.txt") os.rename("a_new.txt", "a.txt") #将a_new.txt文件改名为a.txt ```

    7. 打开文件的另一种方式

    ```Python with open("a.txt", mode="r", encoding="utf-8") as f: content = f.read() ``` 这种读取文件的方式是一次将所有内容读取出来,当文件内容过大时,就会造成内存溢出。
    解决方案:一行一行的读取和操作 ```Python with open("a.txt", mode="r", encoding="utf-8") as f: for line in f: print(line) ```
  • 相关阅读:
    Python基础教程之第2章 列表和元组
    java最简单的方式实现httpget和httppost请求
    90后女生微信销售案例:预热和成熟
    window.onload与$.ready的差别
    在delphi下TClientSocket的使用技巧 转
    delphi安装 Tclientsocket, Tserversocket控件
    DELPHI SOKET 编程(使用TServerSocket和TClientSocket) 转
    Delphi ServerSocket,ClientSocket示例
    Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件
    delphi TServerSocket阻塞线程单元 实例
  • 原文地址:https://www.cnblogs.com/yang-wei/p/9630549.html
Copyright © 2011-2022 走看看