文件管理


1 文件操作流程

对文件的操作流程:

  • 打开文件,得到文件句柄并赋值给一个变量
  • 通过句柄对文件进行操作
  • 关闭文件

现有文件如下:


view codes

"太上忘情":忘情而至公,得情忘情,不为情绪所动,不为情感所扰。天之至私,用之至公。命之制在气。死者生之根,生者死之根。恩生于害,害生于恩。愚人以天地文理圣,我以时物文理哲。
《老子想尔注》:“一者,道也。散形为气,聚形太上老君。”

言不语:众生听令,身不动:天地俯首。以无情化大爱。

昔日盘古受命开天,宁死无悔。虽对自己是无情,但对苍生则是大爱。太上忘情,自是开辟造化之情。
故而《道德经▪道篇▪第七章》有云:天长地久。天地所以能长且久者,以其不自生,故能长生。是以圣人后其身而身先;外其身而身存。非以其无私邪?故能成其私。
# coding:utf8

f = open('wangqing')  # 打开文件
first_line = f.readline()
print('first line:', first_line)  # 读一行
print('我是分隔线'.center(50, '-'))
data = f.read()  # 读取剩下的所有内容,文件大时不要用
print(data)  # 打印文件

f.close()  # 关闭文件

注意 if in the win,wangqing文件是utf8保存的,打开文件时open函数是通过操作系统打开的文件,而win操作系统默认的是gbk编码,所以直接打开会乱码,需要

f=open('wangqing',encoding='utf8')

wangqing文件如果是gbk保存的,则直接打开即可。

2 打开文件的模式

========= ===============================================================
    Character Meaning
    --------- ---------------------------------------------------------------
    'r'       open for reading (default)
    'w'       open for writing, truncating the file first
    'x'       create a new file and open it for writing
    'a'       open for writing, appending to the end of the file if it exists
    'b'       binary mode
    't'       text mode (default)
    '+'       open a disk file for updating (reading and writing)
    'U'       universal newline mode (deprecated)
    ========= ===============================================================

打开文件的模式有:

  • r,只读模式(默认)
  • w,只写模式。【不可读;不存在则创建;存在则覆盖原内容;】
  • a,追加模式。【不可读;不存在则创建;存在则只追加内容;】

"+" 表示可以同时读写某个文件

  • r+,可读写文件。【能读能写,追加写】
  • w+,写读。【能读能写,覆盖写】
  • a+,同a。【能写能读,追加写】

"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)

  • rU
  • r+U

"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)

  • rb
  • wb
  • ab
# f = open('wangqing','w') #打开文件
# f = open('wangqing','a') #打开文件
# f.write('忘情公子1\n')
# f.write('忘情2\n')
# f.write('至圣!3')

rb模式:

f = open('wangqing','rb')      # 以写读模式打开文件

f.read(3)

f.seek(3)
print(f.read(3))    # b'\xaa\xe4\xb8'

f.seek(3,1)
print(f.read(3))    # b'\x98\xe6\x83'

f.seek(-4,2)
print(f.read(3))    # b'\x81\xe3\x80'

# for line in f:
#     print(line.decode())

总结: 在py3中,如果你想要字符数据,即用于观看的,则用r模式,这样我f.read到的数据是一个经过decode的unicode数据; 但是如果这个数据我并不需要看,而只是用于传输,比如文件上传,那么我并不需要decode,直接传送bytes就好了,所以这个时候用rb模式。

在py3中,有一条严格的线区分着bytes和unicode,比如seek的用法,在py2和py3里都是一个个字节的seek,但在py3里你就必须声明好了f的类型是rb,不允许再模糊。

建议: 以后再读写文件的时候直接用rb模式,需要decode的时候再显示地去解码。

3 文件对象的具体操作

3.1 read()

file.read()方法明确指定从文件中指定要读取多少个字节结果返回成一个字符串,若不指定则返回所有内容
例:读取10个字节

f = open('wangqing')  # 打开文件
data = f.read(10)
print(data)

例:读取所有内容

f = open('wangqing')  # 打开文件
data = f.read()
print(data)

3.2 fileno()

file.fileno()方法返回文件对象的文件描述符

f = open('wangqing')  # 打开文件
data = f.fileno()
print(data)


文件描述符是内核为了高效管理已经被打开的文件所创建的索引,它有以下特点:

  • 非负整数
  • 用于指代被打开的文件
  • 所有执行i/o操作的系统调用都是通过文件描述符完成的

进程通过文件描述符来访问文件。 在程序刚启动的时候默认有3个文件描述符:0(标准输入),1(标准输出),2(标准错误),系统默认提供了 0~2的文件描述符,之后当我们进行 open,create等操作的时候 自动添加进表

当我们新建一个文件,打开open 之后,得到的fd 是从3开始的 因为前面的三个被系统占了在OS X系统下测试 文件描述符表 自增,当释放close之后,fd变成-1,如果再继续新建 则填补之前的空缺。

3.3 write()

file.write(s)表示在file中写入字符串s

f = open('wangqing','a')  # 打开文件
f.write('haha')
f.close()

换行加入内容

