1.处理文件时的常用操作
处理文件基本操作步骤:
打开文件---->操作文件---->关闭文件
对文件的常用操作:
r,r+,w,w+,a,a+
r:(默认)
-只能读,不能写
-读取的文件不存在,会报错
FileNotFoundError: [Errno 2] No such file or directory:
f = open('/tmp/passwd','r') ## f = open('/tmp/password','r')
print(f.readable())
print(f.writable())
f.close()
对文件进行读操作
f = open('/tmp/passwd','r')
content = f.read()
print(content)
f.close()
r+:
-可以执行读写操作
-文件不存在,报错
-默认情况下,从文件指针所在位置开始写入
f = open('/tmp/passwd','r+')
print(f.readable())
print(f.writable())
f.close
验证r+的读操作
f = open('/tmp/passwd','r+')
content = f.read()
print(content)
f.close
验证r+的写操作
f = open('/tmp/passwd','r+')
print(f.tell())
f.write('python')
print(f.tell())
f.close
从指针位置0处开始写入python,写之后文件指针位置为6
查看原始文件,可以看到已经成功写入,将原始的root覆盖
w:
-write only只能写
-会清空文件之前的内容
-文件不存在,不会报错,会创建新的文件并写入
f = open('/tmp/passwd','w')
print(f.readable())
print(f.writable())
f.close()
验证w的写操作
f = open('/tmp/passwd','w')
print(f.tell())
f.write('redhat')
print(f.tell())
f.close()
清空文件之前的内容,写入新内容,从指针位置0处开始写入redhat,写之后文件指针位置为6
w+:
-rw可读写
-会清空文件内容
-文件不存在,不报错,会创建新的文件
f = open('/tmp/passwd','w+')
print(f.readable())
print(f.writable())
f.close()
验证w+可读
f = open('/tmp/passwd','w+')
content = f.read()
print(content)
f.close()
验证w+的写操作
f = open('/tmp/passwd','w+')
print(f.tell())
f.write('python')
print(f.tell())
f.close()
清空文件之前的内容,写入新内容,从指针位置0处开始写入python,写之后文件指针位置为6
a:
-write only只能写
-不会清空文件内容
-文件不存在,会报错
f = open('/tmp/passwd','a')
print(f.readable())
print(f.writable())
f.close()
验证a的写操作
f = open('/tmp/passwd','a')
print(f.tell())
f.write('kkxili')
print(f.tell())
f.close()
从文件指针的最后一个位置写入
a+:
-rw可读写
-文件不存在,不报错
-不会清空文件内容
f = open('/tmp/passwd','a+')
print(f.readable())
print(f.writable())
f.close()
验证a+可读
f = open('/tmp/passwd','a+')
content = f.read()
print(content)
f.close()
验证w+的写操作
f = open('/tmp/passwd','a+')
print(f.tell())
f.write('budaow')
print(f.tell())
f.close()
从文件指针的最后一个位置写入
2.文件读取的多种方式
read():读取文件内容,返回文件的所有内容(一次性读取文件的全部内容)
readline():一行一行的读取文件的内容
readlines():读取文件内容,返回一个列表,列表里的元素分别为文件每行的内容
read()方式
f = open('/tmp/passwd','r+')
print(f.read())
f.close()
readline()方式
f = open('/tmp/passwd','r+')
print(f.readline())
f.close()
对文件一行一行读取,默认读取第一行
readlines()方式
f = open('/tmp/passwd','r+')
print(f.readlines())
f.close()
将文件的内容以列表的形式返回,每行为一个列表元素,并且有换行符
指定读取文件中的几个字符方式来读取
f = open('/tmp/passwd','r+')
print(f.read(4))
f.close()
readline()方式对文件一行一行读取,默认读取第一行
f = open('/tmp/passwd','r+')
print(f.readline(),end='')
f.close()
3.seek方法移动指针位置
python中可以使用seek()移动文件指针到指定位置,然后进行读/写
seek第一个参数是偏移量:>0,代表向右移动;<0,代表向左移动
seek第二个参数是:
0:移动指针到文件开头
1:不移动指针
2:移动指针到末尾
指针当前所在位置
f = open('/tmp/passwd','r+')
print(f.tell()) ##打印文件指针当前所在位置
f.close()
不移动文件指针
f = open('/tmp/passwd','r+')
print(f.tell())
f.seek(0,1)
print(f.tell())
f.close()
将文件指针移动到第一个位置
f = open('/tmp/passwd','r+')
print(f.tell())
f.seek(0,0)
print(f.tell())
f.close()
将文件指针移动到最后一个位置
f = open('/tmp/passwd','r+')
print(f.tell())
f.seek(0,2)
print(f.tell())
f.close()
4.非纯文本文件(二进制文件)的读取
建立一个目录,将非文本文件(图片)复制到此目录下,图片可以被查看
复制的方式读取图片
把f1读到的图片写到f2里面去,生成新的二进制文件test.jpg
5.上下文管理器with用法
使用之前的打开文件方式需要在程序末尾使用f.close()来关闭文件,这样的方法不方便,如果忘记写关闭文件语句,执行程序的时候就会报错
现在使用with open(’/tmp/passwd’) as f:打开文件,执行操作以后会自动关闭文件
使用with打开 '/tmp/passwd '文件,把它命名为f
使用with时,执行完with语句后会自动关闭文件对象,不用再去手动关闭
使用with读取多个文件对象
下示例为复制当前文件来做此实验,也可另读取一份文件
把f1读到的内容写到f2里面,这时指针所在位置是文件末位,此时直接读取f2内容是显示为空,所以应将指针移动到文件的第一个位置,才可以读取到内容
6.应用练习
练习一:
创建文件data.txt,文件共100000行,每行存放一个1~100之间的整数
import random
f = open('data.txt','w+')
for i in range(100000):
f.write(str(random.randint(1,100)) + '\n')
f.seek(0)
print(f.read())
f.close()
练习二:
京东二面笔试题
1.生成一个大文件ips.txt,要求1200行, 每行随机为172.25.254.0/24段的ip;
2. 读取ips.txt文件统计这个文件中ip出现频率排前10的ip;
import random
def create_ip_file(filename):
ip = ['172.25.254.' + str(i) for i in range(1,255)]
# print(random.sample(ip,1))
with open(filename,'a+') as f:
for i in range(1200):
f.write(random.sample(ip,1)[0] + '\n')
create_ip_file('ips.txt')
def sorted_by_ip(filename,count=10):
ips_dict = dict()
with open(filename) as f:
for ip in f:
ip = ip.strip()
if ip in ips_dict:
ips_dict[ip] += 1
else:
ips_dict[ip] = 1
sorted_ip = sorted(ips_dict.items(),key=lambda x:x[1],reverse=True)[:count]
return sorted_ip
print(sorted_by_ip('ips.txt'))
练习三:
1.在当前目录新建目录img, 里面包含100个文件, 100个文件名各不相同(X4G5.png)
import random
import string
import os
from os.path import splitext
def gen_code(len=4):
li = random.sample(string.ascii_letters+string.digits,len)
return ''.join(li)
def create_files():
li = [gen_code() for i in range(100)]
os.mkdir('img')
for i in li:
os.mknod('img/' + i + '.png')
create_files()
2.将当前img目录所有以.png结尾的后缀名改为.jpg
import string
import os
from os.path import splitext
def gen_code(len=4):
li = random.sample(string.ascii_letters+string.digits,len)
return ''.join(li)
def create_files():
li = [gen_code() for i in range(100)]
os.mkdir('img')
for i in li:
os.mknod('img/' + i + '.png')
#create_files()
def modify_suffix(dirname,old_suffix,new_suffix): ##找出以png结尾的文件名
# pngfile = [filename for filename in os.listdir(dirname) if filename.endswith(old_suffix))
pngfile = filter(lambda filename:filename.endswith(old_suffix),os.listdir(dirname))
##分离文件名和后缀
basefiles = [os.path.splitext(filename)[0] for filename in pngfile]
## 文件重命名
for filename in basefiles:
oldname = os.path.join(dirname,filename + old_suffix)
newname = os.path.join(dirname,filename + new_suffix)
os.rename(oldname,newname)
print('%s重命名为%s成功' %(oldname,newname))
modify_suffix('img','.png','.jpg')
练习四:
生成100个MAC地址并写入文件中,MAC地址前6位(16进制)为01-AF-3B
01-AF-3B
01-AF-3B-xx
01-AF-3B-xx-xx
01-AF-3B-xx-xx-xx
import random
import string
def create_mac():
MAC = '01-AF-3B'
hex_num = string.hexdigits ##生成十六进制的数
for i in range(3): ##三位
n = random.sample(hex_num,2) ##从生成十六进制的数中选取两个进行拼接
sn = '-' + ''.join(n).upper() ##字母是大写,进行拼接
MAC += sn
return MAC ##返回mac地址
##主函数,随机生成100个mac地址
def main():
with open('mac.txt','w') as f:
for i in range(100):
mac = create_mac()
print(mac)
f.write(mac + '\n')
main()