文件操作三部曲 打开 操作 关闭
| 文件打开模式 | 描述 |
|---|---|
| r | 以只读模式打开文件,并将文件指针指向文件头;如果文件不存在会报错 |
| w | 以只写模式打开文件,并将文件指针指向文件头;如果文件存在则将其内容清空,如果文件不存在则创建 |
| a | 以只追加可写模式打开文件,并将文件指针指向文件尾部;如果文件不存在则创建 |
| r+ | 在r的基础上增加了可写功能 |
| w+ | 在w的基础上增加了可读功能 |
| a+ | 在a的基础上增加了可读功能 |
| b | 读写二进制文件(默认是t,表示文本),需要与上面几种模式搭配使用,如ab,wb, ab, ab+(POSIX系统,包括Linux都会忽略该字符) |
打开文件
打开一个文件用open()方法(open()返回一个文件对象,它是可迭代的)
r表示是文本文件,rb是二进制文件(这个mode参数默认值就是r)
如果文件不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的信息告诉你文件不存在
f=open('passwdss','r')

读文件:文件使用完毕后必须使用.close()进行关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的
实例:

问题:在执行了一次read方法,读取了所有内容,那么再次调用read方法,不能够获取内容
原因:文件指针移动到了文件末尾,再次调用不会读取到任何内容
文件指针:文件指针标记从哪个位置开始读取数据,第一次打开文件时,通常文件指针会指向文件的开始位置,当执行了read方法后,文件指针会移动到读取内容的末尾

解决方法:添加.seek(0)

由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现,但是每次都这么写实在太繁琐,所以,Python引入了with语句来自动帮我们调用close()方法

逐行读取
可以通过循环来实现逐行读取数据:
with open('pi_digits.txt') as f:
for line1 in f:
print line1 # 每行末尾会有一个换行符
print '------------'
for line2 in f:
print line2.rstrip() # 此时文件已经读完,line2指向文本末尾,因此不会有输出
#line2.rstrip():删除字符串末尾的空白

逐行读取数据也可以使用readline()函数
file=open('passwd')
while True:
text=file.readline()
#判断是否读取到内容
#如果文件指针到文件的最后一行,那么就读不到内容
if not text:
break
#每读取一行的末尾已经有一个'\n'
print text
file.close()

with open('pi_digits.txt') as f:
# readline()每一次读取一行数据,并指向该行末尾
line1 = f.readline() # 读取第一行数据(此时已经指向第一行末尾)
line2 = f.readline() # 从上一次读取末尾开始读取(第二行)
print line1.rstrip()
print line2.rstrip()

有时候我们想要一次性读取全部数据并且按分开存储以便于后续的操作,当然用上面的循环可以实现,但python提供了更简单的方法readlines():
with open('passwd')as f:
contents=f.readlines()
print contents
print '-----------'
for line in contents:
print line
print '------------'
str='' #初始化字符串
for line in contents:
str+=line.rstrip() #字符串的连接
print str

python文件对象提供了三个“读”方法: read()、readline() 和 readlines()。每种方法可以接受一个变量以限制每次读取的数据量。
- read() :每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。如果文件大于可用内存,为了保险起见,可以反复调用
read(size)方法,每次最多读取size个字节的内容,在python3中指定的是字符长度 - readlines(): 一次读取整个文件,像 .read() 一样。.readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for ... in ... 结构进行处理。
- readline() 每次只读取一行,通常比readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 readline()。
写数据到文件
python文件对象提供了两个“写”方法: write() 和 writelines()。
- write()方法和read()、readline()方法对应,是将字符串写入到文件中。
- writelines()方法和readlines()方法对应,也是针对列表的操作。它接收一个字符串列表作为参数,将他们写入到文件中,换行符不会自动的加入,因此,需要显式的加入换行符。
with open('passwd','a')as f:
f.write('python\n')
f.write('java\n')
##此时passwd的内容为:123
f1=open('passwd','w')
f1.writelines(["1","2","3"])
f1=open('passwd','w')
f1.writelines(["1\n","2\n","3\n"])
##此时passwd的内容为:
#1
#2
#3
练习: 创建文件data.txt, 文件共10行, 每行存放一个1~100之间的整数
import random
f=open('data.txt','w')
for i in range(10):
num=random.randint(1,100)
f.write(str(num)+'\n')
f.close()
练习:1、生成一个大文件ips.txt,要求1200行,每行随机为172.25.254.0/24段的ip
2、读取ips.txt文件统计这个文件中ip出现的频率排前10的ip
import random
f=open('ips.txt','w')
for i in range(1000):
num=random.randint(0,255)
f.write('172.25.254.'+str(num)+'\n')
f.close()
def sorted_by_ip(filename,count=10):
ip_dict={}
with open(filename)as f:
for ip in f:
if ip in ip_dict:
ip_dict[ip]+=1
else:
ip_dict[ip]=1
sorted_ip=sorted(ip_dict.items(),
key=lambda x:x[1],reverse=True)[:count]
return sorted_ip
print sorted_by_ip('ips.txt')

使用sorted函数按value值对字典排序
基本介绍一下sorted函数,sorted(iterable,key,reverse),sorted一共有iterable,key,reverse这三个参数。
sorted_ip=sorted(d.items(), key=lambda item:item[1])
这里的d.items()实际上是将d转换为可迭代对象,items()方法将字典的元素转化为了元组,而这里key参数对应的lambda表达式的意思则是选取元组中的第二个元素作为比较参数(如果写作key=lambda item:item[0]的话则是选取第一个元素作为比较对象,也就是key值作为比较对象。lambda x:y中x表示输出参数,y表示lambda函数的返回值),所以采用这种方法可以对字典的value进行排序。注意排序后的返回值是一个list,而原字典中的键值对被转换为了list中的元组。
练习:打开一个已经有的文件,读取完整的内容,并写到另一个文件中去
# 源文件以只读的方式打开
file_read = open('passwd')
# 目标文件以只写的方式打开
file_write = open('passwd_copy','w')
#从源文件中读取内容
text = file_read.read()
# 将读取到的内容写到目标文件
file_write.write(text)
# 关闭文件
file_read.close()
file_write.close()
练习:复制一个二进制文件
f1=open('hello.jpg',mode='rb')
content=f1.read()
f1.close()
f2=open('happy.png',mode='wb')
f2.write(content)
f2.close()
练习:有两个文件,每个都有很多行ip地址,求出两个文件中相同的ip地址
import bisect #二分查找法
with open('test1.txt', 'r') as f1:
list1 = f1.readlines()
for i in range(0, len(list1)):
list1[i] = list1[i].strip('\n')
with open('test2.txt', 'r') as f2:
list2 = f2.readlines()
for i in range(0, len(list2)):
list2[i] = list2[i].strip('\n')
list2.sort()
length_2 = len(list2)
same_data = []
for i in list1:
pos = bisect.bisect_left(list2, i)
if pos < len(list2) and list2[pos] == i:
same_data.append(i)
same_data = list(set(same_data))
print(same_data)

533

被折叠的 条评论
为什么被折叠?



