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

    本文主要记录Python中的文件的常用操作

    1.文件操作的流程

    1)打开文件,得到文件句柄并赋值给一个变量
    2)通过句柄对文件进行操作
    3)操作完成,关闭文件

    2.打开文件的常用模式

    有以下2个示例文件:

    # hello_gbk.txt文件为GBK编码,hello_utf8.txt文件为utf-8编码

    Somehow, it seems the love I knew was always the most destructive kind
    不知为何,我经历的爱情总是最具毁灭性的的那种
    Yesterday when I was young
    昨日当我年少轻狂
    The taste of life was sweet
    生命的滋味是甜的
    As rain upon my tongue
    就如舌尖上的雨露
    I teased at life as if it were a foolish game
    我戏弄生命 视其为愚蠢的游戏
    View Code

    2.1.一般模式

    "r"模式

    #"r"只读模式,是默认模式,默认编码是gbk,不可写

    # print(f.read(10))        # 默认读全文,可以按照指定字符数量读文件内容
    # print(f.readline(10))     # 默认读取一行,遇到
    或者
    为止,适合读小文件,也可以按照指定字符数量读文件内容
    # print(f.readlines(1))       # 默认读取全文转换为带
    的列表,括号中指定数字,读取第一行
    # print(f.readlines()[3])     # 可以用这种方式读取出某4行

    实例1:文件读取

    f = open(file='hello_gbk.txt',mode='r',encoding='gbk')    # 标准完整格式,文件名可以加绝对路径
    # f = open('hello_gbk.txt')                   # 最简单的写法
    # f = open('hello_gbk.txt',encoding='gbk')           # 简写2,最后的encoding必须写上
    print(f.readline())                      # 读一行内容
    print('分隔线'.center(50,'-'))
    data = f.read()                                   # 读取剩下的所有内容,文件大时不要用
    print(data)                                     #打印文件
    f.close()                                      #关闭文件

    注解:
    mode='r' encoding='utf-8' #表示 只读 硬盘上的0101按照utf-8的规则去‘断句’,再将断句后的每一段0101转换成Unicode的01010,Unicode对照表中0101和字符的对应关系。
    mode='rb' # 以什么形式存的就以什么形式读 ,二进制打开,给机器看的,用于视频,图片,网络传输

    实例2:读前3行内容--->思路:使用循环
    # 简单想法:尝试以下3种方式

    # 方法1:
    f = open(file='hello_gbk.txt',mode='r',encoding='gbk')
    for i in range(3):
        print(f.readline().strip())
    
    # 方法2:
    f = open(file='hello_gbk.txt',mode='r',encoding='gbk')
    for index,line in enumerate(f.readlines()):
        if index == 5:
            print("--------")
            exit()
        print(line.strip())
    # 注意:以上2中方法在读大文件的时候可能会把内存撑爆,所以readline()的方式不能用于读大文件
    
    # 方法3:优化后,读一行删一行,内存中只保留一行内容,如下:
    f = open(file='hello_gbk.txt',mode='r',encoding='gbk')
    count = 0
    for line in f:                            # 不是列表了,变成了文件迭代器
        if count == 5:
            print("----------")
            count += 1
            exit()
        print(line.strip())
        count += 1
    # 这种方法3是读取文件的最优方法

    "w"模式 

    # "w"创建文件,不可读文件,如果有同名文件则相当于清空数据,重新写入,所以要慎用

    实例1:创建文件

    f = open("hello2.txt",'w')                      # 不指定编码,默认创建gbk格式的文件
    f.write("hello2")
    f.close()
    
    f = open("hello2.txt",'w',encoding='utf-8')         # 如果要创建指定编码格式的文件,需要加“encoding=”字段
    f.write("hello2") 
    f.close()
    注意:在pycharm中写的内容用的是unicode,但在保存成txt文件时会自动转码为GBK的

    "a"模式 

    # "a"追加,但不可读文件,使用a可以直接打开文件,然后直接追加内容

    实例1:追加内容

    f = open("hello2.txt",'a',encoding='gbk')
    f.write("
    我是追加的内容1")                   # 写入的内容需要和原文件编码相同,否则会出现部分乱码,
    用于换行
    f.close()

    2.2.混合读写模式

    "r+"模式  

    # "r+"读写模式。可读,可写,可追加。偶尔用

    实例1:追加写入文件内容

    f = open("hello2.txt",'r+',encoding='gbk')         # 使用"r+",不管怎样移动光标,文字都会追加到文件最后
    data = f.read()                                 # 必须先读到内存中,然后追加,最后写回文件中
    print(data)
    f.write("
    再写点东西")
    f.close()

    "w+"模式

    # "w+",写读模式,会先创建一个文件再写入,也就是清空文件内容,慎用(不用)

    实例1:

    f = open("hello2.txt",'w+',encoding='gbk')
    data = f.read()
    print(data)                                       # 先创建空文件,所以读不出内容,也就无打印
    f.write("
    我还要写点东西")
    f.close()

    "a+"模式 

    # "a+",同a,追加模式,可读(可用)

    2.3.二进制模式,"b"表示处理二进制文件

    二进制"rb"模式

    #1)网络传输:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注
    #2)音视频文件读写

    实例1:

    f = open("hello3.txt",'rb')                   # 使用二进制写模式rb打开文件,不需要使用encoding='gbk'
    print(f.read())                               # 打印的是二进制额bytes数据
    f.close()

    # 实例2:调用chardet模块(需要单独安装),推断文件的编码格式

    pip3 install chardet 
    import chardet
    result = chardet.detect(open(file='hello3.txt',mode='rb').read())
    print(result)
    --->{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

    二进制"wb"模式 

    # 用二进制创建文件,音视频,图片或者其他任何数据等,可以直接传输,可以手动编码
    实例1:

    f = open("hello3.txt",'wb')                      # 使用二进制写模式wb打开文件,不需要使用encoding='gbk'
    f.write("hello3中国你好,二进制写一句".encode('gbk'))    # 使用二进制写入“hello3”,需要转码,否则报错,可以指定GBK,utf-8等进行编码
    f.close()   

    二进制"ab"模式

    # 二进制方式追加文件内容
    实例1:

    f = open("hello3.txt",'ab')                        # 使用二进制追加模式ab打开,进行追加,不需要使用encoding='gbk'
    f.write("
    我是用二进制追加的内容".encode('gbk'))      # 如果使用二进制方式ab写文件,需要转码,否则报错
    f.close()

    2.4.兼容读写模式

    # 用于windows和linux的兼容
    "U"表示在读取时,可以将 自动转换成 (与 r 或 r+ 模式同使用)

    rU
    r+U

    3.文件的其他操作方法:

    3.1.刷新缓存 

    # f.flush()将内存中的内容手动刷新到硬盘中,需要到windows的客户端里测试刷新效果--------------------------------

    f = open("hello3.txt", 'w')
    f.write("
    test flush")
    f.flush()
    f.close()

    # 拓展:进度条

    import sys,time
    for i in range(50):
        sys.stdout.write("#")     # 默认不换行
        sys.stdout.flush()
        time.sleep(0.5)

    3.2.移动光标

    # f.tell()返回当前操作的文件的光标位置
    # f.seek()移动光标到指定位置
    # f.read()是按照字符读文件,f.tell()和.seek()是按照字节读文件

    # 拓展:不同的字符编码中,每个字符所占用的字节长度不一样,所以在不同的编码中同一个字的seek就不同
    1)ASCII码一个字符默认占1个字节,8位,不能存中文,所以出了Unicode
    2)GBK中:一个中文字符占用2个字节,1个英文字符占用1个字节
    3)utf-8是一个汉字占用3个字节,所有的英文用ASCII码存,一个字符默认占1个字节,8位
    4)unicode中:一个中文字符占2个字节,16位,

    # 实例:不同字符编码下的光标位置

    使用GBK

    f = open("hello_gbk.txt","r",encoding="gbk")
    f.seek(13)                             # 光标移动13个字节,在GBK下中文占2个字节,英文占1个字节
    print(f.read(10))                      # 读10个字符,不区分中英文
    print(f.tell())                        # 回车
    也计算了一个字节
    f.close()

    使用utf-8

    f = open("hello_utf8.txt","r",encoding="utf8")
    f.seek(13)                              # 光标移动13个字节,在utf-8下中文占3个字节,英文占1个字节,注意文件开头占3个字节
    print(f.read(10))                       # 可以看到与上面的结果不相同
    print(f.tell())
    f.close()

    3.3.截取文件内容

    # .truncate()从第n个字符截断(去掉)文件内容
    1)指定长度:截取文件开头到指定长度位置的字符内容
    2)不指定长度:截取文件开头到光标所在位置的字符内容

    # 实例1:截取开头10个字符的内容

    # 方法1:截取开头到指定长度的字符,简单高效
    f = open("hello3.txt", 'r+', encoding='gbk')      # 使用"r+"或"a"
    f.seek(100)                                       # 与光标在哪无关
    print(f.tell())
    f.truncate(10)
    f.close()
    
    # 方法2:移动光标,从开头截取到光标位置
    f = open("hello3.txt",'r+',encoding='gbk')        # 使用"r+"或"a"
    f.seek(10)
    print(f.tell())
    f.truncate()
    f.close()

    3.4.其他一些简单的方法:

    f.fileno()      用于返回文件句柄在内核中的索引值,在做IO多路复用时可以用到,一般用不到
    f.isatty()      判断是否是个终端文件
    f.seekable()     判断文件是否可进行seek操作 
    f.readable()     判断文件是否可读,w不可读
    f.writable()     判断文件是否可写
    f = open("hello_gbk.txt",'r+',encoding='utf-8')    # 使用"r+"
    print(f)
    print(f.encoding)                       # 打印文件的编码格式,注意后面不加括号
    print(f.name)                           # 打印文件的名字
    print(f.buffer)
    print(f.errors)

    4.with语句,自动关闭文件

    # 为了避免打开文件后忘记关闭,可以通过with方法打开文件

    with open("hello2.txt",'r',encoding='gbk') as f:
        print(f.read())

    # 如果一次打开较多文件,建议换行书写代码

    with open("hello2.txt") as f1 ,
         open("hello3.txt") as f2:
        for i1 in f1:
            print(i1.strip())
        for i2 in f2:
            print(i2.strip())

    5.修改文件内容的一般方法:

    1)类似vim这种,将修改的文件内容加载到内存中,修改完保存到源文件中
    内存中的内容不存在写数据就覆盖的问题会自动移位
    但是如果打开大文件,内存可能不够,或者系统变慢
    2)读到缓存文件中逐行读写,修改完使用临时文件覆盖原文件

    import os
    f_name = "hello3.txt"
    f_new_name = "%s.new" %(f_name)
    old_str = "[[改了又改]]"                        # find_str = sys.argv[1]
    new_str = "[想改就改,改的响亮]"                 # replace_str = sys.argv[2]
    f = open(f_name,'r',encoding="gbk")
    f_new = open(f_new_name,'w',encoding="gbk")
    for line in f:
        if old_str in line:
            new_line = line.replace(old_str,new_str)   # new_line = line.replace(find_str,replace_str)
        else:
            new_line = line
        f_new.write(new_line)
    f.close()
    f_new.close()
    os.replace(f_new_name,f_name)
    # os.rename(f_new_name,f_name)                 # mac,linux

    完毕,呵呵呵呵

  • 相关阅读:
    (C/C++学习笔记) 十四. 动态分配
    (C/C++学习笔记) 十三. 引用
    (C/C++学习笔记) 十二. 指针
    (C/C++学习笔记) 十一. 数组
    (C/C++学习笔记) 十. 函数
    (C/C++学习笔记) 九. 变量的存储类型
    (C/C++学习笔记) 八. 程序控制语句
    并发编程之多进程
    网络编程之Socket
    异常处理
  • 原文地址:https://www.cnblogs.com/tssc/p/9302077.html
Copyright © 2011-2022 走看看