f = open('wangqing','a')  # 打开文件
f.write('\nhaha')
f.close()

进度条应用

import time,sys
for i in range(30):
    sys.stdout.write("#")
    # sys.stdout.flush()
    time.sleep(0.3)

3.4 readline()

file.readline()方法执行一次返回一行

f = open('wangqing')
data = f.readline()
print(data)
# print(f.readline())
# print(f.readline())
# print(f.readline())
f.close()

3.5 readlines()

file.readlines()方法以列表模式返回文件所有行

f = open('wangqing')
data = f.readlines()
print(data)
f.close()

3.6 遍历文件所有内容

打印文件的前3行

f = open('wangqing')
for i in range(3):
    print(f.readline())
f.close()

打印文件所有行

f = open('wangqing')
for line in f.readlines():
    print(line)
f.close()

由于 readlines 是一次性获取所有行,若文件数据特别多将会极其占用内存资源,所以一般不用readlines,如果需要读取文件所有行推荐以下方式遍历文件,因为其返回的是一个生成器

f = open('wangqing')

for line in f:
    print(line)

需求:打印所有行,在第4行后面加上:'end 3'

3.7 tell()

file.tell()方法用于打印当前指针所在位置,以字节为单位

f = open('wangqing')
print(f.tell())     # 处理前打印当前指针位置
data = f.readlines()
print(f.tell())     # 处理后打印当前指针位置
f.close()

3.8 seek()

file.seek(offset[, whence])方法用于将文件指针移动到指定位置,你可以理解为就是用鼠标将光标定位到指定的位置

f = open('wangqing')
print(f.tell())
data = f.readlines()
print(f.tell())
f.seek(0)
print(f.tell())
f.close()

offset指定偏移量
whence指定从哪里开始偏移

  • 0表示从文件头开始偏移
  • 1表示从当前位置开始偏移
  • 2表示从文件尾部开始偏移

若不给whence的话默认的从文件头开始偏移

3.9 flush()

file.flush()刷新缓冲区手动同步数据到磁盘中,立即将更改写入硬盘

f = open('wangqing','a+')
f.write('\n天之道,损有余而补不足')
f.flush()
f.seek(0)
print(f.read())
f.close()

3.10 truncate()

file.truncate([size])将文件截断为最多size字节也就是说文件被截取后只剩下size字节,常用于清空文件内容

f = open('wangqing','w+')
f.truncate()
print(f.read())
f.close()

3.11 close()

file.close()方法关闭文件被关闭的文件无法再从中读取数据

f = open('wangqing')
print(f.readline())
f.close()
print(f.read())

3.12 file.name

file.name属性直接调用当前文件的全路径名称

f = open('/Users/seancheng/Downloads/test/mycode/wangqing')
print(f.name)
f.close()

3.13 file.closed

file.closed返回当前文件是否为关闭状态

f = open('/Users/seancheng/Downloads/test/mycode/wangqing')
print(f.closed)
f.close()
print(f.closed)

3.14 file.encoding

file.encoding返回当前文件使用的编码

f = open('/Users/seancheng/Downloads/test/mycode/wangqing')
print(f.encoding)
f.close()

3.15 file.mode

file.mode返回当前文件的打开模式

f = open('/Users/seancheng/Downloads/test/mycode/wangqing')
print(f.mode)
f.close()

3.16 文件内容的修改

需求:将文本第四行修改为:'hello 忘情!'

f = open('wangqing','r+')   #以写读模式打开文件

f.readline()
f.readline()
f.readline()
f.readline()
print(f.tell())
f.write('hello 忘情')

f.close()

和想的不一样,不管事!那涉及到文件修改怎么办呢?

在 Python 中文件是不能被修改的,若想修改其内容,只能新建一个新文件,将修改后的内容写入其中

4 with ... as ...

为了避免打开文件后忘记关闭,可以通过管理上下文,即:

with open('log', 'r') as f:
    pass

如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。

在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:

with open('log1') as obj1, open('log2') as obj2:
    pass

作业

1. 实现shell的sed功能

2. 修改haproxy配置文件

需求:

1、查
    输入:www.wangqing.com
    获取当前backend下的所有记录

2、新建
    输入:
        arg = {
            'bakend': 'www.wangqing.com',
            'record':{
                'server': '100.1.7.9',
                'weight': 20,
                'maxconn': 30
            }
        }

3、删除
    输入:
        arg = {
            'bakend': 'www.wangqing.com',
            'record':{
                'server': '100.1.7.9',
                'weight': 20,
                'maxconn': 30
            }
        }

原配置文件

global       
        log 127.0.0.1 local2
        daemon
        maxconn 256
        log 127.0.0.1 local2 info
defaults
        log global
        mode http
        timeout connect 5000ms
        timeout client 50000ms
        timeout server 50000ms
        option  dontlognull

listen stats :8888
        stats enable
        stats uri       /admin
        stats auth      admin:1234

frontend wangqing.com
        bind 0.0.0.0:80
        option httplog
        option httpclose
        option  forwardfor
        log global
        acl www hdr_reg(host) -i www.wangqing.com
        use_backend www.wangqing.com if www

backend www.wangqing.com
        server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000