python文件操作

一、文件读写的原理

  • Python 内置了读写文件的函数,用法和 C 是兼容的;
    操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(又称文件描述符),然后,通过操作系统提供的接口从这个文件对象操作;

二.文件读写的操作

注意:
操作时顺序为:打开+操作+关闭

f = open('/root/hello') ##打开文件,如不存在会报错
f.read()  ##读取文件内容
f.close()  #关闭文件,节省系统的资源

1.open函数带开的文件:包括文件名、模式、编码方式

<_io.TextIOWrapper name='/tmp/passwd' mode='r' encoding='UTF-8'> <class '_io.TextIOWrapper'>

2.read方法

f=open('/tmp/passwd')
print(f.read())        ##打印文件的所有行
print(f.readline())    ##从第1行依次打印
print(f.readline()) 
print(f.readlines())   ##以列表的格式打印所有行(有"\n"符)
print([line.strip() for line in f.readlines()])  ##批量去掉"\n"
f.close()

3.with方法

  • python2.5以后加入了安全上下文管理器with语句;
  • with语句执行结束,会自动清理和关闭文件;
with open(logfile, 'a+') as f:
        for i in range(count):
            f.write(random.choice(ips) + '\n')

三、open函数的模式

1.r模式

  • 文件不存在,报错;
  • 定位到文件开始,文件默认模式(mode)为r
  • 文件不可写:f.writable()判断是否可写;

2.r+

  • 文件不存在,报错;
  • 定位到文件开始,文件可写;
  • 写入的内容插入文件的最开始;

3.w

  • 文件不存在,则自动创建;
  • 定位到文件开始,以读写的方式打开;
  • w模式打开会自动清空文件内容;

4.w+

  • 文件不存在,则自动创建;
  • 定位到文件开始,只能写,不能读取;
  • w模式打开会自动清空文件内容;

5.a

  • 文件不存在,则自动创建;
  • 定位到文件结尾,只能写,不允许读;

6.a+

  • 文件不存在,则自动创建;
  • 定位到文件结尾,以读写方式打开,追加内容;

四、文件指针移动

1.二进制文件

f = open('/home/kiosk/Pictures/Screenshot from 2018-06-06 09-22-29.png', 'rb')
res = f.read()
print(res)
f.close()

fi = open('copy.png', 'wb')  ##将原来图片的内容写入新的文件里,即拷贝
fi.write(res)
fi.close()

2.指针移动

f.seek(offset,whence)
##offset:偏移量(字节)
##whence:0(指针移动到文件最开始),1(指针不移动),2(指针移动到文件最后)
f.seek(4, 0)   ##指针移动到文件最开始+4个字节
f.seek(0, 0)   ##指针移动到文件开始
f.seek(0, 1)   ##指针在当前位置,不移动
f.seek(0, 2)   ##指针移动到文件最后
print(f.readline())  ##测试,查看结果和指针位置
f.seek(4, 0)
print(f.tell())
print(f.readline())
f.tell()  ##查看当前指针位置,字节数

3.字符编码

  • 要读取非 ASCII 编码的文本文件,就必须以二进制模式打开,再解码,Python 还提供了一个codecs模块帮我们在读文件时自动转换编码,直接读出 unicode。
 import codecs
with codecs.open('/Users/michael/gbk.txt', 'r', 'gbk') as f:
    f.read()   # u'\u6d4b\u8bd5'

五、ip日志文件,每一行为1个IP,求日志文件中出现次数最多的前10个IP

1.冗长代码,逻辑结构不清晰,不建议使用

import random

def ip_list(logfile, count):  ##日志文件名,日志条目大小
    ips = ['172.25.254.' + str(ip) for ip in range(1, 255)]
    with open(logfile, 'a+') as f:  ##生成随机IP
        for i in range(count):  ##生成日志文件
            f.write(random.choice(ips) + '\n')  ##注意换行

Num = int(input('please set your num:'))  
FileName = input('please set your filename:')

ip_list(Num, 'FileName')
dict = {}
with open('FileName') as f1:
    for n in f1:
        n = n.strip()
        if n in dict:
            dict[n] += 1
        else:
            dict[n] = 1
print(sorted(dict.items(), key=lambda item: item[-1], reverse=True)[:10])

2.编写函数,逻辑清晰,便于维护

import random

def ip_list(logfile, count):
    ips = ['172.25.254.' + str(ip) for ip in range(1, 255)]
    with open(logfile, 'a+') as f:
        for i in range(count):
            f.write(random.choice(ips) + '\n')

Num = int(input('please set your num:'))
FileName = input('please set your filename:')

