文件处理篇

目录

导语

一、文件的基本操作

1、我们能够操作哪些类型的文件

2、如何操作文件

 二、文件的读写模式

1、语法格式

2、控制文件读写操作的模式

三、读写操作相关的方法

1、读系列

2、写系列

四、文件的读操作优化

五、文件的操作模式

1、文本模式

2、二进制模式

六、二进制模式下读写操作

 七、控制文件内指针的移动

(1)、f.seek()

(2)、模式控制

 八、文件的修改

文件修改方式一

文件修改方式二


导语

应用程序运行过程中产生的数据最先都是存放于内存中的,若想永久保存下来,必须要保存于硬盘中。应用程序若想操作硬件必须通过操作系统,而文件就是操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。

一、文件的基本操作

1、我们能够操作哪些类型的文件

.txt      没有后缀名的文件

我们现在暂时不能操作word、Excel、PPT等文件。

2、如何操作文件

三步法:1、打开文件(open)

              2、读或者写

              3、关闭文件

(1)、打开文件

open('要操作的文件路径', '读写模式', '字符编码')

  注:当路径中出现了字母斜杠的组合会产生一些特殊的含义,所以我们应该给去掉

eg:'D:\Python27\day10\a.txt'

      r'D:\Python27\day10\a.txt'

f = open(r'D:\Python27\day10\a.txt', 'r', encoding='utf-8')
# 返回的是文件句柄

print(f)  # <_io.TextIOWrapper name='D:\\Python27\\day10\\a.txt' mode='r' encoding='utf-8'>

(2)、读取文件 

print(f.read())    # 类似于是文件的内置方法

(3)、关闭文件

f.close()

注:第二种方式来操作文件 

with上下文管理器打开文件!

as:起别名

它的特点就在于:能够自动关闭文件

with open('a.txt', 'r', encoding='utf-8') as f:
    print(f.read())         # helloword

 二、文件的读写模式

1、语法格式

open(文件路径,读写模式,字符编码)

文件路径:是必须写的

读写模式:也是必须写的

字符编码:可选的

2、控制文件读写操作的模式

r(只读:只能读,不能写)  

w(只写:只能写,不能读)    

a(append:在原来的基础之上在添加新的内容)

(1)、只读模式:

当文件路径不存在的时候,会直接保存

f = open('b.txt', 'r', encoding='utf-8')  # No such file or directory: 'b.txt'

with open('a.txt', 'r', encoding='utf-8') as f:
     print(f.read())             # helloword

(2)、只写模式:

写模式的特征: 

1. 当文件路径不存在的时候, 会新建出来一个文件,而不报错

2. 写模式会把原来的数据覆盖掉,从新写入新的数据(重要)

with open('b.txt', 'w', encoding='utf-8') as f:
	pass    # 为了不全语法结构
	f.write('hello')           # hello
	f.write('hahahahhah')      # hahahahhah
	f.write('jerry')           # jerry

(3)、追加模式:

追加模式:当路径不存在的时候,也会新建出来文件

注:它是追加写,而不是覆盖原来的内容!

with open('c.txt', 'a', encoding='utf-8') as f:
	f.write('hello world')    # hello world
	f.write('hello world1')   # hello world1
	f.write('hello world2')   # hello world2
	f.write('hello world3')   # hello world3
	f.write('hello world4')   # hello world4

三、读写操作相关的方法

1、读系列

f.read()           ------> read方法是一次性读取文件中得所有数据

f.readline()     ------> readline一次只读文件的一行内容

f.readlines()   ------> 一次性读取文件的所有内容,然后每一个内容作为列表的一个元素返回,返回的数据类型是:列表

f.writable()     ------> 文件是否可读

2、写系列

f.write()         ------>写入文件,只能书写字符串类型,或者二进制类型,其他类型不能够直接

f.writelines(['a', 'b']) ------>把列表中得一个一个元素当成文件的一行一行内容

f.writeable()            -------->查看文件是否具备写的能力

with open('a.txt', 'w', encoding='utf-8') as f:
	f.write('jerry say hello ')       # jerry say hello
	f.writelines(['hello\n', 'jerry\n', 'kevin\n', 'jason\n'])  # hello
																# jerry
																# kevin
							                                    # jason

	print(f.writable())     # True 
	print(f.readable())     # False

四、文件的读操作优化

当你读取的数据比较小的时候,其实是在缓冲区的,当数据量够多的时候,它会一定刷到磁盘

一次性读取文件的所有数据有什么问题:

当数据比较多的时候,会出现内存溢出,这种情况是坚决不能出现的

