文件处理

1.什么是文件?

  文件是操作系统为应用程序或者用户提供一种操作硬盘的虚拟单位

 强调:
  文件是操作系统提供的虚拟单位
  应用程序或者用户对文件的读写操作其实是向操作系统发送指令

 

2.为何要用文件?

  文件对应的硬盘空间,如果需要考虑永久保存数据那必须使用文件

 

3.如何用文件

[ 路径问题 ] 
  绝对路径:

      win:  C:\a\b\c.txt
      linux:  /a/b/c.txt

  相对路径: 相对于当前执行文件所在文件夹  (a/b/c.txt)

 

  1).打开文件

f = open(r'D:\1 Python\python5期\day09\a.txt',mode='rt',encoding='utf-8')
# r 就是讲'\'变成文本字符,不具有意义(\不转义)
print(f)

  2).读/写文件

data=f.read()
print(data)

  3).关闭文件

f.close() # 向操作系统发送指令,让操作系统关闭打开的文件,回收操作系统资源
print(f)
f.read()

 

4.f=open('a.txt','r')的过程分析

  1).由应用程序向操作系统发起,系统调用open(...)

  2).操作系统打开该文件,并返回一个文件句柄给应用程序

  3).应用程序将文件句柄赋值给变量f

 

5.强调!!!

  打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的变量.在操作文笔一个文件时,必须把与该文件的这两个部分资源一个不落地回收.

回收方法:

  1. f.close()  #回收操作系统级打开的文件

  2. del f   #回收应用程序级的变量

期中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源,而python自动的垃圾回收机制决定了我们无需考虑del .

 

在操作完毕文件后,一定要记住f.close()    

使用with 关键字来管理上下文

with open('a.txt',mode='rt',encoding='utf-8') as f:
    data=f.read()
    print(data)

 

5.操作文件的方法

  r(默认): 只读模式,以该模式打开文件,当文件不存在时则报错.
      当文件存在时文件指针在文件开头

#掌握
f.read() #读取所有内容,光标移动到文件末尾
f.readline() #读取一行内容,光标移动到第二行首部
f.readlines() #读取每一行内容,存放于列表中

f.write('1111\n222\n') #针对文本模式的写,需要自己写换行符
f.write('1111\n222\n'.encode('utf-8')) #针对b模式的写,需要自己写换行符
f.writelines(['333\n','444\n']) #文件模式
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式

#了解
f.readable() #文件是否可读
f.writable() #文件是否可读
f.closed #文件是否关闭
f.encoding #如果文件打开模式为b,则没有该属性
f.flush() #立刻将文件内容从内存刷到硬盘
f.name

  w: 只写模式,以该模式打开文件,当文件不存在时创建一个空文档
      当文件存在时清空文件内容,文件指针在文件开头

  

with open('a.txt',mode='wt',encoding='utf-8') as f:
    print(f.readable())
    print(f.writable())

    在打开了文件不关闭的情况下,连续的写入,新写的内容总是跟在老内容之后
    f.write('你瞅啥\n')
    f.write('瞅你那熊样\n')
    f.write('巴拉巴拉。。。\n')

    lines=['1111\n','2222\n','3333\n']
    for line in lines:
        f.write(line)
    f.writelines(lines)

    f.write('aaaa\nbbb\ncccc\n')  #代替for循环

  a.只追加写模式,以该模式打开文件,当文件不存在时创建一个空文档,
      当文件存在时不清空文件内容,文件指针跳到文件末尾

with open('c.txt',mode='at',encoding='utf-8') as f:
    f.write('你好阿斯蒂芬\n')
    f.write('adfasdf\n')

    f.writelines([1,2,3])

 

控制文件读写内容的模式(不能单独使用,必须与r,w,a连用)

  t(默认):无论读写都是以字符为单位的,只能操作文本文件,必须指定encoding参数

  b:无论读写都是以bytes为单位的,可以操作所有文件,一定不能指定encoding参数