def sorted_ip(filename, count=10):
    ip_list(filename, Num)
    ip_dict = dict()
    with open(filename) as f1:
        for ip in f1:
            ip = ip.strip()
            if ip in ip_dict:
                ip_dict[ip] += 1
            else:
                ip_dict[ip] = 1
    return sorted(ip_dict.items(), key=lambda item: item[1], reverse=True)[:count]

print(sorted_ip(FileName))

3.采用封装的函数,效率更高

import random
from collections import Counter

def ip_list(logfile, count):
    ips = ['172.25.254.' + str(ip) for ip in range(1, 255)]
    with open(logfile, 'a+') as f:
        for i in range(count):
            f.write(random.choice(ips) + '\n')

Num = int(input('please set your num:'))
FileName = input('please set your filename:')

def new_sorted_ip(filename, count=10):
    ip_list(filename, Num)
    with open(filename) as f:
        ips = Counter(f)
    return ips.most_common(count)

print(new_sorted_ip(FileName))

4.对比new_sorted_ip和sorted_ip的运行时间

装饰器:

def timecount(fun):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = fun(*args, **kwargs)
        end = time.time()
        print('%s time is %.4f' % (fun.__name__, end - start))
        return res

    return wrapper
@timecount
def sorted_ip(filename, count=10):
   pass

@timecount
def new_sorted_ip(filename, count=10):
   pass

六、os模块对文件的操作

1.对文件和目录的操作

os.mknod('test.py',0o600)   ##创建文件,并设定600的权限
os.remove('test.py')        ##删除文件
os.makedirs('test/westos/package')    ##创建目录,相当于mkdir test/westos/package -p
os.removedirs('test/westos/package')  ##删除目录
os.rename('file1','file2')  ##重命名

2.对命令的操作

os.listdir('/etc')     ##列出/etc下的文件
os.system('ls')        ##执行shell中的ls命令
os.popen('hostname')   ##执行shell中的hostname命令
os.uname()    ##查看主机的相关信息,包括主机名、内核版本、设备信息等

3..os.path的命令

os.path.isfile('/tmp/passwd')  ##判断是否为文件
os.path.exists('/tmp/fstab')   ##判断文件是否存在
os.path.ismount('/mnt')        ##判断目录是否挂载
os.path.split('/var/log/messages')     ##目录与文件分离
os.path.basename('/var/log/messages')  ##拿出目录名
os.path.dirname('/var/log/messages')   ##拿出文件名
os.path.splitext('os_operation.py')    ##文件名与后缀分离
os.path.sep            ##Linux系统的'/',Window系统的'\\'
  • 练习:修改指定目录中指定后缀名的文件
  • 要求:不存在,报错;参数错误报错;后缀名(’.’)及目录(/)不影响操作;可移植
import os
import sys

def rename_suffix(dirname, old_suffix, new_suffix):
    sep = os.path.sep     ##目录符号(/),可移植
    if not dirname.endswith(sep):       ##判断目录,自动添加'/'
        dirname = dirname + sep
    if not old_suffix.startswith('.'):  ##判断后缀,自动添加'.'
        old_suffix = '.' + old_suffix
    if not new_suffix.startswith('.'):
        new_suffix = '.' + new_suffix
    if os.path.exists(dirname):         ##判断目录是否存在
        suffix_list = [file for file in os.listdir(dirname) if file.endswith(old_suffix)]
        basename_list = [os.path.splitext(i)[0] for i in suffix_list]
        # list = [os.rename(dirname + filename + old_suffix, dirname + filename + new_suffix) for filename in basename_list]  ##列表生成式修改
        for filename in basename_list:  ##遍历文件列表修改
            old_filename = dirname + filename + old_suffix
            new_filename = dirname + filename + new_suffix
            os.rename(old_filename, new_filename)
            print(old_filename + ' is rename ' + new_filename)

    else:
        print(dirname + 'is not exist!!')

if len(sys.argv) == 4:   ##sys.argv返回值为列表,0索引是文件名
    dirname = sys.argv[1]
    old_suffix = sys.argv[2]
    new_suffix = sys.argv[3]
    rename_suffix(dirname, old_suffix, new_suffix)
else:
    print('Usage:dirname old_suffix new_suffix'

命令行输入,执行脚本:

[root@foundation51 desktop]# chmod +x replacre_str.py 
[root@foundation51 desktop]]# ./replacre_str.py 
Usage:dirname old_suffix new_suffix
[root@foundation51 desktop]# ./replacre_str.py img2 jpg png
img2/is not exist!!
[root@foundation51 desktop]# ./replacre_str.py img jpg png
img/copy.jpg is rename img/copy.png
[root@foundation51 desktop]# cp ./replacre_str.py /bin/renameSuffix
[root@foundation51 desktop]# renameSuffix img png jpg
img/copy.png is rename img/copy.jpg
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值