Python下的文件操作和文件系统

一.Python下的文件操作

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()

二.Python下的文件系统

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()

你可能感兴趣的:(Python下的文件操作和文件系统)