zoukankan      html  css  js  c++  java
  • python学习笔记(五)- 文件操作

    1、读文件
    f
    = open('word.txt'encoding='utf8')  #默认打开当前目录下的文件,打开其它目录用绝对路径

    #f = open('word.txt',encoding='utf-8')  #如果报字符编码错误,可能因为中文问题(bbk)
    #file()  #python2中打开文件的的方式
    print(f.read())       #读文件,字符串类型print(f.readline())   #一次读取一行内容print(f.readlines())  #把文件的每一行用
    换行,放到一个list里面
     f.write('sss')  #报错,默认读模式,不能写
    ④f.close()  #每次都要关闭文件
    
    

    打开绝对路径的方式:

      f = open(r'H:pythonprojectday4word.txt')

    2、打开文件的几种方式的比较:

    1、读模式(默认) r  读写模式r+  
      f = open('word.txt')
      1)r/r+文件不存在的话会报错(r
    +文件不存在时都报错)
      2r 读模式打开的文件,不能写
      3)r+ 模式打开的文件,可以写,但默认是在文件最前面写
     
    2、写模式  w   写读模式w+
     f = open('word.txt','w')
      1)w/w+ 文件不存在的话,会帮你新建文件
      2)w/w+ 打开一个已存在的文件,然后写,都会覆盖文件以前的内容
      3)w模式,不能读,报错    比如,print(f.read()) #不能读
      4)w+ 模式,不报错,但读不到内容,因为内容已经被清空了
    
    3、追加模式  a  追加读模式a+
      f = open('word1.txt','a')
      1)a/a+文件不存在的话,会新建文件
      2)a/a+ 都能写,不会清空原来的文件,在尾行末尾写内容
      3a模式,不能读,报错
      4)a+模式,读不到内容,因为文件指针在末尾(配合f.seek(0)就能读到)
    
     #只要沾上了r,文件不存在时都报错
     #只要沾上了w,文件写时都会清空原来的内容

     

    3、文件指针:控制读哪一行

      1)r模式:文件指针

    f = open('word.txt',encoding='utf8')
    
    print('read读的:
    ',f.read()) #文件指针到末尾
    print('readline读的:
    ',f.readline())   #f.readline()没有读到内容

      

      2)a+模式:a模式默认文件指针在末尾

    f = open('word.txt','a+',encoding='utf8')
    print(f.read())  #a+模式,文件指针默认在文件末尾,所以读不到内容
    f.write('zzzz')  #但可以在末行末尾写

      3)a+模式 和f.seek()一起使用:(推荐)

    f = open('word1.txt','a+')
    f.seek(0)  #把文件指针移动到文件最前面
    print(f.read())  #可以读到内容

      4)

    f.seek(0) #a+模式,移动指针到最前面,只能从最前面读,写还是文件末尾写
    point = f.tell()  #获取到当前文件指针的位置

    4、打开文件且自动关闭文件的方式:

    with open('word.txt','a+') as f:
        for line in f:
            print(line)

    5、【练习1-随机产生一些手机号】

    #随机生成手机号后四位,然后写到文件里面
    #比如:1861111 9999   #import random
    # print(random.randint(1,1000))
    # print('1',zfill(4))   #不够4位,前面补0
    
    import random
    f = open('phone','w',encoding='utf-8')
    num = input("请输入想要生成的手机号数量")
    for i in range(int(num)):
        start = '1861111'
        rand_num = str(random.randint(1,9999))  #将整型转成字符串类型
    
        new_num = rand_num.zfill(4)  #不足4位数就补零,zfill是字符串的方法
        phone = start + new_num
        f.write(phone+'
    ')  #换行写入到文件
    
    f.close()

    6、直接循环一个文件对象,一行一行处理日志文件:

    f = open(r'H:pythonprojectday4access.log',encoding='utf-8')  #打开文件句柄(文件对象)
    count = 0
    for line in f:   #直接循环一个文件对象的话,每次循环的是文件的每一行
        print(count,line)  #一行一行处理,不然文件太大,内存消耗大
        count += 1
    ip = line.split()[0]  #每一行按空格分隔,取第一个元素即IP
    print(ip)

      【例二】:监控日志文件,如果有攻击咱们的,就把IP加入黑名单

      分析:

        #1、打开日志文件
    #2、把IP地址拿出来 #split(),按空格分隔
    #3、每分钟,判断每一个IP出现的次数,如果大于50次,加入黑名单
    #4、每分钟读一次

      

    all_ip = []
    f = open('access.log',encoding='utf-8')
    for line in f:
        ip = line.split()[0]
        all_ip.append(ip)
        #print(ip)
    
    all_ip_set = set(all_ip)
    #print(all_ip_set)
    for set_ip in all_ip_set:
        if all_ip.count(set_ip) > 50:
            print("攻击频繁的ip有%s" % set_ip)
    f.close()

    【优化】:

    #监控日志文件,如果有攻击咱们的,就把IP加入黑名单
        #1、打开日志文件
        #2、把IP地址拿出来  #split(),按空格分隔
        #3、每分钟,判断每一个IP出现的次数,如果大于50次,加入黑名单
        #4、每分钟读一次
    
    import time  #引入time模块,每分钟读一次
    point = 0   #用于记录每次文件指针的位置
    while True:   #每60s循环一次
        all_ips = []
        f = open(r'H:pythonprojectday4access.log',encoding='utf-8')  #打开文件句柄(文件对象)
        f.seek(point)    #打开文件后,移动文件指针,每次读这一分钟的日志内容
        for line in f:   #直接循环一个文件对象的话,每次循环的是文件的每一行
            ip = line.split()[0]  #每一行按空格分隔,取第一个元素即IP
            all_ips.append(ip)  #将所有的ip放入空列表
        point = f.tell()  #记每次读文件后记录文件指针的位置(以前读过的文件就不需要读了)
    
        all_ips_set = set(all_ips)  #集合去重
        for set_ip in all_ips_set:
            if all_ips.count(set_ip)> 50:   #拿集合里面没有重复的ip到all_ips里面去判断次数是否大于50
                print('应该加入黑名单的ip是:%s' % set_ip)  #拿出集合中大于50次的,执行linux命令加入黑名单
        f.close()
        time.sleep(60)  #暂停60s,每一分钟读一次

    七、fw.flush()强制把内存缓冲区里的数据写到磁盘上

    #有时候写完东西,并没有写到文件里,是因为内存有缓冲区,缓冲区满,才会写到磁盘上

    fw = open('user','w')
    fw.write('www')
    fw.flush()   #强制把缓冲区里的数据写到磁盘上

    八、修改文件的两种方式

      1)方式一简单粗暴直接:replace()

        1、打开一个文件,获取到所有的内容

       2、对内容进行修改

        3、清空原来的内容
        4、把新的内容写进去

      

    f = open('user.txt','a+')  #1、打开一个文件,获取到所有的内容
    f.seek(0)         #a+模式,重置指针位置
    all_str = f.read()  #1、获取到所有的内容---字符串模式
    new_str = all_str.replace('123456','11111')   #2、修改
    f.seek(0)    #3、把文件指针移动到文件最前面,再清空
    f.truncate()      #3、清空原来的内容
    f.write(new_str)  #4、把新的所有的内容重新写进去
    f.close()
    【例三】:将文件的每一行前面都加上一个'sys_',或者将每行的'xyz_',变成'xxx_'
    f = open('a.log','r+',encoding='utf-8') #用w会清空,读不到内容;用r不能写(可以r+)
    f.seek(0)  #指针置0
    all_str = ''
    # all_data = f.readlines()
    # print(all_data)
    for line in f:   #直接读文件是字符串
        #zhangsan,11111
        # new_line =  'xyz_' + line  #将每行的前面加前缀
        new_line = line.replace('xyz_', 'xxx_')  # 将每行的'xyz_',变成'xxx_'
        all_str = all_str + new_line #将修改后的每行放在字符串中
    f.seek(0) #指针置0
    f.truncate() #清空以前的内容
    f.write(all_str)
    f.close()

    >>>syz_zhangsan,123

    syz_lisi,123

    syz_wuang,23245

      2)方式二高效的方式:一行一行修改,然后修改“隐藏文件”的文件名

      # 1打开2个文件aba.txta.txt.bak
      # 2每修改一行a文件的,就写一行到ba.txt.bak)文件
      # 3删掉a文件,把b文件a.txt.bak的名字名成a文件a.txt

    import os
    with open('word.txt',encoding='utf-8')  as fr,open('.word.bak','w',encoding='utf-8') as fw:
        for line in fr:  #循环取a文件
            new_line = line.replace('a','1111')  #替换
            fw.write(new_line)   #循环写入b文件
    os.remove('word.txt')      #删除a文件
    os.rename('.word.bak','word.txt')   #将b改名为a

    九、f.write()f.writeline()的区别:

    f = open('user.txt','w',encoding='utf-8')
    f.write('123456')   #f.write()必须是写一个字符串
    >>>123456
    f.writelines('aaa,bbb,ccc')  #如果是字符串就没必要用writelines()了,因为不用循环,直接用f.write()就行
    >>>aaa,bbb,ccc
    
    f.writelines([
    'aaa','123456','786']) #f.writelines()可以将列表循环写入,writelines会帮我们循环一次 >>>aaa123456786
    相当于f.write()循环写:
    for data in l: f.write(data) f.close()

    zz

  • 相关阅读:
    Swift
    ios高质量博客
    Swift
    UML建模
    Swift
    Swift
    IIS建立.net framework4 应用程序池HTTP 错误 500.21
    zz entity framework vs linq to sql
    zz部署wcf iis
    zzIIS站点中部署WCF项目
  • 原文地址:https://www.cnblogs.com/chenhongl/p/8859279.html
Copyright © 2011-2022 走看看