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

    一、文件操作步骤

    1、有个文件

    2、打开文件

    3、操作文件:读、写

    4、关闭文件

    f=open('users.txt','a+') #打开文件,有中文加上encoding='utf-8',不加会报错【如果文件在当前目录下可以直接写文件名,如不没在,需要些绝对路径】
    with open('user.txt', 'a+') as f #也可以这样打开文件,会自动关闭
    f.flush() 
    f.seek(0) #指针从头开始,-1是不能移动到最后
    print(f.read()) #读取内容
    f.write('hhh,1234
    ') #写入内容
    print(f.read()) 
    f.close() #关闭文件
    
    #结果:
    #123,abc
    #456,def
    #123,abc
    #456,def
    #hhh,1234

    * 文件名称前面加上 r,遇到 /n 就不会转译成换行符了,把 / 加成两个斜杠也可以,只是读一下,如:f = open(r'c:users iushuaia.txt')、f = open(r'c:users\niushuai\a.txt')

    * 写入的只能是字符串,不能是别的类型 

    打开文件第一种格式:

    f=open('a.txt','r')
    #       文件名  模式   

    打开文件第一种格式:

    with open('a.txt') as f:
    #       文件名       f是变量名

    * 两种打开方式区别:第一种需要方式  .close()关闭下,第二种方式不需要  .close()关闭

    二、文件模式

    r ----------只读模式:打开文件不存在的话,会报错;使用.write()方法时报错。

    w----------只写模式:打开文件不存在的话,会自动新建文件;会清空原来文件的内容;使用.read()方法时报错。

    a-----------追加写模式:打开文件不存在的话,会自动新建文件;使用.read()方法时报错。

    3种模式的增强模式:

    r+----------读写模式:打开文件不存在的话,会报错;使用.write()方法时不报错;写的话,会覆盖原来的内容。

    w+---------写读模式:打开文件不存在的话,会自动新建文件;会清空原来文件的内容;使用.read()方法时不报错。

    a+----------追加写读模式:打开文件不存在的话,会自动新建文件,使用.read()方法时不报错。

    f=open('user.txt','w',encoding='utf-8') 
    f.seek(0)
    print(f.read())
    f.write('hahah')
    f.close()

    写入东西时,想要换行写入,在后边加上‘ ’,在次写入就会另起一行

    3种模式的二进制模式:

    rb-----------二进制读模式:当文件不再是文本文件时,是.mp3、.mp4、.jpg这些格式时,就不能用r模式了,使用b模式。

    wb----------二进制写模式:处理非文本文件的写模式。

    ab-----------二进制追加模式。

    rb+----------二进制读写模式。

    wb+---------二进制写读模式。

    ab+----------二进制追加写读模式。

    res=open('pic.jpg','rb')
    print(res.read())
    #将网上一个图片爬到本地
    import requests
    url='https://www.baidu.com/link?url=s686w7Nxr94erC-cd6-ZOC5PaXWBJDtcfF1htryXmXRnZpkgyfBMkVZ7Fcq7Qfdy6nmV1JDMv3YX_l0ut8BvGDtjWI7jOyhcl79H_L0PI8utCERBrVV7UFceVPxfur5et_r-Pj3YRLNkVKPInUMnbYa3kfagL46mzIfX6tnUYIYYfQa1N6Hhgs857Vx0Ui6CfSdF5DULEfB8DpCyEfre2cbasF5o5H8-p2A6udIWysbBJ4aBO6QYS3C82UYmBLokjwcYeklVpPdofnr_tOhduSDGwdoa0Ei8tw83cKorVuuvmbpedVEnQ5_vZ3b8Ua9imvq5HDp5JF6evua9-QyNqR-lc6J_wRovVZ5QwKfyHDSU3K16dkZJbGi-ZKuo7-vy85dPBA2g56OVq4HhrDoba6DDfo1P_LFHxdJSNDpgbvEEaf2G9NgZH9qGqEBnKeLKNtE5nEuqFXOlt4OUhbCHuonxkaRREvEeufcfNQUuFmhcVF0D1tYz1qUmgvObDuc4M1COk0o1UjZgvn_DCXgV-_o6YILiQyPm6QTcA0H7JwqYxW25eNTGpFHnnNEVOUCjnvcKd4CqNe4Nbpps1BNwLaLyFPY2472R2XX6L7EQIdnUSZxL5eGXJp550h8t5gZF&timg=https%3A%2F%2Fss0.bdstatic.com%2F94oJfD_bAAcT8t7mm9GUKT-xh_%2Ftimg%3Fimage%26quality%3D100%26size%3Db4000_4000%26sec%3D1536217084%26di%3D6b76fffb192e350ccfe6df6867e068d5%26src%3Dhttp%3A%2F%2Fn1.itc.cn%2Fimg8%2Fwb%2Frecom%2F2016%2F08%2F12%2F147094106594748751.JPEG&click_t=1536218169977&s_info=1203_558&wd=&eqid=d57bf8350003ab56000000035b90cffc'
    res=requests.get(url,verify=False).content
    f=open('333.jpg','wb')
    f.write(res)

    三、文件读--------r

    获取文件里面的所有内容:

    (1).read()方法,获取到文件的全部内容

    =open('users.txt')
    print('',f.read())#获取到文件里面所有的内容
    print('第二次读',f.read())#读不到内容了,因为文件指针在第一次读完的末尾

    (2).readlines()方法,读取文件里面所有的内容,把读取到内容放到list里面,每行的内容是list的一个元素

    f=open('users.txt')
    print(f.readlines())#获取到文件里的所有内容,并转为list,把每一行当做list里的每一个元素

    (3).readline()方法,一次只读一行,调一次读第一行,调第二次只读第二行

    f=open('users.txt')
    print(f.readline())#获取文件里的所有内容,并将内容转成list,每次只读一行

    (4)总结

    • read()、readlines()、readline()都是读完后,指针到读完的末尾
    • redlines()自动将文件内容转为list,把每一行当做list里的一个元素
    • readline()每次只读文件里的一行
    • readline()应用:由于计算机处理文件时都是先从磁盘每次读到内存里,再从内存读入到CPU里;取数据是CPU先从内存里取,再又内存到磁盘里取的过程,如果一次性读的内容过多,有可能撑爆内存,因此这时候如果一行一行读代码,内存占用小,执行效率就高了,这时使用readline()方法
    • 由于计算机处理文件时都是先从磁盘每次读到内存里,再从内存读入到CPU里;取数据是CPU先从内存里取,再又内存到磁盘里取的过程,如果每次有一点东西需要写入都会运行一次,就会影响嗲性能,所以,就会当所需要写入的东西比较少时,就会先保存到缓冲区,写入的东西不会立即写入,这时,我们可以使用 .flush(),就会刷新缓冲区,直接写到磁盘里面

    四、文件写--------w

    (1).write()方法,只可以传字符串

    f=open('users.txt','w')
    a=['username1,12345
    ','username2,123456
    ']
    for i in a:
        f.write(i)#把list里的元素一个一个写到文件里

    (2).writelines()方法,可以传list【批量写入】

    f.writelines(a)#list里的元素循环写到文件里,自动执行循环取元素的操作,循环一次写入一次
    #字符串也能循环
    u='abc,223'
    f.writelines(u)#自动执行循环取字母的操作,没必要,因此写入字符串的话不必用writelines(),用write()即可

    (3)总结

    • 只写字符串的时候用write(),写list、set用writelines()。

    五、文件指针

    (1).seek()——指定文件指针的位置

    f=open('user.txt','w',encoding='utf-8') 
    f.seek(0)  #括号里面是0,文件指针就会在一开始的位置
    print(f.read())
    f.write('hahah')
    f.close()

    (2).tell()——当前文件指针的位置

    f=open('user.txt','w',encoding='utf-8') 
    point = f.tell()  #记录下当前文件指针的位置
    print(f.read())
    f.write('hahah')
    f.close()

     六、修改文件

    #1、简单直接粗暴的方法
    f = open('a.txt','a+',encoding='utf-8')
    f.seek(0)
    result = f.read()
    new_result = result.replace('abc','ABC') #把文件里面的 abc 修改为:ABC
    f.seek(0)
    f.truncate() #清空文件内容
    f.write(new_result) #重新写入
    f.close()
    #2、第二种是逐行修改
    import os
    f1 = open('a.txt',encoding='utf-8')
    f2 = open('a2.txt','w',encoding='utf-8')
    for line in f1: #循环读到的每一行
        new_line = line.replace('','1')  #把每一行的 一 替换为 1
        f2.write(new_line) # 重新写入
    f1.close()
    f2.close()
    os.remove('a.txt') #把a.txt删除
    os.rename('a2.txt','a.txt') #把文件a2.txt名字更改为a.txt

     七、清空文件里内容

    • truncate()

    with open('user.txt','a+')as f:
        f.truncate() 

     八、应用

    1、高效处理文件:

    第一种方式while循环:

    #高效处理文件
    f=open('users.txt',encoding='utf-8')#不指定模式,默认是r
    while True:#由于.readline()模式是一行一行读,如果不知道一共多少行,可以采用判断最后一行是否是空串的方法,如果是,则到最后一行了
        line=f.realine()
        if line!='':
           print('line:',line) 
        else:
        print('文件内容都读完了,结束了')
           break     

    第二种方式for循环:

    f=open('users.txt',encoding='utf-8')#打开这个文件就叫文件对象/文件句柄
    for line in f:#使用for循环,直接取的就是文件里每一行的内容,当读入为空时自动结束循环。
        print(line)
    • for循环不需要读,即没有.readline()方法,内置读操作了。

    2、监控日志:

    207.46.13.77 - - [04/Jun/2017:08:20:57 +0800] "GET /people/60 HTTP/1.1" 200 11396 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)" "-"
    66.249.75.29 - - [04/Jun/2017:08:22:06 +0800] "GET /bbs/forum.php?mod=forumdisplay&fid=705&filter=hot HTTP/1.1" 200 17496 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "-"
    123.125.71.31 - - [04/Jun/2017:08:22:17 +0800] "GET /static/blog/img/default.ico HTTP/1.1" 302 161 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    123.125.71.58 - - [04/Jun/2017:08:22:18 +0800] "GET /blog HTTP/1.1" 301 233 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    123.125.71.39 - - [04/Jun/2017:08:22:19 +0800] "GET /blog/ HTTP/1.1" 200 38330 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    220.181.108.160 - - [04/Jun/2017:08:22:19 +0800] "GET /static/blog/img/ HTTP/1.1" 302 161 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    123.125.71.36 - - [04/Jun/2017:08:22:19 +0800] "GET /blog HTTP/1.1" 301 233 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    123.125.71.31 - - [04/Jun/2017:08:22:20 +0800] "GET /blog/ HTTP/1.1" 200 38330 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    66.249.69.65 - - [04/Jun/2017:08:25:53 +0800] "GET /bbs/home.php?mod=space&username=1fcxtest003 HTTP/1.1" 200 12498 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "-"
    220.181.108.160 - - [04/Jun/2017:08:28:51 +0800] "GET /bbs/forum.php?mod=forumdisplay&fid=550 HTTP/1.1" 200 17113 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" "-"
    66.249.69.95 - - [04/Jun/2017:08:29:40 +0800] "GET /bbs/home.php?mod=space&username=MorganQE004 HTTP/1.1" 200 12478 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" "-"
    113.5.2.61 - - [04/Jun/2017:08:32:20 +0800] "GET /blog/wp-content/themes/QQ/js/player.js?ver=1.0.0 HTTP/1.1" 304 0 "http://www.nnzhp.cn/blog/" "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1" "-"
    113.5.2.61 - - [04/Jun/2017:08:32:20 +0800] "GET /blog/wp-content/themes/QQ/js/mousewheel.js?ver=1.0.0 HTTP/1.1" 304 0 "http://www.nnzhp.cn/blog/" "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1" "-"
    '''
    题目:
    #1、要从日志里面找到1分钟之内访问次数超过20次的ip
    #2、每分钟都运行一次
    '''
    #分析:
    #1、读取文件内容,获取到ip地址
    #2、把每个ip地址存起来[]?{}
    #3、判断ip访问次数是否超过20次
    #4、加入黑名单print
    
    import time
    point=0#初始的位置
    while True:
        ips={}
        f=open('access.log',encoding='utf-8') 
        f.seek(point)
        for line in f:#循环取文件里面每行数据
            ip=line.split()[0]#.split()自动将字符串转成list;按照空格分割,取第一个元素就是ip
            if ip in ips:#判断这个ip是否存在
                ips[ip]+=1#如果存在的话,次数加+1
            else:
                ips[ip]=1#如果不存在ip,ip的次数就加+1
        print(ips)
        point=f.tell()#记录文件指针位置,加入这个下次循环时,不会再次从一开始位置循环
        f.close()
    
        for ip,count in ips.items():#循环这个字典,判断次数大于20的
            if count>=20:
                print('%s 加入黑名单'%ip)
        time.sleep(60)
    #和上边三行代码效果一样
    for ip in ips:
    if ips.get(ip)>100:
    print('访问次数超过20次的IP是%s'%ip)
    • 为什么ip要存在字典而不是列表里?

    1)每次循环都要再统计一次ip;

    2)ip越多list越大,执行效率低。


     * 文件读出来的都是字符串

  • 相关阅读:
    mojoportal学习——文章翻译之SmartCombo
    windows froms 程序打包 (转载)
    [笔记]LCD1602 Display Experiment
    [笔记] JLink V8固件烧录指导
    [笔记]NiosII之Count Binary
    [笔记]DE2115 LCD1602字符的显示
    [笔记]What is HDBaseT
    [笔记]Inrush Current Case
    [笔记]远传中继的实现
    [笔记]RunningLED Experiment
  • 原文地址:https://www.cnblogs.com/brf-test/p/11523267.html
Copyright © 2011-2022 走看看