python文件操作(一)

一 文件操作介绍

计算机系统分为:硬件系统、软件系统两部分,软件系统又可以分为系统软件和应用软件。

        我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,但是,应用程序是无法直接操作硬件的,需要通过操作系统来完成。操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。

       这样的话,我们只需要关注操作文件的流程就行了,也就是:

1.打开文件,得到文件句柄并赋值给一个变量

2.通过句柄对文件进行操作

3.关闭文件

二 python实现流程

      根据上面的流程,在python中我们是这样实现的:

#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r,也就是读文件

#2. 通过句柄对文件进行操作
data=f.read()

#3. 关闭文件
f.close()

      现在我们可以分析一下第一步,操作系统和应用程序是怎么交互的:

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

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

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

注意事项:

1.千万记得操作完文件后要写f.close()。从上面的交互流程我们可以看到,打开一个文件是包含两部分资源的:操作系统级打开的文件+应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:

1、f.close() #回收操作系统级打开的文件
2、del f #回收应用程序级的变量

其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源,

而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()

但还是经常有人会忘记加上,所以还有一种方式打开文件,并且不用你写close,就是通过with来管理上下文:

with open('a.txt','w') as f:
    data = f.read()
 
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)

#第二种格式通过逗号分开,可以在一行打开两个文件

2.建议指定编码。有时候大家打开文件,发现拿到的数据都是乱码的,这是因为f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。若要保证不乱码,文件以什么方式存的,就要以什么方式打开。
f=open('a.txt','r',encoding='utf-8')

三 打开文件的模式

从上文我们知道:文件句柄 = open('文件路径', '模式'),模式可以是以下方式以及他们之间的组合:

CharacterMeaning
‘r'open for reading (default)
‘w'open for writing, truncating the file first
‘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 (for backwards compatibility; should not be used in new code)
 
  

我们逐个举例说明:

'r'模式,只读模式【默认模式,文件必须存在,不存在则抛出异常】,所以我们首先要有一个文件,我这里文件叫'陈粒',内容如下:

11111111
222222222
333
4444
555
555
6666
555
6666

'r'模式操作如下:

f=open('陈粒',encoding='utf-8')
data=f.read()
print(data)
f.close()
View Code

这样我们拿到的文件所有的内容,那我们要一行行的读,就要用到readline()方法:

f=open('陈粒','r',encoding='utf-8')
print(f.readable())
print('第1行',f.readline())
print('第2行',f.readline())
print('第3行',f.readline())
View Code

结果是:

True
第1行 
第2行 
第3行 
        我们用了3个readline(),读取的是前3行的内容,说明readline()在读取一行内容后,光标移动到下一行首部。光标是什么,我们写文件的时候,一直会有一个光标在最后闪烁,我们读取文件的时候,是从光标的位置开始读的(光标是默认在0位置上的,后面会讲一个移动光标的方法叫seek)。
       如果我想要里面任意一行,比如最后一行的内容,上面的方法就很难做到了,这时候需要用到readlines()方法:
 
f=open('陈粒','r',encoding='utf-8')
data=f.readlines()
print(data)
print(data[-1])
f.close()
View Code

结果是:

['11111111\n', '222222222\n', '333\n', '4444\n', '555\n', '555\n', '6666\n', '555\n', '6666\n']
6666

       可以看到readlines()拿到的是所有结果,但是按行放在一个列表里面,通过列表索引,我们可以拿到任何一行的内容。

'w'模式:只写模式【不可读;不存在则创建;存在则清空内容】,可以自己创建,那就简单了,直接来:

 

f=open('陈粒1','w',encoding='utf8')
f.write('11111111\n')
f.write('222222222\n')
f.write('333\n4444\n555\n')
f.close()
View Code

       运行之后你会发现,多了一个文件叫“陈粒1”,里面就是我们写入的内容:

 

11111111
222222222
333
4444
555

         可见我们可以写一行,加上换行符就可以写多行,那除了write()方法,还有别的方法可以写吗?当然是有的,比如writelines(),和我们的readlines()感觉对应,所以里面的内容也要是一个列表:

 

f=open('陈粒1','w',encoding='utf8')
f.write('11111111\n')
f.write('222222222\n')
f.write('333\n4444\n555\n')
f.writelines(['555\n','6666\n'])
f.close()
View Code

       再看我们的文件,又多了两行。下面再看一段代码:

 

f=open('陈粒1','w',encoding='utf8')
f.write('11111111\n')
f.write('222222222\n')
f.write('333\n4444\n555\n')
f.writelines(['555\n','6666\n'])
f.writelines(['555\n','6666\n',1]) # 文件内容只能是字符串,只能写字符串
f.close()
View Code

       运行之后发现报错了,因为我们最后写入了一个数字,而文件的内容都是字符串,所以写也都是写入字符串的,不能写数字,当然其他类型也是不可以的。

'a'追加写模式【不可读;不存在则创建;存在则只追加内容】,看到我们上面的w模式,写在同一个文件里面,会把之前的覆盖,那么如果只想在文件里面加点东西,显然需要另一种模式,就是a模式:

 

f=open('陈粒1','a',encoding='utf-8')
f.write('写到文件最后')
View Code

       这时候看结果,最后已经加上一行了:

 

11111111
222222222
333
4444
555
555
6666
555
6666
写到文件最后

       上面说的3种模式非常简单,也是我们常用的3种模式,但都只是单一的模式,很多时候我们需要同时对一个文件进行读写操作,就需要这三个配合'+'一起使用了:

 

"+" 表示可以同时读写某个文件
r+, 读写【可读,可写】
w+,写读【可读,可写】
a+, 写读【可读,可写】

        在说这三个模式之前,需要了解一个知识点就是:文件没有修改这一说,大家所认知的修改文件,是应用程序为了方便使用写的一个功能,改是在内存中改,但最终还是覆盖硬盘中的源文件,所以修改文件本质上是覆盖之前的文件。所以我们看看'r+'模式:

 

f = open('陈粒1','r+',encoding='utf-8')
data = f.read()
print(data)
# f.write('aaa')
f.close()
View Code

       从结果看到,读文件是没有问题的,现在把写的那一行取消注释,看看文件内容:

 

11111111
222222222
333
4444
555
555
6666
555
6666
写到文件最后aaa

       不会换行写,如果你要换行写,就要在aaa前面加上\n,那单独写是什么情况:

 

f = open('陈粒1','r+',encoding='utf-8')
# data = f.read()
# print(data)
f.write('aaa')
# f.write('\naaa')
f.close()
View Code

      结果是:

 

aaa11111
222222222
333
4444
555
555
6666
555
6666
写到文件最后

      覆盖了前面三个111,因为光标默认是0,而写是从光标处开始写的,所以导致覆盖,这几种模式理解就行,用到不多。那如果我们要修改文件怎么办?就要打开两个文件了:

 

r_f = open('陈粒1','r',encoding='utf-8')
data = r_f.readlines()
r_f.close()

w_f = open('陈粒2','w',encoding='utf-8')
data.pop(2)
w_f.writelines(data)
w_f.close()
View Code

     一个文件读,一个文件写,写之前把读到的数据列表删除了一个元素,所以’陈粒2‘文件就少了一行333,这样就实现了文件修改啦。有人说这样拿到的是新文件,但我想要在原来的文件修改怎么办?那就在改完之后把源文件删除后,再把新文件rename一下就好了,os模块能搞定这个需求。下一篇要讲的是二进制方式打开文件。

 

 

转载于:https://www.cnblogs.com/pengfy/p/10817946.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值