with open('a.txt',mode='rb') as f:
    data=f.read()
    print(data,type(data))
    print(data.decode('utf-8'))


with open('01.mp4',mode='rb') as f:
    data=f.read()
    print(data,type(data))


with open('a.txt',mode='wb') as f:
    f.write('字符行啊士大夫阿斯蒂芬撒旦发'.encode('utf-8'))

 

练习: 拷贝文件小程序

with open('01.mp4',mode='rb',) as read_f,\
        open(r'D:\1111.mp4',mode='wb') as write_f:
    data=read_f.read()
    write_f.write(data)
拷贝文件小程序

 


文件修改的两种方式:

  方式一:

  1.以读的方式打开源文件
  2.将文件内容一次性全读入内存,在内存完成修改
  3.以写的方式打开源文件,然后将修改后的结果一次性写入源文件

总结:

  优点: 在文件修改过程中硬盘只存在一份数据
  缺点:浪费内存

 

with open('b.txt',mode='rt',encoding='utf-8') as f1:
    msg=f1.read()
    new_msg=msg.replace('alex','大SB')


with open('b.txt',mode='wt',encoding='utf-8') as f2:
    f2.write(new_msg)

 

 

方式二:

  1.以读的方式打开源文件,以写的方式打开一个临时文件
  2.读取源文件的一行内容到内存中,将修改的结果写入临时文件,循环往复直到
  3.删除源文件,将临时文件重命名为源文件

优点: 同一时间在内存中只有文件的一行内容,更节省内容

缺点: 在文件修改过程中硬盘只存在两份数据

import os

with open('b.txt',mode='rt',encoding='utf-8') as read_f,\
    open('.b.txt.swap',mode='wt',encoding='utf-8') as write_f:
    for line in read_f:
        write_f.write(line.replace('大SB','alex'))

os.remove('b.txt')
os.rename('.b.txt.swap','b.txt')

 

 

控制文件内指针移动

 (a.txt文本内容为:你好啊hello)

  强调:只有t模式下read(n),n代表字符个数,除此以外都是以字节为单位

with open('a.txt',mode='rt',encoding='utf-8') as f:
    res=f.read(4)    #四个字符
    print(res)

with open('a.txt',mode='rb') as f:
    res=f.read(3)    #三个字节
    print(res.decode('utf-8'))

  truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为这样直接清空文件了,所以truncate要在r+ 或a 等模式下测试结果

with open('a.txt',mode='at',encoding='utf-8') as f:
    f.truncate(3)
#截取三个字节

  

f.seek() : 指针移动是以字节为单位的

三种模式:    ***(只有0模式既可以在t下使用也可以在b下使用,

          而1,2两者模式只能在b模式下使用)

  0模式 (默认的) :参照文件开头

with open('a.txt',mode='rt',encoding='utf-8') as f:
    f.seek(3,0)      #参照文件开头,从第三个字符开始
    print(f.tell())
    print(f.read())


#运行结果:

3
好啊hello

 

  1模式:   参照指针当前所在的位置

with open('a.txt',mode='rb') as f:
    f.read(2)        #当前所在位置为2个字节
    f.seek(4,1)
    print(f.tell())
    print(f.read().decode('utf-8'))        

#运行结果
6
啊hello

 

 

  2模式:   参照文件末尾

with open('a.txt',mode='rb') as f:
    f.seek(-5,2)    #参照文件末尾,再向前(-5)个字节
    print(f.tell())
    print(f.read().decode('utf-8'))    

#运行结果
9
hello

 

 

小程序练习:记录新增内容

import  time

with open('access.log',mode='rb') as f:
    f.seek(0,2)
    while True:
        line = f.readline()
        if len(line) == 0:
            time.sleep(0.1)
        else:
            print(line.decode('utf-8'),end='')
tail-f access.log
with open('access.log',mode='at',encoding='utf-8') as f:
    f.write('2011-11-11 11:11:11 alex离婚啦\n')
run

 

posted @ 2018-11-26 18:51  kongpan  阅读(150)  评论(0编辑  收藏  举报