chenhongl

导航

 
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())  #把文件的每一行用\n换行,放到一个list里面
 f.write('sss')  #报错,默认读模式,不能写
④f.close()  #每次都要关闭文件

打开绝对路径的方式:

  f = open(r'H:\pythonproject\day4\word.txt')

 

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

1、读模式(默认) r  读写模式r+  
  f = open('word.txt')
  1)r/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读的:\n',f.read()) #文件指针到末尾
print('readline读的:\n',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+'\n')  #换行写入到文件

f.close()

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

f = open(r'H:\pythonproject\day4\access.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:\pythonproject\day4\access.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

posted on 2018-04-16 23:36  chenhongl  阅读(225)  评论(0)    收藏  举报