zoukankan      html  css  js  c++  java
  • Python3 从零单排2_文件读写&集合

      文件操作其实和我们日常处理文件一样的,先打开文件,然后操作,最后保存关闭,在python里就是这三步骤:

      1、打开文件获取文件的句柄,句柄就理解为这个文件
      2、通过文件句柄操作文件
      3、关闭文件

      文件操作有以下三个模式:

      r:读模式【可读; 不可写,不存在则报错】
      w:写模式【不可读;不存在则创建;存在则删除内容】  //注意:只要写了w模式,不论后面跟的啥,文件不存在则创建,存在则清空文件内容,然后再写。
      a:追加模式【不可读; 不存在则创建;存在则只追加内容】//注意:追加内容是在最后的指针位置开始写,所以一般这样的话,要先f.seek(0),回到文件的第一行第一个字节的位置。

      在模式后面跟上'+'号,则表示同时可以读写文件:

      r+:【可读、可写;可追加,如果打开的文件不存在的话,会报错】
      w+:【写读模式,使用w+的话,已经存在的文件内容会被清空,可以读到已经写的文件内容】
      a+:【追加读写模式,不存在则创建;存在则只追加内容;】

      在模式后面跟上'b',则表示处理二进制文件:rb,wb,ab 

      1.读取文件

    f=open('a.txt','r',encoding='utf-8')#mac下不需要设置字符类型,操作系统默认字符类型是utf-8;windows需要设置这个字符类型,系统默认的是gbk字符类型
    print(f.read())#读取文件内容,返回的是一个字符串,当文件太大时,不建议这样操作,防止内存撑爆
    print(f.readlines())#读取文件内容,返回的是一个list,list每个元素是文件的每一行
    print(f.readline())#每次只读取一行
    f.close()
    
    #for循环文件句柄是通过行循环文件的内容,这样做的好处是当文件太大时,防止内存撑爆
    f=open('a.txt','r',encoding='utf-8')
    print(f.read())
    i=1
    for content in f:
        print('第{line}行:{content}'.format(line=i,content=content))
        i+=1
    f.close()
    
    #在不确定文件的编码前,读写文件的时候可能会存在乱码,chardet模块可以分析文件得到一个编码,它是根据编码特性来分析的,
    #比如ascii码是一个字节,高位基本为0;utf-8编码中文的时候会出现两个相邻字节的高位都为1;所以它可以根据字符编码的特性,得到一个概率性的编码,一般都比较靠谱
    import chardet f = open('a.txt','rb') # 以二进制打开一个文件对象 res = chardet.detect(f.read()) # res = {'language': '', 'encoding': 'ascii', 'confidence': 1.0} 这样就可以通过 res{'encoding'} 拿到文件编码 f.close()

      2.写文件

    f=open('a.txt','w',encoding='utf-8')
    f.write('hahaha')#只能写字符串,不能是列表
    f.writelines(['aaa','bbb','ccc'])#写的是可迭代对象 比如list
    f=open('a.txt','r+',encoding='utf-8')#r+读写模式,只要有r权限在,当文件不存在时都会报错
    f.write('1111')#读写模式下,写数据的时候会从第一行开始写,替换之前文件里第一行的内容前n个字符(n为写入的字符长度)
    f=open('a.txt','w+',encoding='utf-8')
    f.write('asd')
    f.tell() # 返回当前文件光标位置
    f.flush() #将文件内容从内存缓冲到硬盘,该方法是怕在操作文件过程中断点,导致内存文件丢失。
    f.seek(0)#seek(n),移动指针到n位置,0为首位
    print(f.read())

      3.追加模式

      追加模式跟上面的差不多,要注意的地方是:追加内容是在最后的指针位置开始写,所以一般这样的话,要先f.seek(0),回到文件的第一行第一个字节的位置,要时刻关注指针的位置。

    f=open('a.txt','a+',encoding='utf-8')
    f.seek(0)
    print(f.read())
    i=1
    for content in f:
        print('第{line}行:{content}'.format(line=i,content=content))
        i+=1
    f.close()

      4.with方法操作文件

      with方法操作文件,可以少些close文件关闭方法,这个with会自动关闭文件,不需要我们自己再重复写了,其他用法一样。

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

      

      5.文件修改

      有一个细节,日常修改文件的时候,打开文件的时候,会产生一个隐藏文件,其实我们修改的内容过程是这样的:打开文件->在隐藏的那个文件上增删改文件内容->保存隐藏文件->之前的文件删除->隐藏文件重命名开始的文件名称,是这样一个过程,那为啥会是这样的呢?因为硬盘的原理导致,就是一个文件在硬盘里占的空间大小已经定死了,你再在原来的文件基础上进行修改,内容变短会导致硬盘里多出来的部分一直不可用,内容变短,存储时会将多出来的内容截取,导致文件内容丢失。

      那么我们要修改文件时,其实是一样的: 

      1.读模式打开待修改的文件A
      2.修改读取到的内容
      3.将修改后的内容写进新的文件B
      4.删除文件A
      5.将文件B重命名为A

    import os
    with open('阳光总在风雨后.txt','r',encoding='utf-8') as f1,open('a.txt','w',encoding='utf-8') as f2:
        for line in f1:
            new_line=line.replace('阳光','彩虹')
            f2.write(new_line)
    os.remove('阳光总在风雨后.txt')
    os.rename('a.txt','阳光总在风雨后.txt')

      

      当然还有另外一种方法,不需要删文件,直接清空文件即可

    f1=open('阳光总在风雨后.txt','a+',encoding='utf-8')
    f1.seek(0)
    res=f1.read()
    new_content=res.replace('彩虹','阳光')
    f1.seek(0)
    f1.truncate()
    f1.write(new_content)
    f1.close()

      6.写一个监控服务器的脚本,每分钟运行一次,这分钟内如果ip访问次数超过200,则计入黑名单。

      log日志文件格式如下:

      58.19.57.99 - - [04/Jun/2017:05:23:30 +0800] "GET / HTTP/1.0" 302 161 "-" "Wget/1.12 (linux-gnu)" "-"
      58.19.57.99 - - [04/Jun/2017:05:23:30 +0800] "GET /blog HTTP/1.0" 301 233 "-" "Wget/1.12 (linux-gnu)" "-"

    import time
    pin=0
    while True:
        with open('access.log','rb') as f:
            ip_list=[]
            f.seek(pin)
            for line in f:
                ip=line.decode().split()[0]
                print(ip)
                ip_list.append(ip)
            for ip in set(ip_list):
                if ip_list.count(ip)>=200:
                    print('黑名单:%s,访问次数:%d'%(ip,ip_list.count(ip)))
            pin=f.tell()
            print(pin)
            time.sleep(5)
  • 相关阅读:
    android 项目学习随笔十五(ShareSDK开放平台)
    android 项目学习随笔十四(WebView)
    android 项目学习随笔十三(ListView实现ITEM点击事件,将已读状态持久化到本地)
    android 项目学习随笔十二(ListView加脚布局)
    android 项目学习随笔十一(ListView下拉刷新提示)
    android 项目学习随笔十(自定义ProgressBar)
    android 项目学习随笔九(ListView加头布局)
    android 项目学习随笔八(xUtils的BitmapUtils模块)
    android 项目学习随笔七(ViewPagerIndicator与ViewPager)
    android 项目学习随笔六(网络缓存)
  • 原文地址:https://www.cnblogs.com/znyyy/p/8067531.html
Copyright © 2011-2022 走看看