
1.8.1 文件读写步骤与打开模式
1.文件读写操作步骤
不同编程语言读写文件的操作步骤大体都是一样的,分为以下几个步骤:
1)打开文件,获取文件描述符;
2)操作文件描述符——读/写;
3)关闭文件。
然而,不同的编程语言提供的读写文件的API是不一样的,有些提供的功能比较丰富,有些则比较简单。
注意 文件读写操作完成后,应该及时关闭。一方面,文件对象会占用操作系统的资源;另一方面,操作系统对同一时间能打开的文件描述符的数量是有限制的,在Linux操作系统上可以通过ulimit -n来查看这个显示数量。如果不及时关闭文件,还可能会造成数据丢失。因为将数据写入文件时,操作系统不会立刻把数据写入磁盘,而是先把数据放到内存缓冲区异步写入磁盘。当调用close方法时,操作系统会保证把没有写入磁盘的数据全部写到磁盘上,否则可能会丢失数据。
2.文件打开模式介绍
我们先来看一下通过Python、PHP和C语言打开文件的函数定义。
Python:
open(name[, mode[, buffering]])# Python3 open (file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
PHP:
reso urce fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] )
C:
int open(const char * pathname, int flags);
在上面3种编程语言内置的打开文件的方法所接收的参数中,除了都包含一个“文件路径名称”外,还会包含一个mode参数(与C语言的open函数中的flags参数作用相似)。这个mode参数定义的是打开文件时的模式,常见的文件打开模式有:只读、只写、可读可写、只追加。
例如,我们来读取这样一个已有的文本文件:song.txt。该文件的字符编码为utf-8。具体操作如下例所示。
【例1-82】Python文件操作步骤示例
# 第一步:(以只读模式)打开文件 f = open('song.txt', 'r', encoding='utf-8') # 第二步:读取文件内容 print(f.read()) # 第三步:关闭文件 f.close()
不同编程语言中对文件打开模式的定义有些微小的差别,我们来看一下Python中的文件打开模式,如表1-9所示。
表1-9 文件打开模式
【思考1】r+、w+和a+都可以实现对文件的读写,那么它们有什么区别呢?
1)r+会覆盖当前文件指针所在位置的字符,如原来文件内容是“Hello,World”,打开文件后写入“hi”则文件内容会变成“hillo,World”。
2)w+与r+的不同是,w+在打开文件时就会先将文件内容清空。
3)a+与r+的不同是,a+只能写到文件末尾,如表1-10所示。
表1-10 r+、w+与a+的模式对比
【思考2】为什么要定义这些模式呢?为什么不能像我们用word打开一篇文档一样既可以读,又可以写,还可修改呢?
主要有两种观点:
1)跟安全有关,有这种观点的大部分是做运维的读者,他们认为这就像Linux上的rwx(读、写、执行)权限。
2)跟操作系统内核管理I/O的机制有关,有这种观点的大部分是做C语言开发的读者,特别是与内核相关的开发人员。为了提高读写速度,要写入磁盘的数据会先放进内存缓冲区,之后再回写。由于可能会同时打开很多文件,因此当回写数据时,需要遍历已打开的文件从而判断是否需要回写。他们认为如果打开文件时指定了读写模式,那么需要回写时,只要去查找以“可写模式”打开的文件就可以了。