python-文件操作

一、文件读写

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

文件读写的过程

1). 打开文件
2). 向文件中写入内容;
3). 关闭文件

1.打开文件, 以读的方式打开文件,返回一个文件对象;
#打开文件,以读的方式打开文件,返回一个文件对象;
# 如果文件不存在, open() 函数就会抛出一个 IOError 的错误,并且
给出错误码和详细的信息告诉你文件不存在;
f = open('/mnt/passwd')
print(f,type(f)
2.读取文件
#如果文件打开成功,接下来,调用 read() 方法可以一次读取文件的全部内容;
content = f.read()
print(content)
## 每次读取文件的一行内容
print(f.readline())
print(f.readline())
print(f.readline())
print(f.readline())

## 如果文件很小, read() 一次性读取最方便;

##  若文件过大:反复调用 read(size)比较保险

##  如果是配置文件,调用 readlines()

## 返回一个文件对象,类型为列表:
print(f.readlines())

## 批量去掉'\n'

print([line.strip() for line in f.readlines()])
3.关闭文件
#文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源。
f.close()
4.读写二进制文件

要读取二进制文件,比如图片、视频等等,用 ‘rb’ 模式打开文件即可

5.open函数的模式
r  以读的方式打开,定位到文件开头 , 默认的 mode
- 文件不存在, 则报错;
- 文件内容不会变化
- 文件只能读不能写入;

    f = open('/mnt/pass','r')
    print(f)
   /mnt/pass 不存在,报错

r+  以读写的方式打开,定位文件开头 , 可以写入内容到文件

w  以写的方式打开,打开文件的时候会清空文件的内容,并且不能读
- 文件不存在,则自动创建;
- 只能写不能读取文件;
- 文件内容会被覆盖掉;当文件以'w'的方式打开, 默认会清空文件内容;
    f = open('/tmp/passwd','w')
    print(f.writable())   检验文件是否可写,可写,返回True;不可写,返回False
li = ['java', 'c', 'python', 'qq']
lis = [i+'\n' for i in li]
print(f.writelines(lis))

[kiosk@foundation10 tmp]$ cat passwd 
java
c
python
qq


w+  以读写的方式打开,定位到文件头,并且打开文件的时候也会清空文件的内容
    f = open('/tmp/passwd','w+')
    li = ['java', 'c', 'python']

    lis = [i+'\n' for i in li]
    f.writelines(lis)
    [kiosk@foundation10 tmp]$ cat passwd 
    java
    c
    python

a  以写的方式打开,定位到文件的末尾,是一个追加的操作 , 但并不允许读
f = open('/tmp/passwd','a')
f.write('westos\n')
[kiosk@foundation10 tmp]$ cat passwd 
java
c
python
westos

a+  以读写的方式打开,定位到文件的末尾,追加的方式。若文件不存在,自动创建文件

在使用以上 mode 打开文件的时候,如果增加了b 模式,表示以二进制方式打开
• 二进制文件
要读取二进制文件,比如图片、视频等等,用 'rb' 模式打开文件即可
    f = open('img01.jpg','rb')
    res = f.read()
    print(res)
    f.close()
    '\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节

复制图片
这里写图片描述

5.文件指针移动
seek(offset,whence)
# offset: 偏移量;    2
# whence: 0:移动指针到文件最开始; 1: 不移动指针,2:移动到文件最后;
tell
# 查看当前指针的位置;

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

6.文件的其它操作
f.flush()函数,将缓冲区的内容写入到硬盘中

fileno() 函数,返回当前的文件描述符,一个数字

isatty() 函数,当前打开的文件是否是一个终端设备

closed 属性,当前文件是否关闭 ,|True,False, f.closed

file 对象是一个迭代器:

next() 方法 , 一行一行的读 , 每次读取一行

二、with语句与文件对象的遍历(文件是否可迭代)

python2.5以后加入了安全上下文管理器with语句;当执行完with语句之后会自动清理和关闭文件对象;
with open('/tmp/passwd') as f:
    f = open('/tmp/passwd')

print(f.read()


/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
判断文件对象是否可迭代
from collections import Iterable

with open('/tmp/passwd') as f:
    f = open('/tmp/passwd')
print("文件对象是否迭代:",isinstance(f,Iterable))

for line in f:
    print(line)

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
文件对象是否迭代: True
root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
练习:

找出文件中出现最多的10个ip;

import random

import time

def create_ip_file(count,logfile):
    # 生成所有的ip列表
    ips = ['172.25.254.'+str(host) for host in range(1,255)]
    # 写入文件;
    with open(logfile,'w') as f:  #w:默认清空文件内容
        for i in range(count):
            f.write(random.choice(ips)+'\n')

create_ip_file(1200,'ips.log')
print("日志文件生成成功")   ##生成ips.log 文件

# 测试函数运行时间的装饰器timeit
def timeit(fun):
    def wrapper(*args,**kwargs):
        start = time.time()
        res = fun(*args,**kwargs)
        end = time.time()
        print("%s runs %.3fs" %(fun.__name__,end-start))
        return res
    return wrapper

第一种方法:

@timeit
def sorted_by_ip(filename,count=10):
    # 创建一个存储ip的字典
    ips_dict = dict()
    # 1. 读取文件内容
    with  open(filename) as f:
        for ip in f:
            ip = ip.strip()    ## 去掉ip里面的空格;
            if ip in ips_dict:
                ips_dict[ip] += 1
            else:
                ips_dict[ip] = 1
        return sorted(ips_dict.items(),key=lambda item:item[1],reverse=True)[:count]

print(sorted_by_ip('ips.log', count=10))
/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
日志文件生成成功
sorted_by_ip runs 0.001s
[('172.25.254.34', 12), ('172.25.254.224', 11), ('172.25.254.173', 11), ('172.25.254.15', 10), ('172.25.254.182', 10), ('172.25.254.137', 10), ('172.25.254.96', 10), ('172.25.254.135', 10), ('172.25.254.106', 9), ('172.25.254.7', 9)]

第二种方法:
倒入Counter 模块

from collections import Counter

@timeit
def new_sorted_by_ip(filename,count=10):
    with open(filename) as f:
        ipcount = Counter(f)
    ## 找出ip出现次数最多的前'count'位
    return ipcount.most_common(count)

print(new_sorted_by_ip('ips.log',count=10))
/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
日志文件生成成功
new_sorted_by_ip runs 0.001s
[('172.25.254.34\n', 12), ('172.25.254.224\n', 11), ('172.25.254.173\n', 11), ('172.25.254.15\n', 10), ('172.25.254.182\n', 10), ('172.25.254.137\n', 10), ('172.25.254.96\n', 10), ('172.25.254.135\n', 10), ('172.25.254.106\n', 9), ('172.25.254.7\n', 9)]

Counter模块示例

from collections import Counter
li = ['a', 'a', 'c', 'd', 'rt', 'f']

word_count = Counter(li)
print(word_count.most_common(2))

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
[('a', 2), ('c', 1)]
三.OS模块

1.查找目录内的所有内容

print(os.listdir('/var/log'))

['tallylog', 'lastlog', 'wtmp', 'samba', 'pluto', 'libvirt', 'audit', 'chrony', 'ppp', 'rhsm', 'glusterfs', 'speech-dispatcher', 'gdm', 'sa', 'tuned', 'yum.log', 'anaconda', 'secure-20180520', 'dmesg.old', 'Xorg.0.log.old', 'wpa_supplicant.log-20180601', 'spooler-20180603', 'wpa_supplicant.log-20180524', 'cron-20180529', 'boot.log', 'btmp-20180601', 'maillog-20180603', 'wpa_supplicant.log', 'spooler-20180529', 'dmesg', 'secure-20180513', 'btmp', 'maillog', 'Xorg.0.log', 'messages-20180529', 'cron-20180513', 'maillog-20180513', 'messages-20180520', 'messages-20180603', 'spooler-20180513', 'secure-20180529', 'cron-20180603', 'Xorg.1.log', 'spooler', 'wpa_supplicant.log-20180606', 'messages-20180513', 'spooler-20180520', 'messages', 'cron-20180520', 'maillog-20180520', 'maillog-20180529', 'secure-20180603', 'secure', 'httpd', 'wpa_supplicant.log-20180527', 'cron']

2. os.system执行shell命令, 直接打印命令的执行结果;返回值为命令的执行效果, 如果为0,代表执行成功, 反之, 不成功;

print(os.system('du -sh /etc/'))
print(os.system('las'))


31M /etc/
256
32512

3. os.popen执行shell命令;

res = os.popen('hostname')
hostname = res.read()
print("主机名为:",hostname)


/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
主机名为: foundation20.ilt.example.com

4. 创建文件, 指定文件权限;

os.mknod('os.txt',0o644)
print("sucess")

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
sucess

[kiosk@foundation20 day_08]$ ll os.txt 
-rw-r--r-- 1 kiosk kiosk 0 Jun  7 14:54 os.txt

5.删除文件

os.remove('os.txt')

6.创建 删除目录

os.mkdir('westos.dir')

[kiosk@foundation20 day_08]$ ls -ld westos.dir/
drwxrwxr-x 2 kiosk kiosk 6 Jun  7 14:57 westos.dir/

## 删除目录
os.removedirs('westos.dir')

7.在上层目录不存在情况下创建和删除目录或文件

os.makedirs('westos/qq/user')

[kiosk@foundation20 day_08]$ cd westos/qq/user/
[kiosk@foundation20 user]$ 

#删除目录
os.removedirs('westos/qq/user')

8.判断文件是否存在,及其类型

os.path.isfile('/etc/passwd') 判断是否是文件
os.path.isdir('/var') 是否为目录
os.path.ismount('/mnt') 是否被挂载
os.path.exists('/etc/passwd') 文件是否存在
os.path.isabs()   此路径是否是绝对路经
os.path.islink('/usr/bin/python3') 文件是否是链接文件
os.path.lexists()  测试路径是否存在  
print(os.path.isfile('/etc/passwd'))
print(os.path.isdir('/var'))
print(os.path.ismount('/mnt'))
print(os.path.exists('/etc/passwd'))
print(os.path.islink('/usr/bin/python3'))
/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
True
True
False
True
True

9.Linux路径分隔符
## Windows: C:\book\etc

print(os.path.sep)

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
/

10.查询系统基本属性

all_info = os.uname()
print(all_info)
print(all_info.sysname)
print(all_info.machine)


/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
posix.uname_result(sysname='Linux', nodename='foundation20.ilt.example.com', release='3.10.0-327.el7.x86_64', version='#1 SMP Thu Oct 29 17:29:29 EDT 2015', machine='x86_64')
Linux
x86_64

11.对目录和文件的操作

把目录名和文件名分割;

print(os.path.split('/var/log/messag'))

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
('/var/log', 'messag')

拿出文件名

print(os.path.basename('/var/log/messag'))

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
messag

拿出目录名

print(os.path.dirname('/var/log/messag'))

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
/var/log

分离文件名和后缀名;

print(os.path.splitext('/etc/hello.txt'))
print(os.path.splitext('hello.py'))
print(os.path.splitext('hello.c'))

/usr/local/python3/bin/python3 /home/kiosk/PycharmProjects/day_08/02_6.6总结.py
('/etc/hello', '.txt')
('hello', '.py')
('hello', '.c')

重命名

os.rename('westos', 'westosdir')

[kiosk@foundation20 day_08]$ ls -ld westosdir/
drwxrwxr-x 2 kiosk kiosk 6 Jun  7 15:36 westosdir/

练习:修改指定的后缀名

#!/usr/bin/python3
import os


def rename_suffix(dirname, old_suffix, new_suffix):
    # dirname: img
    # old_suffix: .png
    # new_suffix: .jpg

    # if not dirname.endswith('/'):
    #     dirname = dirname + '/'

    # 目录分隔符
    sep = os.path.sep
    if not dirname.endswith(sep):  # img  ----> img/
        dirname = dirname + sep


    # 如果后缀名不是.png, .jpg, 则加上'.'
    if not old_suffix.startswith('.'):  # png ---> .png
        old_suffix = '.' + old_suffix
    if not new_suffix.startswith('.'):
        new_suffix = '.' + new_suffix


    if os.path.exists(dirname):
        # 1.  找出以.png结尾的所有文件;
        suffix_lis = [filename for filename in os.listdir(dirname)
                      if filename.endswith(old_suffix)]

        # 2. 分离文件名和后缀名, 拿出所有的文件名即可;
        basename_lis = [os.path.splitext(file)[0] for file in suffix_lis]

        # 3. 批量修改后缀名:(重命名)
        # li = [os.rename(dirname+file+old_suffix, dirname+file+new_suffix) for file in basename_lis]
        for file in basename_lis:
            old_filename = dirname + file +  old_suffix
            new_filename = dirname + file + new_suffix

            os.rename(old_filename, new_filename)
            print("%s重命名为%s成功!" %(old_filename, new_filename))

        # 这里的文件是相对路径
        # os.rename('file1.png', 'file1.jpg')

    else:
        print("%s目录不存在" %(dirname))



import sys      ## 导入命令行执行模块

# 代表传入了三个参数
if len(sys.argv) == 4:
    dirname = sys.argv[1]
    old_suffix = sys.argv[2]
    new_suffix = sys.argv[3]
    # rename_suffix('img', 'png', 'jpg')
    rename_suffix(dirname, old_suffix, new_suffix)
else:
    print("""
    Usage:  command   dirname  old_suffix new_suffix
    """)


[root@foundation10 day01]# cp 01_后缀.py /bin/renameSuffix 
[root@foundation10 day01]# chmod +x /bin/renameSuffix
[root@foundation10 mnt]# ls
ab.sh  file1.png  file2.png  file3.png  file4.png  file5.png  hllo.py  passwd  test1.jpg  test2.jpg  test3.jpg
[root@foundation10 mnt]# renameSuffix /mnt/ png jpg
/mnt/file1.png重命名为/mnt/file1.jpg成功!
/mnt/file2.png重命名为/mnt/file2.jpg成功!
/mnt/file3.png重命名为/mnt/file3.jpg成功!
/mnt/file4.png重命名为/mnt/file4.jpg成功!
/mnt/file5.png重命名为/mnt/file5.jpg成功!
[root@foundation10 mnt]# ls
ab.sh  file1.jpg  file2.jpg  file3.jpg  file4.jpg  file5.jpg  hllo.py  passwd  test1.jpg  test2.jpg  test3.jpg
#!/usr/bin/python3

import os


def rename_suffix(dirname, old_suffix, new_suffix):
    # dirname: img
    # old_suffix: .png
    # new_suffix: .jpg

    # if not dirname.endswith('/'):
    #     dirname = dirname + '/'

    # 目录分隔符
    sep = os.path.sep
    if not dirname.endswith(sep):  # img  ----> img/
        dirname = dirname + sep


    # 如果后缀名不是.png, .jpg, 则加上'.'
    if not old_suffix.startswith('.'):  # png ---> .png
        old_suffix = '.' + old_suffix
    if not new_suffix.startswith('.'):
        new_suffix = '.' + new_suffix


    if os.path.exists(dirname):
        # 1.  找出以.png结尾的所有文件;
        suffix_lis = [filename for filename in os.listdir(dirname)
                      if filename.endswith(old_suffix)]

        # 2. 分离文件名和后缀名, 拿出所有的文件名即可;
        basename_lis = [os.path.splitext(file)[0] for file in suffix_lis]

        # 3. 批量修改后缀名:(重命名)
        # li = [os.rename(dirname+file+old_suffix, dirname+file+new_suffix) for file in basename_lis]
        for file in basename_lis:
            old_filename = dirname + file +  old_suffix
            new_filename = dirname + file + new_suffix

            os.rename(old_filename, new_filename)
            print("%s重命名为%s成功!" %(old_filename, new_filename))
    #
    #     # 这里的文件是相对路径
    #     # os.rename('file1.png', 'file1.jpg')
    #
    else:
        print("%s目录不存在" %(dirname))

rename_suffix('img', 'jpg', 'png')


/usr/local/python3/bin/python3.6 /home/kiosk/PycharmProjects/day01/01_后缀.py
img/fiile1.jpg重命名为img/fiile1.png成功!
img/fiile2.jpg重命名为img/fiile2.png成功!
img/fiile3.jpg重命名为img/fiile3.png成功!
img/fiile4.jpg重命名为img/fiile4.png成功!
img/fiile5.jpg重命名为img/fiile5.png成功!

[root@foundation10 day01]# cd img
[root@foundation10 img]# ls
fiile1.png  fiile2.png  fiile3.png  fiile4.png  fiile5.png  test.sh

12.接收命令行传入的参数

import sys

# sys.argv返回一个列表, 一个值为脚本名称;
print(sys.argv)


# 脚本后跟的第一个参数: sys.argv[1]
# 脚本后跟的第2个参数: sys.argv[2]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值