zoukankan      html  css  js  c++  java
  • python3 文件操作

    '''
    一、文件操作(读写追加,其他方法)
    f = open(文件,mode="模式", encoding="编码")
    模式:
        r:只读
        w:只写
        a:追加写
        +:扩展
        b:字节(非文本文件)
    
    读取文件最好的方案
    with open() as f:
        for line in f:
            line = line.strip()
    
    修改文件:
    1、创建一个文件副本。
    2、把源文件中的内容读取到内存。
    3、然后再内存中进行修改。
    4、修改之后保存在文件副本中。
    5、把源文件删除。
    6、把文件副本更改名称为源文件的名称。
    
    1.1.初识文件操作
        使用python来读写文件是非常简单的操作。我们使用open()函数来打开一个文件,获取到文件句柄。
    然后通过文件句柄就可以进行各种各样的操作了。根据打开方式的不同能够执行的操作也会有相应的差异。
    打开文件的方式:r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b默认使用的是r(只读)模式
    
    1.2.只读操作(r, rb)
    需要注意encoding表示编码,根据文件的实际保存编码进行获取数据,对于我们而言,更多的是utf-8.
    '''
    '''1.写模式(w, wb)
    写的时候注意,如果没有文件,则会创建文件,如果文件存在,则将原件中原来的内容删除,再写入新内容'''
    f = open("a1.txt", "w", encoding="utf-8")
    f.write("苹果
    ")
    f.write("桃子
    ")
    f.write("香蕉
    ")
    f.close()
    '''w只读write模式,写会报错'''
    f = open("a1.txt", "w", encoding="utf-8")
    f.write("苹果
    ")
    f.write("桃子
    ")
    f.write("香蕉
    ")
    content = f.read()  # UnsupportedOperation: not readable
    f.close()
    ---------------------------------------------------------------------------
    UnsupportedOperation                      Traceback (most recent call last)
    <ipython-input-129-01a25d1ab733> in <module>()
          4 f.write("桃子
    ")
          5 f.write("香蕉
    ")
    ----> 6 content = f.read()  # UnsupportedOperation: not readable
          7 f.close()
    
    UnsupportedOperation: not readable

    '''
    wb模式下,不指定打开文件的编码,但是在写文件的时候必须将字符串转换成utf-8的bytes数据。
    '''
    f = open("c1.txt", mode="wb") 
    print("橙汁".encode("utf-8"))  # b'xe6xa9x99xe6xb1x81'
    f.write("橙汁".encode("utf-8"))
    f.flush()
    f.close()
    b'xe6xa9x99xe6xb1x81'

    '''
    2.r只读read模式,read()将文件中的内容全部读取出来,弊端:占内存,如果文件过大。容易导致内存崩溃。
    '''
    f = open("a1.txt", mode="r", encoding="utf-8")
    content = f.read()
    print(content)
    f.close()
    苹果
    桃子
    香蕉
    
    '''r只读read模式,写会报错'''
    f = open("a1.txt", mode="r", encoding="utf-8")
    content = f.read()
    print(content)
    f.write("aaa")  # UnsupportedOperation: not writable
    f.close()
    苹果
    桃子
    香蕉
    
    
    ---------------------------------------------------------------------------
    UnsupportedOperation                      Traceback (most recent call last)
    <ipython-input-132-1bb711d148ec> in <module>()
          3 content = f.read()
          4 print(content)
    ----> 5 f.write("aaa")  # UnsupportedOperation: not writable
          6 f.close()
    
    UnsupportedOperation: not writable
    
    '''
    rb读取出来的数据是bytes类型,在rb模式下,不能选择encoding字符集。
    rb的作用:在读取非文本文件的时候,比如读取MP3、图像、视频、直播等信息的时候就需要用到rb。因为这种数据是没办法直接显示出来的。
    在后面我们文件上传下载的时候还会用到。
    '''
    f = open("a1.txt", "rb")
    content = f.read()  # read一次把文件内容读取完,type类型
    print(content)  # utf-8编码下,一个汉字是3个字节,一个字节是8位,gbk编码下,一个汉字是2个字节
    f.close()
    b'xe8x8bxb9xe6x9ex9c
    xe6xa1x83xe5xadx90
    xe9xa6x99xe8x95x89
    '
    '''
    read(n)读取n个字符。需要注意的是,如果每次读取,那么会在当前位置继续去读取而不是从头读。
    如果使用的是rb模式,则读取出来的是n个字节。
    '''
    f = open("a1.txt", mode="r", encoding="utf-8")
    content = f.read(4)  # 4个字符
    print(content)
    f.close()
    苹果
    桃
    '''
    readline()一次读取一行数据,注意:readline()结尾,注意每次读取出来的数据都会有一个
    ,需要我们使用strip()方法来去掉
    或者空格。
    '''
    f = open("a1.txt", mode="r", encoding="utf-8")
    content = f.readline()  # 读取一行
    print(content)
    content2 = f.readline()  # 读取一行
    print(content2)
    content3 = f.readline()  # 读取一行
    print(content3)
    f.close()
    苹果
    
    桃子
    
    香蕉
    '''
    readlines()将每一行形成一个元素,放到一个列表中。将所有的内容都读取出来,容易出现内存崩溃的问题,不推荐使用。
    '''
    f = open("a1.txt", mode="r", encoding="utf-8")
    lst = f.readlines()  # 一次把文件读取完,每行为一个元素,放入列表中
    print(lst)  # ['苹果
    ', '桃子
    ', '香蕉']
    for line in lst:
        print(line.strip())
    f.close()
    ['苹果
    ', '桃子
    ', '香蕉
    ']
    苹果
    桃子
    香蕉
    '''
    for循环读取,这种方式是最好的,每次读取一行内容,不会产生内存溢出的问题。
    '''
    f = open("a1.txt", mode="r", encoding="utf-8")
    for line in f:  # 节省内存,一行一行读取
        print(line.strip())
    f.close()
    苹果
    桃子
    香蕉
    '''
    3.追加(a, ab)
    只要是a、ab、a+都是在文件的末尾写入,不论光标在任何位置。
    在追加模式下,我们写入的内容会追加在文件的结尾。
    '''
    f = open("a1.txt", mode="a", encoding="utf-8")
    f.write("南果梨")
    f.flush()
    f.close()
    '''ab和wb追加写和只写模式的时候,记得编码后再写入'''
    f = open("a1.txt", mode="ab")
    f.write("天山雪莲".encode("utf-8"))
    f.flush()
    f.close()
    '''
    4.读写模式(r+, r+b)
    对于读写模式,必须是先读,因为默认光标是在开头的。当读完了之后再进行写入,我以后使用频率最高的模式是r+
    正确操作:
    '''
    f = open("a1.txt", mode="r+", encoding="utf-8")
    content = f.read()
    print(content)
    f.close()
    苹果
    桃子
    香蕉
    南果梨天山雪莲
    '''r+先读取,光标移动到最后,再写入,写入的内容是在最后,然后把光标移动到开始的位置,重新读取'''
    f = open("a1.txt", mode="r+", encoding="utf-8")
    f.read()
    f.write("读完了写入
    ")
    f.seek(0)
    content = f.read()
    print(content)
    f.close()
    苹果
    桃子
    香蕉
    南果梨天山雪莲读完了写入
    '''r+必须是先读,后写,容易出现字符编码问题,会遇到下面的报错'''
    f = open("a1.txt", mode="r+", encoding="utf-8")
    f.write("先写。")  
    now_seek = f.tell()
    print(now_seek)
    f.seek(0)
    content = f.read()  # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 9: invalid start byte
    print(content)
    f.close()
    9
    
    ---------------------------------------------------------------------------
    UnicodeDecodeError                        Traceback (most recent call last)
    <ipython-input-141-3dd82e9e1e9a> in <module>()
          5 print(now_seek)
          6 f.seek(0)
    ----> 7 content = f.read()  # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 9: invalid start byte
          8 print(content)
          9 f.close()
    
    ~Anaconda3libcodecs.py in decode(self, input, final)
        319         # decode input (taking the buffer into account)
        320         data = self.buffer + input
    --> 321         (result, consumed) = self._buffer_decode(data, self.errors, final)
        322         # keep undecoded input until the next call
        323         self.buffer = data[consumed:]
    
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 9: invalid start byte
    '''1.写模式(w, wb)
    写的时候注意,如果没有文件,则会创建文件,如果文件存在,则将原件中原来的内容删除,再写入新内容'''
    f = open("a1.txt", "w", encoding="utf-8")
    f.write("苹果
    ")
    f.write("桃子
    ")
    f.write("香蕉
    ")
    f.close()
    '''
    错误操作:
    结果:将开头的内容改成了“石榴”,然后读取的内容是后面的内容。
    所以记住:r+模式下,必须是先读取,然后再写入
    '''
    f = open("a1.txt", mode="r+", encoding="utf-8")
    f.write("石榴")
    f.seek(0)
    content = f.read()
    print(content)
    f.flush()
    f.close()
    石榴
    桃子
    香蕉
    '''
    seek(n)光标移动到n的位置,注意,移动的单位是byte。所以如果是UTF-8的中文部分要是3的倍数。
    通常我们使用seek都是移动到开头或者结尾。
    移动到开头:seek(0)
    移动到结尾:seek(0, 2) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾。
    '''
    f = open("a1.txt", mode="r+", encoding="utf-8")
    f.seek(0)  # 光标移动到开头,此行可有可无
    content = f.read()  # 读取内容,此时光标移动到结尾
    print(f"content: {content}
    ")
    f.seek(0)  # 再次将光标移动到开头
    content2 = f.read()
    print(f"content2: {content2}
    ")
    f.seek(0, 2)  # 将光标移动到结尾
    content3 = f.read()  # 读取内容,什么都没有
    print(f"content3: {content3}
    ")
    f.seek(0)  # 移动到开头
    f.write("苹果")  # 写入信息,此时光标在6 中文2*3 = 6
    f.flush()
    f.close()
    content: 石榴
    桃子
    香蕉
    
    
    content2: 石榴
    桃子
    香蕉
    
    
    content3: 
    '''
    tell()可以帮我们获取到当前光标在什么位置
    '''
    f = open("a1.txt", mode="r+", encoding="utf-8")
    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("榴莲")  # 写入信息,此时光标在6 中文3*2 = 6
    print(f.tell())  # 光标的位置6
    f.flush()
    f.close()
    苹果
    桃子
    香蕉
    
    
    6
    '''
    truncate()截断文件
    '''
    f = open("d1.txt", mode="w", encoding="utf-8")
    f.write("苹果")  # 写入两个字符
    f.seek(3)  # 光标移动到3,也就是两个字中间
    f.truncate()  # 删除光标后面的所有内容
    f.close()
    '''
    总结:
    f.read(n) 如果是r模式打开,表示读取n个字符
    f.read(n) 如果是rb模式打开,表示读取n个字节
    f.seek(n) 表示n个字节,1中文由3个字节组成 
    '''
    '''a+模式,不管光标移动到哪个位置,都是在最后写入内容'''
    f = open("a1.txt", "a+", encoding="utf-8")
    f.seek(0)
    f.write("开始位置
    ")
    f.seek(0)
    content = f.read()
    print(content)
    f.close()
    榴莲
    桃子
    香蕉
    开始位置
    '''
    修改文件以及另一种打开文件的方式(重点)
    文件修改:只能将文件中的内容读取到内存中,将信息修改完毕,然后将源文件删除,将新文件的名字改成老文件的名字。
    '''
    import os
    
    with open("b1.txt", mode="r", encoding="utf-8") as f1,
        open("b1.txt_temp", mode="w", encoding="utf-8") as f2:
        for line in f1:
            new_line = line.replace("砀山梨", "橙汁")
            f2.write(new_line)
    os.remove("b1.txt")  # 删除源文件
    os.rename("b1.txt_temp", "b1.txt")  # 重命名新文件
    
    
    import requests
    
    
    url = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2241880857,977619289&fm=26&gp=0.jpg"
    content = requests.get(url).content
    with open("flower.jpg", "wb") as f:  # 将图片写入文件
        f.write(content)




  • 相关阅读:
    分布式版本控制系统Git的安装与使用
    利用GitLab自动同步软件仓库
    MakerDAO 代币解释:DAI, WETH, PETH, SIN, MKR(一)
    数组 Major^
    String 类 Major^
    深度优先排序(数字全排列) Major^
    喊数字小游戏 Major^
    java数据类型 Major^
    ArrayList类的使用方法 Major^
    深度优先搜索(迷宫救人最短路径) Major^
  • 原文地址:https://www.cnblogs.com/lilyxiaoyy/p/11842972.html
Copyright © 2011-2022 走看看