unix中文件I/O

在unix中可用的文件I/O函数包括打开文件,读文件,写文件等。

Unix系统中的大多数文件I/O需要用到5个函数:open,read,write,lseek,close.

这里要说明的是read,write的文件I/O都是不带缓冲的,所谓的不带缓冲意思是它们都是走的内核中的一个系统调用。

对于内核而言,所有打开的文件都是通过文件描述符进行引用,文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读或写一个文件时,使用open,create返回文件描述符标识该文件,然后把返回的文件描述符作为参数传递给read,write。

一般情况下unix系统的shell使用文件描述符0作为进程的标准输入,1为标准输出,2为标准错误输出,不同的shell版本可能有所不同,与unix内核无关。

文件描述符的范围是0~open_max 早期的unix系统规定每一个进程最多使用20个文件描述符,

open函数

由open返回的文件描述符是一个最小的未被使用的描述符数值。这一点被有些程序是现在在标准输入,输出,报错上打开新文件。比如。一个程序先关闭标准输出,然后再打开另一个文件。其实我们可以通过dup2函数来实现控制在制定的文件描述符上打开文件。

Creat函数

Creat的一个不足之处是它以只读方式打开所创建的文件。在open的老版本中,如果要创建一个临时文件,并要先写该文件,然后又要读该文件,则必须先调用creat,close,然后调用open.不过现在的新版本open已经解决了这些不便利。

Close函数

当关闭一个文件时还会释放该进程加在该文件上的所有记录锁(有关记录锁有关内容,可以查看博客关于记录锁的文章)。

当一个进程终止时,内核会自动关闭它打开的所有文件。很多程序利用了这一功能而不显示的调用close关闭打开的文件。

Lseek函数

每一个打开的文件都有一个与其相关联的“当前文件偏移量”它通常是一个非负整数,用以度量从文件开始处计算的字节数。通常,读,写操作都从当前文件偏移量处开始,并使偏移量增加所读写的自己数,当打开一个文件的最初时候文件的偏移量为0.

一般,文件的当前偏移量应当是一个非负整数,但是,某些设备也可能允许负的偏移量。但对于普通文件,则其偏移量必须是非负值。因为偏移量可能是负值,所以在比较lseek的返回值时不能检测是否小于0而是测试它是否等于-1.

Lseek仅将当前的文件偏移量记录在内核中,它并不引起任何I/O操作。然后,该偏移量用与下一个读或是写操作。

文件偏移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将加长该文件并在文件中造成一个空洞,这一定是允许的。位于文件中但没有写过的字节都被读为0.

文件中的空洞并不要求在磁盘上占用存储区。具体处理方式与文件系统的实现有关,当定位到超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于源文件尾端和新开始写位置之间的部分则不需要分配磁盘块。

Read函数

如read成功,则返回读到的字节数。如已到达文件结尾,则返回0.

有多重情况可使实际读到的字节数少于要求读的字节数:

·读普通文件时,在读到要求字节数之前已经到达了文件尾端。例如,若在到达文件尾端之前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将返回0

·  当从终端设备读时,通常一次最多读一行

·  当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。

·  当从管道或FIFO读时,如若管道包含的字节少于所需要的数量,那么read将只返回实际可用的字节数

·  当从某些面向记录的设备(例如磁带)读时,一次最多返回一个记录。

·  当某一信号造成中断,而已经读了部分数据量时,读操作从文件的当前偏移量处开始,在成功返回之前,该偏移量将增加实际读到的字节数。

Write函数

对于普通文件,写操作从文件的当前偏移量处开始。如果在打开该文件时,制定了append选项,则在每次写操作之前,将文件偏移量设置在文件的当前结尾处。在一次成功写之后,该文件偏移量增加实际写的字节数

文件共享

unix系统支持在不同进程间共享打开的文件。

内核使用三种数据结构表示打开的文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。

(1)每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:

(a)文件描述符标志

(b)指向一个文件表项的指针。

