1. 文件读取的三部曲: 打开–> 操作 -> 关闭
打开
f = open('/etc/passwd1')
print(f)
读操作
如果文件打开成功,接下来,调用 read() 方法可以一次读取文件的全部内容;
content = f.read()
print(content)
写操作
f.write("hello")
判断文件对象拥有的权限
print(f.readable()) # True
print(f.writable()) # False
关闭
文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源.
f.close()
判断文件对象是否关闭, 已经关闭返回True
print(f.closed)
2. 文件读取模式的选择
r:以读的方式打开,定位到文件开头 , 默认的 mode
- 只能读, 不能写;
- 读取的文件不存在,会报错;
FileNotFoundError: [Errno 2] No such file or directory: '/etc/passwd1'
r+:以读写的方式打开,定位文件开头 , 可以写入内容到文件
- 可以执行读写操作;
- 文件不存在, 会报错;
- 默认情况下, 从文件指针所在位置开始写入;
w:以写的方式打开,打开文件的时候会清空文件的内容,并且不能读
- write only
- 文件不存在, 不报错
- 会清空文件内容
w+:以读写的方式打开,定位到文件头,并且打开文件的时候也会清空文件的内容
- rw
- 文件不存在, 不报错
- 会清空文件内容
a:以写的方式打开,定位到文件的末尾,是一个追加的操作 , 但并不允许读
- write only
- 文件不存在, 不报错
- 不会清空文件内容
a+:以读写的方式打开,定位到文件的末尾,追加的方式。
- rw
- 文件不存在, 不报错
- 不会清空文件内容
非纯文本文件的读取
如果读取图片, 音乐或者视频(非文本文件), 需要通过二进制的方式进行读取与写入;b
- 读取二进制文件
rb; rb+; wb; wb+; ab; ab+;
- 读取文本文件
rt; rt+; wt; wt+; at; at+; 等价于 r; r+; w; w+; a; a+;
先读取二进制文件内容, 保存在变量content里面
f1 = open("frame1.png", mode='rb')
content = f1.read()
f1.close()
print(content)
f2 = open('hello.png', mode='wb')
f2.write(content)
f2.close()
文件常用属性
缓冲区
f = open('/tmp/passwd')
f.buffer
<_io.BufferedReader name='/etc/passwd'>
bufferObj = f.buffer
from collections import Iterable
isinstance(bufferObj, Iterable)
True
for i in bufferObj:
print(i)
f.close()
# 当只是读取文件时, buffer里面没有内容
f = open("/tmp/passwd", 'a+')
f.read()
f.write('123')
3
# 此时写入的内容在缓冲区里面,并没有真正写入磁盘文件
f.buffer
<_io.BufferedRandom name='/tmp/passwd'>
for i in f.buffer:
print(i, end=',')
f.close()
print(f.buffer) # buffer缓冲区对象
文件常用方法
读取文件内容
f = open('/tmp/passwd', 'r+')
f.read():
# 默认情况读取文件的所有内容, 小的文件, 直接用read读取即可,
# 如果是一个大文件时(文件大小>内存大小), 不能通过read一次性读取所有内容;
f.readline(): 每次读取一行内容
f.readlines()
f.readable()
# 类似于head -c 3 /tmp/passwd命令
print(f.read(3))
print(f.readline(), end='')
print(f.readline(), end='')
print(f.readline(), end='')
# 读取文件的所有内容, 返回一个列表, 列表元素分别为文件行内容
print(f.readlines())
# 对于每一行, 去掉后面的'\n' --(列表生成式, map)
print([line.strip() for line in f.readlines()])
print(list(map(lambda x: x.strip(), f.readlines())))
文件的写入操作
# f.write() : 从指针所在位置写入, 写入是字符串内容
# f.writelines(): 将列表里面的每个元素写入文件中
# f.writable()
li = ['user'+str(i)+'\n' for i in range(10)]
f.writelines(li)
指针位置的操作
告诉当前指针所在位置
print(f.tell())
print('1:', f.read(3))
print("移动指针之前:", f.tell())
# 将文件指针移动到文件最开始
# f.seek(0, 0)
# 将指针移动到文件最后
f.seek(0,2)
print("移动指针之后:", f.tell())
f.write("ptest")
# print('2', f.read())
f.close()
文件安全读取-With语句
上下文管理器:打开文件, 执行完with语句内容之后, 自动关闭文件对
with open('/tmp/passwd') as f:
print("with语句里面:", f.closed)
print(f.read())
print("after with语句:", f.closed)
同时打开两个文件对象(这种写法, python2中不支持)
with open('/tmp/passwd') as f1, \
open('/tmp/passwdBack', 'w+') as f2:
# 将第一个文件的内容写入第二个文件中;
f2.write(f1.read())
# 移动指针移动到文件最开始
f2.seek(0,0)
# 读取指针内容
print(f2.read())
python2中只能以普通方式实现
with open('/tmp/passwd') as f1:
content = f1.read()
with open('/tmp/passwdBack', 'w+'):
f2.write(content)
用yield读取大文件:
文件操作
1). 创建文件data.txt, 文件共100000行, 每行存放一个1~100之间的整数.
2). 找出文件中数字出现次数最多的10个数字, 写入文件mostNum.txt;
import random
with open('data.txt', mode='a+') as f:
for i in range(1000000):
f.write(str(random.randint(1,100))+'\n')
# 通过yield, 每次读取一行进行处理
def byLineReader(filename):
with open(filename) as f:
line = f.readline()
# 如果可以读取到内容, 返回改行信息
while line:
yield line
line = f.readline()
# read是一个生成器对象,
read = byLineReader('data.txt')
print(read)
#1). next 读取生成器的内容
print(next(read))
print(next(read))
# 2). 通过for循环
for item in read:
print(item)
# ******** 文件对象是可以for循环遍历的, 默认遍历的内容为每一行的内容.是节省内存空间的。
from collections import Iterable
f = open('data.txt')
print(isinstance(f, Iterable))
for i, item in enumerate(f):
if i == 10:
break
print(i, item)
环境变量函数-os
import os
1). 返回操作系统类型, 值为posix,是Linux操作系统, 值为nt, 是windows操作系统
print(os.name)
print('Linux' if os.name=='posix' else 'Windows')
2). 操作系统的详细信息
info = os.uname()
print(info)
print(info.sysname)
print(info.nodename)
3). 系统环境变量
print(os.environ)
4). 通过key值获取环境变量对应的value值
print(os.environ.get('PATH'))
print(os.getenv('PATH'))
os函数的应用
一.判断是否为绝对路径—’/tmp/hello’, ‘hello.png’, ‘qq/hello.mp3’
import os
import random
from os.path import exists, splitext, join
print(os.path.isabs('/tmp/hello'))
print(os.path.isabs('hello'))
# 2.生成绝对路径
print(os.path.abspath('/tmp/hello'))
print(os.path.abspath('hello.png'))
# 3.'hello.png'
print(os.path.join('/home/kiosk', 'hello.png'))
# 返回一个绝对路径: 当前目录的绝对路径+ 文件名/目录名
print(os.path.join(os.path.abspath('.'), 'hello.png'))
# 4.获取目录名或者文件名
filename = '/home/kiosk/Desktop/201808python/day10/hello.png'
print(os.path.basename(filename))
print(os.path.dirname(filename))
# 5.创建目录/删除目录
mkdir -p qq/qq1/qq1 递归创建目录
os.makedirs('img/films')
os.mkdir('img')
os.rmdir('img')
# 6.创建文件/删除文件
os.mknod('00_ok.txt')
os.remove('00_ok.txt')
# 7.文件重命名(mv)
os.rename('data.txt', 'data1.txt')
# 8.判断文件或者目录是否存在
print(os.path.exists('img'))
# 9.分离后缀名和文件名
print(os.path.splitext('hello.png'))
print(os.path.split('hello.png'))
# 10.将目录名和文件名分离
print(os.path.split('/tmp/hello/hello.png'))
二.在当前目录新建目录img, 里面包含100个文件, 100个文件名各不相同(X4G5.png)
将当前img目录所有以.png结尾的后缀名改为.jpg.
import string
def gen_code(len=4):
# 随机生成4位的验证码
li = random.sample(string.ascii_letters+string.digits, len)
# 将列表元素拼接为字符串
return "".join(li)
def create_files():
# 随机生成100个验证码
li = {gen_code() for i in range(100)}
os.mkdir('img')
# # 随机生成四个数字
for name in li:
os.mknod('img/' + name + '.png')
from collections import Iterable
import sys
def modify_suffix(dirname, old_suffix, new_suffix):
"""
:param dirname: 操作的目录
:param old_suffix: 原先的后缀名
:param new_suffix: 新的后缀名
:return:
"""
# 1. 判断查找的目录是否存在, 如果不存在, 显示报错
if exists(dirname):
# 2. 找出所有以old_suffix(.png)结尾的
# pngfiles = [ filename for filename in os.listdir(dirname)
# if filename.endswith(old_suffix)]
pngfiles = filter(lambda filename: filename.endswith(old_suffix), os.listdir(dirname))
# 3. 将文件名和后缀名分开, 留下所有的文件名
basefiles = [splitext(filename)[0] for filename in pngfiles]
print(basefiles)
# 4. 文件重命名
for filename in basefiles:
# 需要加上目录名
oldname = join(dirname, filename+old_suffix)
newname = join(dirname, filename+new_suffix)
os.rename(oldname, newname )
print("%s重命名为%s成功" %(oldname, newname))
else:
print("%s不存在, 不能操作......" %(dirname))
# 如果该脚本没有被调用, 则执行下面的代码;
if __name__ == '__main__':
# **** 如何在执行脚本时, 接收用户传入的参数;
# 判断用户传的参数是否为3个参数?
if len(sys.argv) == 4:
dirname = sys.argv[1]
old_suffix = sys.argv[2]
new_suffix = sys.argv[3]
# modify_suffix('img', '.png', '.jpg')
modify_suffix(dirname, old_suffix, new_suffix)
else:
print("""
Usage: %s dirname old_suffix new_suffix
""" %(sys.argv[0]))