1.Python下的文件操作基础知识
<1>读写文件(io操作的步骤):
(1)打开文件,或者新建一个文件;(2)读/写数据;
(3)关闭文件
<2>打开文件,或者新建一个文件:(open,默认模式是r,也可以认为是mode='r')
在python中,使用open函数,可以打开一个已经存在的文件,或者新建一个新文件。
open(文件名 访问模式)
其中open 后面跟的文件名/文件路径一般都是字符串。open的作用类似于vim命令(文件存在——打开;文件不存在——新建)。
说明:
访问模式 | 说明 |
r | 以只读方式打开文件,文件的指针会放在文件的开头,这是默认模式 |
w | 打开一个新的文件只用于写入,如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件进行写入 |
a | 打开一个文件用于追加。如果文件已存在,文件指针将会放在文件的末尾,也就是说,新的内容将会被写入到已有内容之后,如果该文件不存在,则新建文件进行写入 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头,这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件存在则将其覆盖。如果该文件不存在,创建新文件进行写入 |
ab | 以二进制格式打开一个文件用于追加。如果文件已存在,文件指针将会放在文件的末尾,也就是说,新的内容将会被写入到已有内容之后,如果该文件不存在,则新建文件进行写入 |
r+ | 相当于r和在文件的开头写入数据(即覆盖文件开头的数据)。这也是r+和r的区别 |
w+ | 相当于r和w。这也是w+与w的区别 |
a+ | 相当于r和a。这也是a+和a的区别 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头 |
wb+ | 以二进制格式打开一个文件用于读写。如果文件已存在,将其覆盖。如果文件不存在,则创建文件 |
ab+ | 以二进制格式打开一个文件用于追加。如果文件已存在,文件指针将会放在文件的末尾。如果文件不存在,创建文件用于读写。 |
其中涉及三点:1.可读/可写;2.指针的概念(控制读写数据的位置和顺序的);3.二进制格式:(文件分为两种:一种是二进制文件(不能通过某种编码解析成字符);另外一种是文本文件(能够通过某种编码解析成字符))
在当前目录下创建test1.txt文件(即相对路径)
f=open('test1.txt','w') #在当前目录下创建test1.txt文件
pass
f.close() #关闭文件
在/home/kiosk/文件夹下创建test1.txt文件(即绝对路径)
f=open('/home/kiosk/test1.txt','w') #在/home/kiosk目录下创建test1.txt文件
pass
f.close()
<3>关闭文件:(close)
close()
<4>文件的操作(读/写数据)
(1)写入数据(write)
使用write()可以完成向文件写入数据
(2)读取数据(read)
使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位为字节),
如果没有传入num,那么就表示读取文件的所有数据
(3)读取数据(readlines)
就像read没有参数一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,
并且返回的是一个列表,其中每一行的数据为一个元素。
(4)读取数据(readline)
readline用于读取一行
f=open('/tmp/passwd') #以只读模式打开/tmp目录下的passwd文件
content=f.read() #读取文件
print(content)
print(f.readable()) #判断文件是否可读
print(f.writable()) #判断文件是否可写
f.close() #文件操作之后,必须关闭文件
#输出为:
/tmp/passwd文件中的所有内容
True
False
f=open('/tmp/passwd') #以只读模式打开/tmp目录下的passwd文件
content=f.read(5) #读取文件的5个字节
print(content)
f.close() #文件操作之后,必须关闭文件
#输出为:
'root:'
True
False
f=open('/tmp/passwd') #以只读模式打开/tmp目录下的passwd文件
content=f.readline() #读取文件的一行
print(content)
f.close() #文件操作之后,必须关闭文件
#输出为
/tmp/passwd文件中的一行内容
True
False
f=open('/tmp/passwd') #以只读模式打开/tmp目录下的passwd文件
content=f.readlines() #读取文件的全部内容,以列表的形式呈现
print(content)
f.close() #文件操作之后,必须关闭文件
#输出为
/tmp/passwd文件中的所有内容,并且以列表的形式呈现
True
False
f=open('/tmp/passwd','w') #以只读模式打开/tmp目录下的passwd文件。
也可以写成f=open('/tmp/passwd',mode='w')
f.write('hello') #向文件/etc/passwd文件中写入内容'hello'
f.close() #文件操作之后,必须关闭文件
#因为是以'w'的模式打开/tmp/passwd文件的,所以将/tmp/passwd文件覆盖,再写入'hello'这句话
<5>
(1)获取当前读写的位置(tell)
在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取
(2)定位到某个位置(seek)
如果在读写文件的过程中,需要从另外一个位置进行操作的话,可以使用seek()。
seek(offset,from)有2个参数
offset:偏移量
from:方向
其中偏移量小于0,表示左移(比如-1表示左移1位);偏移量为0,表示不动;偏移量大于0,表示右移(比如1表示右移1位);其中from表示方向(0表示文件开头;1表示当前位置;2表示文件末尾)。
f=open('/tmp/passwd',mode='r') #以只读模式打开/tmp目录下的passwd文件
print(f.tell()) #输出0
content=f.read()
print(content)
print(f.tell()) #输出2287,即文件的末尾
f.close() #文件操作之后,必须关闭文件
f=open('/tmp/passwd',mode='r') #以只读模式打开/tmp目录下的passwd文件
print(f.tell()) #输出0
content=f.read()
print(content)
print(f.tell()) #输出2287,即文件的末尾
f.seek(1,0) #表示将指针移到文件的开头,再向右移一个字节(即移到字节为1的位置
print(f.tell()) #输出1
print(f.read()) #输出第一个字节后面所有的文件内容
f.close() #文件操作之后,必须关闭文件
<6>上下文管理器:打开文件,执行完with语句内容之后,自动关闭文件对象
'''
案例:将/tmp/passwd文件中的内容复制到/tmp/passwdbackup文件中
'''
#同时打开两个文件对象
with open('/tmp/passwd') as f1,\
open('/tmp/passwdbackup','w+') as f2:
#将第一个文件的内容写入到第二个文件中
f2.write(f1.read())
#移动指针到文件最开始
f2.seek(0,0)
print(f2.read())
2.文件操作练习
<1>练习一:
创建文件data.txt,文件共100000行,每行存放一个1~100之间
的整数,写完后读取文件内容 。
import random
with open('data.txt','w+') as f:
for i in range(100000):
f.write(str(random.randint(1,100))+'\n')
f.seek(0,0)
print(f.read())
<2>练习二:去空格(readlines读出来的列表中含有\n空格)
f=open('/tmp/passwd','rb')
# print([line.strip() for line in f.readlines()])
print(list(map(lambda x:x.strip(),f.readlines())))
f.close()
import os(python自带的模块)
1.文件系统的基本操作:
<1>os.name():返回操作系统的类型:windows返回'nt';Linux返回'posix'
print(os.name) #输出posix
<2>os.uname():返回操作系统的详细信息
print(os.uname())
#输出posix.uname_result(sysname='Linux', nodename='foundation41.ilt.example.com', release='3.10.0-514.el7.x86_64', version='#1 SMP Wed Oct 19 11:24:13 EDT 2016', machine='x86_64')
print(os.uname().sysname) #输出Linux
<3>os.environ:返回系统的环境变量
print(os.environ) #输出......
通过key值获取环境变量对应的value值
print(os.environ.get('HOME')) #输出/home/kiosk
print(os.environ.get('haha')) #输出None
print(os.environ.get('haha',1)) #输出1
<4>os.getpwd():得到当前工作的目录
print( os.getcwd())#输出/home/kiosk/PycharmProjects/xin
<5>os.listdir():列出指定目录下的所有文件名和目录名:
并以列表的形式给出。
值的注意的是:当不给定目录时,默认列出的是当前目录下的全部内容。
print(os.listdir('/mnt')) #输出['create.sh']
<6>os.chdir():改变目录到指定目录
os.chdir('/mnt')
print(os.listdir()) #输出['create.sh']
<7>os.mkdir():创建目录;
注意:这样只能建立一层,想要递归建立目录可用:os.makedirs(x/y/z)
os.rmdir():删除目录(只针对空目录)
print(os.mkdir('img')) #输出None,但是在当前目录下新建了一个img目录
os.makedirs('/hello/world') #递归建立目录(/hello/world)
os.rmdir('img')
<8>os.mknod():创建文件;os.remove():删除文件
os.mknod('file')
os.remove('file')
<9>os.rename(需要修改的文件名,新的文件名):文件重命名
# os.mknod('xin.txt')
os.rename('xin.txt','chen.txt')
<10>os.path.isfile():判断对象是否为文件。是返回True,否则返回False
值的注意的是:当文件不存在时,也返回False。
print(os.path.isfile('chen.txt')) #输出True(因为chen.txt存在,且为文件,所以返回True)
print(os.path.isfile('xin.txt')) #输出False(因为xin.txt不存在,所以返回False)
<11>os.path.isdir():判断对象是否为目录。是返回True,否则返回False
值的注意的是:当目录不存在时,也返回False。
print(os.path.isdir('字符串')) #输出True(因为字符串存在,且为目录,所以返回True)
print(os.path.isdir('haha')) #输出False(因为haha不存在,所以返回False)
<12>os.path.isexsits():判断对象是否存在。是返回True,否则返回False
print(os.path.exists('chen.txt')) #输出True
<14>os.path.split():返回路径的目录和文件名,以元组的形式输出。
此处只是把前后两部分分开而已。就是找最后一个'/'
print(os.path.split('/test/test1'))
#输出('/test', 'test1')
<15>os.path.splitext():分离文件名和后缀名。
并以元组的形式输出。
print(os.path.splitext('/test/data.txt'))
#输出('/test/data', '.txt')
<16>os.path.basefilename():获取文件名;os.path.dirname():获取目录名:
filename='/xin/hello/world'
print(os.path.basename(filename)) #输出world
print(os.path.dirname(filename)) #输出/xin/hello
<17>os.path.isabs():判断是否为绝对路径:
带'/'的就是绝对路径。
print(os.path.isabs('hello')) #输出False
print(os.path.isabs('/xin/hello')) #输出True
<18>os.path.abspath():在当前目录下生成绝对路径:
print(os.path.abspath('hello'))
#输出/home/kiosk/PycharmProjects/xin/2019.01.22/文件操作/hello
<19>os.path.join(path,name):连接目录和文件名
print(os.path.join('xin','data.txt')) #输出 xin/data.txt
<20>os.path.getsize():获取文件的大小。如果是目录,则返回0
print(os.path.getsize('data.txt.py')) #输出 108
<21>目录的遍历
for root in os.walk('/mnt'):
print(root)#输出 ('/mnt', ['dir'], ['file'])——>以元组的形式呈现
# ('/mnt/dir', ['test'], [])——>以元组的形式呈现
# ('/mnt/dir/test', [], ['testfile'])——>以元组的形式呈现
mnt目录下有dir目录和file文件;dir目录下有test目录;teswt目录下有testfile文件
for root,dir,file in os.walk('/mnt'):
print(root)
print(dir)
print(file)
#输出 /mnt
# ['dir']
# ['file']
# /mnt/dir
# ['test']
# []
# /mnt/dir/test
# []
# ['testfile']
for root,dir,file in os.walk('/mnt'):
for name in dir:
print(os.path.join(root,name))
#输出 /mnt/dir
# /mnt/dir/test
for root,dir,file in os.walk('/mnt'):
for name in file:
print(os.path.join(root,name))
#输出 /mnt/file
# /mnt/dir/test/testfile
<22>非文本文件的读和写:读必须是rb,写必须是wb(即必须加b)
f1=open('1111.jpg',mode='rb')
content=f1.read()
f1.close()f2=open('xin.jpg','wb')
f2.write(content)
f2.close()
2.文件系统的练习:
<1>练习一:
京东二面笔试题
# 1. 生成一个大文件ips.txt,要求1200行,每行随机为172.25.254.0/24段的ip;
# 2. 读取ips.txt文件统计这个文件中ip出现频率排前10的ip;
1.
import random
f=open('ips.txt','w+')
for i in range(1200):
f.write('172.25.254.'+str(random.randint(0,244))+'\n')
f.close()
(teacher)
import random
def create_ip_file(filename):
ip = ['172.25.254.' + str(i) for i in range(0,255)]
with open(filename,'a+') as f:
for count in range(1200):
# print(random.sample(ip,1))
f.write(random.sample(ip,1)[0] + '\n')
create_ip_file('ips.txt')
2.
f=open('ips.txt')
l=[]
d={}
for ip in f.readlines():
l.append(ip.strip())
for i in l:
if i in d:
d[i]+=1
else:
d[i]=1
d_sorted=sorted(list(d.items()),key=lambda x:x[1],reverse=True)
print(dict(d_sorted[:10]))
(teacher)
def sorted_by_ip(filename,count=10):
ips_dict = dict()
with open(filename) as f:
for ip in f:
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'))
<2>练习二:
# # 1. 在当前目录新建目录img, 里面包含100个文件, 100个文件名各不相同(X4G5.png)
# # 2. 将当前img目录所有以.png结尾的后缀名改为.jpg.
1.
import os
import string
import random
#生成4位内推码
str_code=string.ascii_letters+string.digits
def gen_code(code,len=4):
return ''.join(random.sample(code,len))
#生成内推码的列表(100个元素)
#生成100个文件
def create_file():
se=(gen_code(str_code) for i in range(100))
os.mkdir('img')
for i in se:
os.mknod('img/%s.png' %i)
create_file()
(teacher)
import random
import string
import os
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 name in li:
os.mknod('img/'+name+'.png')
create_files()
2.
(teacher)
import os
def modify_suffix(dirname,old_suffix,new_suffix):
#1.判断要操作的目录是否存在,如果不存在,报错
if os.path.exists(dirname):
#2.找出所有以old_suffix结尾的文件名
pngfile=filter(lambda filename:filename.endswith(old_suffix),os.listdir(dirname))
#3.将文件名和后缀名分开,留下文件名
basefiles=[os.path.splitext(filename)[0] for filename in pngfile]
print(basefiles)
#4.文件重命名
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))
else:
print('%s不存在,不能操作...' %dirname)
modify_suffix('img','.png','.jpg')
<3>练习三:
生成100个MAC地址并写入文件中,MAC地址前6位(16进制)为01-AF-3B
01-AF-3B-xx-xx-xx
import random
import string
#生成两位二进制码
string_code=string.hexdigits
def gen_code(code,len=2):
return ''.join(random.sample(code.upper(),len))
def create_mac():
mac_code = '01-AF-3B'
for i in range(3):
mac_code+=('-'+gen_code(string_code))
return mac_code
with open('mac.txt','w') as f:
for i in range(100):
f.write(create_mac()+'\n')
(teacher)
import random
import string
#随机生成一个mac地址
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
# print(create_mac())
#随机生成100个MAC 地址
def main():
with open('mac.txt','w') as f:
for i in range(100):
mac = create_mac()
print(mac)
#每生成一个MAC地址,存入文件
f.write(mac + '\n')
main()