(2)内核为所有打开文件维持一张文件表。每个文件表项包含:

(a)文件状态标志(读,写,添加,同步和非阻塞等)。

(b)当前文件偏移量

(c)指向该文件v节点表项的指针

(3)每个打开文件(或设备)都有一个v节点,v节点包含了文件类型和对比文件进行各种操作的函数的指针。对于大多数文件,v节点还包含了该文件的i节点(索引节点)。这些信息是在打开文件时从磁盘上读入内存的,所以所有关于文件的信息都是快速可供使用的。例如,i节点包含了文件的所有这,文件长度,文件所在的设备,指向文件实际数据块在磁盘上所在位置的指针(linux没有使用v节点,而是使用了通用i节点结构。虽然两种实现有所不同,但在概念上,v节点与i节点是一样的。两者都指向文件系统特有的i节点结构)。创建v节点结构的目的是对在一个计算机系统上的多文件系统类型提供支持。

如果两个独立进程各自打开了同一个文件,我们假定第一个进程在文件描述符3上打开该文件,而另一个进程则在文件描述符4上打开该文件。打开该文件的每个进程都得到一个文件表项,但对一个给定的文件只有一个v节点表项。每个进程都有自己的文件表项的一个理由是:这种安排使每个进程都有它自己的对该文件的当前偏移量。

给出了这些数据结构后,现在对前面所述的操作做进一步说明

1.在完成每个write后,在文件表项中的当前文件偏移量即增加所写的字节数。如果这使当前文件偏移量超过了当前文件长度,则在i节点表项中的当前文件长度被设置为当前文件偏移量(也就是该文件加长了)。

2.如果已append标志打开了一个文件,则相应标志也被设置到文件表项的文件状态标志中。每次对这种具有填写标志的文件执行写操作时,在文件表中的当前文件偏移量首先被设置为i节点表项中的文件长度。这使得每次写的数据都添加到文件的当前尾端处。

3.若一个文件用lseek定位到文件当前的尾端,则文件表项中的当前文件偏移量被设置为i节点表项中的当前文件长度。

4.lseek函数只修改文件表项中的当前文件偏移量,没有进行任何I/O操作

可能有多个文件描述符项指向同一个文件表项。我们就能看到这一点。在fork后也会发生同样的情况,次时父,子进程对于每一个打开文件描述符共享同一个文件表项。

注意,文件描述符标志和文件状态标志在作用域方面的区别,前者只用于一个进程的一个描述符,而后者则适用于指向该给定文件表项的任何进程中的所有描述符。

对于多个进程读同一个文件都能正确工作。每个进程都有它自己的文件表项,其中也有它自己的当前文件偏移量。但是,当多个进程同时写同一个文件时,则可能产生预期不到的结果。

我们会在单独的文章中,描述多个个进程写的情况。

时间: 2024-08-28 14:39:02

unix中文件I/O的相关文章

UNIX中的文件类型

