python中的文件

纯文本内容

各个字符的意义

w:write only
没有的文件会新建
已有的文件会覆盖原有文件内容
r:read only
没有的文件会出现报错

FileNotFoundError: [Errno 2] No such file or directory: '/tmp/passwd1'

只能读一遍,因为文件指针的问题

print(f.tell())    # 查看文件指针的位置

才开始文件指针在最开始的位置,读一遍之后指针指到了文件末尾
所以再读一遍,无内容
a:write only
没有的文件会新建
已有的文件会在原有文件后追加内容
w+:read write
没有的文件会新建
原有文件内容清空
r+:read write
没有的文件会报错

FileNotFoundError: [Errno 2] No such file or directory: '/tmp/passwd1'

文件指针指在那里,写的时候就写在那里
已有文件文件开头替换成python
a+:read write
没有的文件会新建
已有文件文末添加内容

实例

打开文件

f = open('/tmp/passwd','r+')
print(f)      #生成一个对象

操作

# 读操作1
# content = f.read()
# print(content)
# 读操作2
# print(f.read())

# 写操作
# f.write('python')

# 查看文件读写权限
# print(f.readable())
# print(f.writable())

关闭文件

f.close()    # 一定要关闭文件否则会一直占用系统资源
		     # 在写的时候可以先写打开文件和关闭文件,再写文件的操作内容

文件指针

文件才一打开的时候,文件指针在文件内容一开始的地方。当文件读取一遍的时候,文件指针随读取默认向下,直到文件末尾,所以此时再读取一遍时,无法读取到文件的内容

非纯文本内容

如果读取图片,音频或视频(非纯文本文件),需要通过二进制的方式来进行读取。
读取文本文件

r r+ w w+ a a+ == rt rt+ wt wt+ at at+

读取二进制文件

rb rb+ wb wb+ ab ab+

复制非纯文本内容

# 将old.png复制到new.png
f1 = open('old.png', 'rb')
print(f1)
# print(f1.read())
content = f1.read()
print(content)   # 读取old.png中的内容

f2 = open('new.png', 'wb')    # 新建一个new.png文件
f2.write(content)    # 在new.png中写入old.png的内容

文件的常用操作

默认情况下读取文件的所有内容,小的文件,直接用read()读取即可
如果是一个大文件(文件大小>内存大小) readline()

读取

f = open('/tmp/passwd')

print(f.read(2))  		      # 按字符读取
			              # 类似于head -c
			      
print(f.readline())                   # 按行读取  


print(f.readlines())                  # 读取文件内容,返回一个列表,列表元素分别为文件的行内容

对于每一行,去掉后边的\n

# 方法一
print([line.strip('\n') for line in f.readlines()])
# 方法二
print(list(map(lambda x:x.strip('\n'),f.readlines())))

f.close()

写入

f = open('/tmp/passwd','w')
f.write('hello')  # 从指针所在位置写入,写的就是字符串的内容
f.writelines(['a','b'])
print(f.writable())
f.close()

指针

f = open('/tmp/passwd','r')
print(f.tell())
print('1:',f.read(3))
print(f.tell())
f.seek(0,0)
print(f.tell())
f.close()

seek:移动指针
第一个参数:偏移量
第二个参数:
0:移动指针到文件开头
1:当前位置
2:移动指针到文件末尾
注意:当第二个参数为1或2时,要改成二进制格式。即在open时后边加上b。

文件练习一

题目要求:创建文件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.write('\n')
f.seek(0,0)
# print(f.tell())
print(f.read())
f.close()

文件练习二

题目要求:生成100个MAC地址并写入文件中,MAC地址前6位(16进制)为01-AF-3B

方法一(生成了100个MAC地址):

import random
import string

hex_num = string.hexdigits
for i in range(100):
    n = random.sample(hex_num.upper(), 6)  # 随机选择出2个
    # print(n)
    print('01-AF-3B' + '-' + n[0] + n[1] + '-' + n[2] + n[3] + '-' + n[4] + n[5])

方法二:

import random
import string

def creat_mac():
    MAC = '01-AF-3B'
    hex_num = string.hexdigits
    for i in range(3):
        n = random.sample(hex_num, 2)
        sn = '-' + ''.join(n).upper()  # 用空将列表n中的值拼接在一起,
        # 并通过upper将所有的字母都变成大写
        MAC += sn
    return MAC

def main():
    with open('mac.txt', 'w') as f:
        for i in range(100):
            mac = creat_mac()
            print(mac)
            f.write(mac + '\n')

main()

文件练习三

题目要求:京东二面编程题
1.生成一个大文件ips.txt,要求1200行,每行随机为172.25.254.0/24段的ip;
2.读取ips.txt文件统计这个文件中ip出现频率排前10的ip;

# 生成1200个ip
# 方法一:
import random

def create_ips():
    with open('ips.txt', 'w') as f:
        ip = '172.25.254.'
        for i in range(1200):
            f.write(ip + str(random.randint(0, 254)) + '/24' + '\n')

# create_ips()

# 方法二:
import random

def create_ips(filename):
    ips = ['172.25.254.' + str(i) for i in range(0, 255)]
    # print(ips)
    with open(filename, 'a+') as f:
        f.write(random.sample(ips, 1)[0] + '\n')

create_ips('ips.txt')

# 排序
def sorted_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_ips = sorted(ips_dict.items(), key=lambda x: x[1], reverse=True)[:10]
    return sorted_ips
    
print(sorted_ip('ips.txt'))

用with省去close

用with来省去每一次都要close的麻烦。

例如:将passwd中的文件内容复制到passwdbackup之中。
方法一:python2和python3中共同的用法。(python2中只能这样用)

with open('/tmp/passwd', 'r') as f1:
    content = f1.read()
with open('/tmp/passwdbackup', 'w+') as f2:
    f2.write(content)

方法二:python3中的另一种用法。

with open('/tmp/passwd', 'r') as f1, \
        open('/tmp/passwdbackup', 'w+') as f2:
    f2.write(f1.read())
    f2.seek(0, 0)
    f2.read()

在此我们引用装饰器一节中的计时器,来对两种方法进行装饰。完整内容如下:

# 装饰器——记时器
# 加装饰器查看两种方式哪一个所用时间更短
import time

def timeit(func):
    def get_time(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print('运行时间为%.6f' % (end_time - start_time))

    return get_time

# python3和python2中都能这样写
# python2中只能这样写
@timeit
def f1():
    with open('/tmp/passwd', 'r') as f1:
        content = f1.read()
    with open('/tmp/passwdbackup', 'w+') as f2:
        f2.write(content)

# python3中还可以这样写
@timeit
def f2():
    with open('/tmp/passwd', 'r') as f1, \
            open('/tmp/passwdbackup', 'w+') as f2:
        f2.write(f1.read())
        # f2.seek(0, 0)
        # f2.read()

f1()
f2()

所得结果如图:

在这里插入图片描述

结论:我们发现f2方法所用时间更短。

文件与生成器结合

# 制作一个生成器
def bylineread(filename):
    with open(filename) as f:
        line = f.readline()
        while line:
            yield line     # 说明是一个生成器
            line = f.readline()
            
# read是一个生成器对象
read = bylineread('data.txt')
print(read)

# 读取生成器内容
方法一:next读取
print(next(read))
print(next(read))

方法二:for循环
for item in read:
    print(item)

方法三:Iterable(可迭代对象)
from collections import Iterable
f= open('data.txt')
print(isinstance(f,Iterable))
for i,item in enumerate(f):
    if i == 5:             # 可以控制想要读取内容的多少
        break
    print(i,item)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值