如何优化以上操作:

一点一点的读取数据然后把数据赶紧刷到硬盘里

with open('a.txt', 'r', encoding='utf-8') as f:
	print(f.read())  # 一次性读取文件的所有数据,并且光标在文件的末尾,如果在去读,就读不到了
	# 文件句柄f是支持for循环的

	for line in f:
		# line: 就是文件的一行内容
		print(line)

了解的方法:

f.flush()     ------>把数据从内存中立刻刷到磁盘

五、文件的操作模式

1、文本模式

t:text

r  w  a =====> rt   wt    at

文本模式默认就是操作字符串,文本

特征:

1. encoding参数必须指定

2. 读取的所有的数据都是以字符串为单位的

3. t模式只能够读取文本或者字符模式

2、二进制模式

b模式:binary

b模式中得b不能省略------------> rb  wb  ab

特征:

1. encoding='utf-8'参数不能够指定

2. 读取的数据全部以字节为单位

3. 二进制模式可以读取任意类型的文件

六、二进制模式下读写操作

t模式下:

        f.read() 如果不指定参数,默认情况下是一次性读取所有

        f.read(5) 如果指定了参数,返回的就是字符个数
    
b模式下:

        f.read(5) 如果指定了参数,返回的就是字节个数

        如果文件中有中文字符,切记书写的数字要是3的倍数,如果有中文也有英文字符,这个数字需要计算了

 七、控制文件内指针的移动

(1)、f.seek()

f.seek(offset, whence)

    offset:偏移量
        正数:往右移
        负数:往左移        
    whence: 移动的模式

(2)、模式控制

0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的

1: 该模式代表指针移动的字节数是以当前所在的位置为参照的

2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的

# a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”各占3个字节)
abc你好
0模式:
with open('a.txt',mode='rt',encoding='utf-8') as f:
    f.seek(3,0)     # 参照文件开头移动了3个字节
    print(f.tell()) # 查看当前文件指针距离文件开头的位置,输出结果为3
    print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
with open('a.txt',mode='rb') as f:
    f.seek(6,0)
    print(f.read().decode('utf-8')) #输出结果为: 好

1模式:
with open('a.txt',mode='rb') as f:
    f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
    print(f.tell()) # 输出结果为:3
    f.seek(4,1)     # 从当前位置往后移动4个字节,而此时的当前位置为3
    print(f.tell()) # 输出结果为:7

2模式:
with open('a.txt',mode='rb') as f:
    f.seek(0,2)     # 参照文件末尾移动0个字节, 即直接跳到文件末尾
    print(f.tell()) # 输出结果为:9
    f.seek(-3,2)     # 参照文件末尾往前移动了3个字节
    print(f.read().decode('utf-8')) # 输出结果为:好

小练习:实现动态查看最新一条日志的效果

# 小练习:实现动态查看最新一条日志的效果
import time  # 导入的一个时间模块

# linux里面的一条命令:tail -f access.log
with open('access.log', mode='rb') as f:
    f.seek(0, 2)
    while True:
        line = f.readline()
        if len(line) == 0:
            # 没有内容
            time.sleep(0.5) # 睡眠0.5秒
        else:
            print(line.decode('utf-8'), end='')

 八、文件的修改

mode='r+'        # 可读可写
mode='w+t'      # 可读可写
mode='a+t'      # 可读可写

# 文件a.txt内容如下
张一蛋     山东    179    49    12344234523
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422

# 执行操作
with open('a.txt',mode='r+t',encoding='utf-8') as f:
    f.seek(9)
    f.write('<妇女主任>')
    
# 文件修改后的内容如下
张一蛋<妇女主任> 179    49    12344234523
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422

强调:
1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容

2、内存中的数据是可以修改的

文件修改方式一

实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件

优点: 在文件修改过程中同一份数据只有一份

缺点: 会过多地占用内存

# 1. 读取文件内的所有数据
# 快捷键:shift+enter
with open('a.txt', 'r', encoding='utf-8') as f:
    data = f.read()

print(data)

# 2. 读取完字符之后,做字符替换
with open('a.txt', 'wt', encoding='utf-8') as f:
    f.write(data.replace('kevin', 'kevinSB'))

文件修改方式二

实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名。

优点: 不会占用过多的内存

缺点: 在文件修改过程中同一份数据存了两份

import os

with open('db.txt',mode='rt',encoding='utf-8') as read_f,\
        open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
    for line in read_f:
        wrife_f.write(line.replace('SB','kevin'))

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

你可能感兴趣的:(开发语言,python)