Unix的文件类型信息包含在stat结构的st_mode成员中可以用宏确定文件类型: 普通文件(S_ISREG()):包含某种形式数据的常用文件类型 目录文件(S_ISDIR()):这种文件包含其他文件的名字以及指向与这些文件有关信息的指针.只有内核可以写目录文件,对其有读权限的进程可以读文件 块特殊文件(S_ISBLK()):提供对设备带缓冲的访问,每次访问以固定长度为单位进行.(块设备在内核中的表现类型?) 字符特殊文件(S_ISCHR()):提供对设备不带缓冲的方位,访问长度可变(字符设备

在linux/unix中查找大文件

在linux/unix中查找大文件,如查找大于100M文件的位置路径,查找等于10M文件的位置路径等等,下面就介绍几个实现快速查找的命令: 1. 查找指定目录下所有大于100M的文件,命令为 find path -type f -size +100M  (path 为自己指定的目录,如当前目录./): 2. 查找指定目录下等于10M的文件,命令为 find path -type f -size 10M (path 为自己指定的目录,如当前目录./): 3. 查找指定目录下小于1M的文件,命令为

在Linux系统中文件(资源)和用户的管理

一个可执行二进制程序,被加载到内存,被内核调度到CPU上运行,这时候,就表现了一个进程.也可以说进程是程序的一个实例,是程序的动态表现. 在 Linux 系统中进程(process)是有属主的,也就是该进程以哪个用户的身份运行的.大家都知道,程序有输入和输出,也称这为程序IO.如果我们程序数据输入是磁盘.如,Web 服务器,接收用户的请求之后,把网页数据从磁盘中读入加工之后再把数据响应给用户.如果,发起Web 服务进程的用户没有读取该用户请求网页文件的权限.则无法响应用户的请求了.所以,文件(资

使用 ACE 库框架在 UNIX 中开发高性能并发应用

使用 ACE 库框架在 UNIX 中开发高性能并发应用来源:developerWorks 中国 作者:Arpan Sen ACE 开放源码工具包可以帮助开发人员创建健壮的可移植多线程应用程序.本文讨论创建使用 ACE 线程的应用程序的一些方法.Adaptive Communication Environment (ACE) 是一个高性能.开放源码.面向对象的框架和 C++ 类库,它有助于简化网络应用程序的开发.ACE 工具包包括一个操作系统层和一个封装网络 API 的 C++ 外观(facade

tcl中文件访问

1. 文件名 TCL提供了丰富的文件操作命令,通过这些命令你可以对文件名进行操作,以顺序后随机方式读写文件,检索系统保留的文件信息(如最后访问时间). 2. 基本文件输入输出命令 下面介绍几个基本的文件输入输出命令: 1) open name? access? open命令以access方式打开文件name.返回供其他命令(gets,close)使用的文件标识.如果name的第一个字符是"|",管道命令被触发,而不是打开文件. 文件的打开有以下方式: r  : 以只读方式打开,文件必须

linux系统中文件的特殊权限

在上篇博客中叙述linux系统中文件的基本属性,见http://vinsent.blog.51cto.com/13116656/1951574,这篇给大家带来linux系统文件的特殊权限,包括SUID.SGID.Sticky(粘滞位). 一.安全上下文 安全上下文指的是一类定义某个进程允许做什么的许可和权限的集合.安全上下文的概念范围很广范,权限.特权.访问令牌.完整性等级等等都包含在其中.这里只简要说说linux系统对文件的安全控制: (1)进程有属主和属组,文件有属主和属组      (2)

MATLAB中文件的读写和数据的导入导出

http://blog.163.com/tawney_daylily/blog/static/13614643620111117853933/ 在编写一个程序时,经常需要从外部读入数据,或者将程序运行的结果保存为文件.MATLAB使用多种格式打开和保存数据.本章将要介绍 MATLAB中文件的读写和数据的导入导出. 13.1 数据基本操作 本节介绍基本的数据操作,包括工作区的保存.导入和文件打开.13.1.1 文件的存储 MATLAB支持工作区的保存.用户可以将工作区或工作区中的变量以文件的形式保

MD5的好处及linux中文件MD5校验和的应用

MD5算法简介: MD5全称是报文摘要算法(Message-Digest Algorithm5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的"指纹"(或称"报文摘要"),不同的文件产生相同的报文摘要的可能性是非常非常之小的. Message Digest Algorithm MD5为计算机安全领域广泛使用的一种散列函数,MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.它是用复杂的数学算法求得的一个12

UNIX中C语言的管道

一.管道的概念 管道是一种队列类型的数据结构,它的数据从一端输入,另一端输出.管道最常见的应用是连接两个进程的输入输出,即把一个进程的输出编程另一个进程的输入.shell中存在专门的管道运算符"|",例如shell命令: ps -ef |grep init 命令"ps -ef"分析当前运行的全部进程,并将结果打印到屏幕上.进程"grep init"从输入的字符串中查找包含字符"init"的子串,并打印结果.这两个领命通过管道符