zoukankan      html  css  js  c++  java
  • 第三章| 3.1文件处理

    1、三元运算

    简单条件语句:

    if 条件成立:
        val = 1
    else:
        val = 2
    

    改成三元运算:

    val = 1 if 条件成立 else 2

    2、文件处理 (用python对硬盘上的文件操作)

    读取文件的三个方法:read()、readline()、readlines()

    三个方法均可接受一个变量用以限制每次读取的数据量,通常不使用该变量。

    关于read()方法: 1、读取整个文件,将文件内容放到一个字符串变量中 2、如果文件大于可用内存,不可能使用这种处理

    关于readline()方法: 1、readline()每次读取一行,比readlines()慢得多 2、readline()返回的是一个字符串对象,保存当前行的内容

    关于readlines()方法: 1、一次性读取整个文件。 2、自动将文件内容分析成一个行的列表。

    f = open(file = "兼职白领学生空姐模特护士联系方式.txt",mode="r",encoding="utf-8") #r模式以什么方式存的就要以什么方式读出来。如果文件是gbk格式,就encoding=“gbk”
    data = f.read() #read方法是把文件全部读出到屏幕输出;readline是读取文件的一行信息;readlines是读取整个文件,输出屏幕的是一行包含所有的信息。
    print(data)  
    f.close() #一定要加上这个,不然数据文件数据就没有了,哎呀
    read打印:
    王心       北京    159    46    13813234424
    马纤羽     深圳    173    50    13744234523
    乔亦菲     广州    172    52    15823423525
    罗梦竹     北京    175    49    18623423421
    刘诺涵     北京    170    48    18623423765
    岳妮妮     深圳    177    54    18835324553
    贺婉萱     深圳    174    52    18933434452
    叶梓萱     上海    171    49    18042432324
    杜姗姗     北京    167    49    13324523342
    black girl 河北    167    50    135423422334
    
    readline:
    王心       北京    159    46    13813234424
    
    readlines:
    ['王心       北京    159    46    13813234424
    ', '马纤羽     深圳    173    50    13744234523
    ', '乔亦菲     广州    172    52    15823423525
    ', '罗梦竹     北京    175    49    18623423421
    ', '刘诺涵     北京    170    48    18623423765
    ', '岳妮妮     深圳    177    54    18835324553
    ', '贺婉萱     深圳    174    52    18933434452
    ', '叶梓萱     上海    171    49    18042432324
    ', '杜姗姗     北京    167    49    13324523342
    ', 'black girl 河北    167    50    135423422334']

    存在硬盘上是二进制。以什么方式存的文件,就要以什么样的方式打开这个文件。此处的encoding必须和文件在保存时设置的编码一致,不然“断句”会不准确从而造成乱码。
    r文本模式
    二进制转换为字符串。open把它转一下。

    rb为二进制模式,把这段内容直接读到内存里边来,硬盘怎么存的就怎么拿来,不用它转了。 视频、图片或者网络传输的文本,都是二进制模式。
    f = open(file = "兼职白领学生空姐模特护士联系方式.txt",mode="rb") #二进制模式就不需要encoding了
    data = f.read()
    print(data)  #打印出来就是二进制格式
    f.close()
    打印:
    b'xe7x8ex8bxe5xbfx83       xe5x8cx97xe4xbaxac    159    46    13813234424
    xe9xa9xacxe7xbaxa4xe7xbexbd     xe6xb7xb1xe5x9cxb3    173    50    13744234523
    xe4xb9x94xe4xbaxa6xe8x8fxb2     xe5xb9xbfxe5xb7x9e    172    52    15823423525
    xe7xbdx97xe6xa2xa6xe7xabxb9     xe5x8cx97xe4xbaxac    175    49    18623423421
    xe5x88x98xe8xafxbaxe6xb6xb5     xe5x8cx97xe4xbaxac    170    48    18623423765
    xe5xb2xb3xe5xa6xaexe5xa6xae     xe6xb7xb1xe5x9cxb3    177    54    18835324553
    xe8xb4xbaxe5xa9x89xe8x90xb1     xe6xb7xb1xe5x9cxb3    174    52    18933434452
    xe5x8fxb6xe6xa2x93xe8x90xb1     xe4xb8x8axe6xb5xb7    171    49    18042432324
    xe6x9dx9cxe5xa7x97xe5xa7x97     xe5x8cx97xe4xbaxac    167    49    13324523342
    black girl xe6xb2xb3xe5x8cx97    167    50    135423422334'
    自动检测编码:(不知道原文件是什么编码)
    import chardet
    f = open('log',mode='rb')
    data = f.read()
    f.close()
    
    result = chardet.detect(open('log',mode = 'rb').read())
    print(result)  #{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

     循环文件 (边读边处理,内存就存一小块。)

    f = open("兼职白领学生空姐模特护士联系方式.txt",'r',encoding="gbk")
    for line in f:
        print(line)
    f.close()
    #循环打印出:
    王心 北京 159 46 13813234424 马纤羽 深圳 173 50 13744234523 乔亦菲 广州 172 52 15823423525 罗梦竹 北京 175 49 18623423421 刘诺涵 北京 170 48 18623423765 岳妮妮 深圳 177 54 18835324553 贺婉萱 深圳 174 52 18933434452 叶梓萱 上海 171 49 18042432324 杜姗姗 北京 167 49 13324523342 black girl 河北 167 50 135423422334

    写文件(w是创建不是修改,没有就清空覆盖了。)   w给转换,而wb 二进制的就不用转换了。

    f = open("兼职.txt",'w',encoding = "gbk") #创建一个文件以gbk的形式
    f.write(“路飞学城!”) #”路飞学城”是以unicode的形式写的,再编码为gbk
    f.close()
    f = open("兼职2.txt",'wb') #创建一个兼职2的文件
    f.write(“路飞学城!”.encode("gbk")) #encode下表示以什么样的编码存在
    f.close()
    f = open("兼职.txt",'wb')
    f.write("原子二号".encode("gbk")) #新写进去的没有的就清除再创建,会把原来的文件被清空了。
    f.close()

     

    追加模式(修改,追加到文件尾部。以a或者ab的模式打开)

    f = open("兼职白领学生空姐模特护士联系方式.txt",'ab') #以ab的模式打开 
    f.write("
    肛娘    北京  167   55   13312340322”.encode("gbk"))#追加到文件后面,
    为换行
    f.close()

    比如:追加“给岁月以文明,而不是给文明以岁月”在第五行。(就是把其他的内容往下挤,不是覆盖第五行)(见练习题)

    lines = []
    f = open('三体语录','r',encoding='utf-8')
    for line in f:
      lines.append(line)
    lines.insert(5,'给岁月以文明,而不是给文明以岁月
    ')
    s = ''.join(lines)  #把列表转成字符串
    with open('三体语录','w',encoding='utf-8')as f_write:
      f_write.write(s)
      f_write.close()

    混合操作(既能写又能读即 读写模式。r+ )

       

      读写就相当于append,只是多了个可以读。

    写读模式 w+  (几乎没什么应用场景)

    读写是先读后写,以读的模式打开然后往后继续追加;写读模式,是以写的模式打开(就是创建的模式)支持你读,把你写的读出来,但是之前的被清空了。

      

    文件操作的其他功能

       def fileno(self, *args, **kwargs): # real signature unknown
            返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到
        def flush(self, *args, **kwargs): # real signature unknown
            把文件从内存buffer里强制刷新到硬盘
    
        def readable(self, *args, **kwargs): # real signature unknown
            判断是否可读
    
        def readline(self, *args, **kwargs): # real signature unknown
            只读一行,遇到
     or 
    为止
    
        def seek(self, *args, **kwargs): # real signature unknown
            把操作文件的光标移到指定位置
            *注意seek的长度是按字节算的, 字符编码存每个字符所占的字节长度不一样。
            如“路飞学城” 用gbk存是2个字节一个字,用utf-8就是3个字节,因此以gbk打开时,seek(4) 就把光标切换到了“飞”和“学”两个字中间。
            但如果是utf8,seek(4)会导致,拿到了飞这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用utf8处理不了了,因为编码对不上了。少了一个字节
    
        def seekable(self, *args, **kwargs): # real signature unknown
            判断文件是否可进行seek操作
    
        def tell(self, *args, **kwargs): # real signature unknown
            返回当前文件操作光标位置 
    
        def truncate(self, *args, **kwargs): # real signature unknown
            按指定长度截断文件
            *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。
    
        def writable(self, *args, **kwargs): # real signature unknown
            判断文件是否可写

    flush 强制把内存刷到硬盘。

      flush() 方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入,   正常情况下缓冲区满时,操作系统会自动将缓冲数据写入到文件中。

    一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。

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

       

    readline()

     tell()返回当前文件操作光标位置;  seek()把操作文件的光标移到指定位置。

        

    seek(3)真的是字符吗?不是的,seek是找的是字节。  tell()是寻找光标的位置read是读的字符,tell和seek是找的字节。

    utf-8中一个中文占3个字节,gbk中一个中文占2个字节。

    >>>f = open('兼职白领学生空姐模特护士联系方式.tex',‘r’, encoding='gbk')   #文件里边:hello world! 
    >>>f.seek(3)
    3
    >>>f.readline()
    'lo world!'

      

     truncate()按指定长度截断文件 要以r+的模式打开   *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。

     

        

     文件修改 (两种方式:要么占内存要么占硬盘)

     把光标seek到中间的位置就可以了。

    占硬盘修改,打开旧文件一行行的读,新文件一行行的写。  最后把新文件重命名为旧文件,就把它覆盖掉了。命名要 import os

    import os
    f_name = "兼职白领学生空姐模特护士联系方式.txt" f_new_name = "%s.new" %f_name old_str = "乔一菲" new_str = "红娘" f = open(f_name,"r",encoding="utf-8") f_new = open(f_new_name,"w",encoding="utf-8") for line in f: if old_str in line: line = line.replace(old_str,new_str) f_new.write(line) f.close() f_new.close() os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆盖掉了
    
    

    占内存方式:以r+模式打开文件全read在内存,直接.replace,全程读一遍然后再seek到文件开头,再写进去就覆盖掉了。不一定能全部覆盖,怎么办:先把文件truncate完,flush

    #占内存方式修改 
    f = open('兼职白领学生空姐模特护士联系方式.txt','r+',encoding='utf-8')
    f1 = f.readlines()
    f.seek(0)  #这个一定要加
    old_str = "乔亦菲"
    new_str = "Yifei Qiao"
    for line in f1:
        if old_str in line:
            line = line.replace(old_str,new_str)
        f.write(line)
    #f.truncate()
    #f.flush()
    f.close()
    
    
    #################
    f = open(r"info.txt", "r+")
    l = f.readlines()
    f.seek(0)  # 指针指向文件开头
    old_str = "唐三"
    new_str = ""
    for line in l[0::2]:  # 只取部分字符
         if old_str in line:
             line = line.replace(old_str,new_str)
         f.write(line+"
    ")
    f.truncate()
    # 对文件进行截取,如果文件之前为100M,
    # 修改后文件只覆盖了50M,如果不使用truncate不会整体覆盖,只会部分覆盖,后面剩余的50M内容会追加新文件中,修改后的文件大小不变
    # 使用truncate后,文件就只有50M,他会把剩余的50M内容从当前write的指针后面进行截取
    f.close()

     对文件的删除

    如:删除最后一行

    with open('三体语录','r',encoding='utf-8') as f:
        f1 = f.readlines()  ##readline 和readlines的区别
        with open('三体语录','w',encoding='utf-8')as f_w:
            for line in f1:
                if '25' in line:
                    continue  #跳出本次循环
                f_w.write(line)
  • 相关阅读:
    蒸发冷却概述
    2011年2月22日星期2
    在中国搞技术的都是狗
    实用新型专利申请书规范
    我小时候家里穷
    蒸发冷却基本原理
    opera浏览器使用技巧
    浏览器哪个好用
    Matlab数理统计工具箱应用简介(转)
    EXCEL模板读写说明(转)
  • 原文地址:https://www.cnblogs.com/shengyang17/p/8570312.html
Copyright © 2011-2022 走看看