现在的位置: 首页 > 综合 > 正文

linux的文件操作

2012年10月27日 ⁄ 综合 ⁄ 共 7479字 ⁄ 字号 评论关闭

S_ISREG()  正规文件
S_ISDIR()  目录文件
S_ISCHR()  字符设备文件
S_BLK()   块设备文件
S_FIFO   有名管道文件
S_ISLNK   符号链接文件
S_SOCK   套接字文件

#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname,int oflag,.../*,modet mode */);
 正确返回:文件描述符
 错误返回:-1
pathname是待打开或待创建的语言件名
 * O_RDONLY  只读方式打开
 * O_WRONLY  只写方式打开
 * O_RDWR  读写方式打开
注意,为了和UNIX以前的程序兼容大我数情况下,O_RDONLY的值为0 O_WRONLY的值为1,O_RDWR的值为2
 此外还可以包含利用按位逻辑加符号对下列标志值进行任意组合
O_APPEND 每次写文件时从文件的末尾开始
O_CREAT  如果文件不存在,则创建文件,如果使用这个参数,则必须在后面跟第三个参数——mode,设置对新文的访问方式
O_EXCL  如果文件存在,但又设置了参数O_CREATE会产生错误,这个参数可以检查文件是否存在,以及文件不存在时创建此文件的情况
O_TRUNC  如果文件存在,而且文件以只写或读写方式正确的打开,则将文件长度截至为0、

S_IRUSR  文件所有者的读权限位
S_IWUSR  文件所有者的写权限位
S_IXUSR  文件所有者的执行权限位
S_IRGRP  文件用户组的读权限位
S_IWGRP  文件用户组的写权限位
S_IXGRP  文件用户组的执行权限位
S_IROTH  文件其它用户的读权限位
S_IWOTH  文件其它用户的写权限位
S_IXOTH  文件其它用户的执行权限位

三个有用的按位逻缉加组合定义如下
S_IRWXU 定义为(S_IRUSR|S_IWUSR|S_IXUSR)
S_IRWXG 定义为(S_IRGRP|S_IWGRP|S_IXGRP)
S_IRWXO 定义为(S_IROTH|S_IWOTH|S_IXOTH)

此外还可以利用下列的常量值设置set_uid位和set_gid位
S_ISUID  置set_uid位
S_ISGID  置set_gid位

当一个进程代表你创建文时,其权限位由该进程相联系的umask值所修改,进程利用下列公式决定被创建的文件实际权限位:
 mode&(~umask)
 这表示程序所创建的文件上得到的权限位可能和在open()调用中所要求的mode参数不一致,如果安全问题很重要,我们可以umask的值做一些事情

 

 有时试图打开一个特定的文件之前,可能希望检验进程是否已经访问过该文件这时可以有access系统调用来完成。access系统调用的一般形式是:
 #include <unistd.h>
 int access(char *pathname,int mode);
 正确返回:1
 错语返回:0
 其中,pathname是希望检验的文件名mode是包函在unistd.h中的下列值之一
 R_OK 检验调用进程是否有过读写访问
 W_OK 检验调用进程是否有过写访问
 X_OK 检验调用进程是否有过执行访问
 F_OK 检验规定文件是否存在

 /**
 * 创建一个新文件 5.2.2.c
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *pathname,mode_t mode)
这个函数等价于:
 open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode)

 /**
  * 随机文件操作
  */
 #include <sys/stypes.h>
 #include <unistd.h>
 off_t lseek(int fd,off_t offset,int whence)
 参数fd是文件描述符,它所指的打开文件描述将被调用修改
 当对文件偏移值规定一个新位置时,只需给一个数作为新值,一般来说,这个值相当于一个相对于文件开始位置的偏移值。另外两种可能性是需要给出相对于当前文件位置的偏移值或者希望给出相对于文件结束的偏移值,这三种可能性以级用于选择它们的符号常量表示在图5-2中。
 参数offset是一个相对值,它被加到所选的基地址上,给出新的文件偏移值。参数whence可以取下列三个值中的一个(这些值定义在<unistd.h>文件中)):
 * SEEK_SET  从文件的开始处计算偏移值
 * SEEK_CUR  从当前文件的偏移处行算偏移值
 * SEEK_END  从文件的结束处算算偏移值

-------------------------------------------------------------------------------------------
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--------------------------------------------------------------------------------------------

 

 

 文件操作(流)
 只有当一个流与栽个文件或设备关联起来时,才可以对这个流进行各种操作,这就叫做流的打开操作,只有在文件存在,命名用者有对这个文件进行打开操作的权限,且这个文件没有其它用户锁定的情况下,系统才允许对特定流实施打开的操作,流的打开操作才能成功,如果成功的话系统将返回一个FILE结构的指针,以 后各种操作都可以借助这个结构指针。通过调用系统函数来完成了。
 下面这三个系统调用都可以打开一个标准 输入输出流。
 #include <stido.h>
 FILE *fopen(const char *pathname,const char *type);
 FILE *freopen(const char *pathname,const char *type,FILE *fp);
 FILE *fdopen(int filedes,const char *type);
 这三个系统调用的不同特点在于
 fopen 打开一个特定的文件,文件名由pathname指出。
 freopen在一个特定的流上打开一个特定的文件。首先关闭由FILE *fp指定的已打开的流,然后打开由pathname指定的流,它一般用于打开一个特文件以代替标准输入流,标准输出流,标准 错误输出流等预定流。
 fdopen 将一个流对应到某个己打开的文件上,filedes就是这个文件的描述符。这个调用只有在已打开的模式和type定义的模式相同的情况下才能成功。这个已打开的文件一般是管道文件或网络通信管道,这些文件没有办法通过标准输入输出函数fopen打开,只有通过调用特定的设备来得到文件描述符,然后通过fdopen函数将一个流与这个文件关联起来。

 流的清洗操作。
 #include <stdio.h>
 int fflush(FILE *fp)
 int fpurge(FILE *fp)
 正确返回 0;
 错误返回 EOF;
 其中 FILE *fp就是某个已经打开的流,它们的特点如下
 fflush将缓冲区的内容保存在磁盘上,并清空缓存区
 fpurge将缓冲区中所有的数据清除,包括未读过或者未写回的数据。这是一种破坏情的清除,是通过切断缓冲区的电源来实现的。

 流的关闭操作。
 #include <stdio.h>
 int fclose(FILE *fp)
 正确返回:0
 错误返回:EOF

 流缓冲的属性设定

 流对应的缓冲区的属性包括缓冲区的大小和类型,缓冲区的类型有下面三种,它们有不同的特点
 全缓冲:当这种类型的缓冲区为满时,才会执行真正的输入输出,即将缓冲器的数据保存到磁盘上或输出到终端设备上,大部分情况下缓冲区都是这个类型的。
 行缓冲:这种情况下当缓冲区中输入一个换行符时,真正的输入输出就会发生,这种缓冲允许一次一个字符地在终端上输出,代表情的行缓冲通常用在与终端设备相连的缓冲区上。
无缓冲:这种情况下,一接受到字符,真正的输入输出就进行了,标准错误输出流通常都是无缓冲的,这就是为什么错误信息一产生就会输出,任何情况下都可能输出在屏幕上的原因。
#include <stdio.h>
int setbuf(FILE *fp,char *buf);
int setbuffer(FILE *fp,char *buf,size_t size);
int setlinebuf(FILE *fp);
int setvbuf(FILE *fp,char *buf,int mode,size_t size);
正确返回:0
错语返回:非0
这些系统调用中的FILE *fp是以经打开的流,char *buf是用户自己设定的缓冲区,size_t size是缓冲区的大小,int mode是流的类型,可以取_IOFBF,_IOLBT,_IONBF,分别代表全缓冲,行缓冲和无缓冲。调用这些系统函数时,必须以经打开了流,这样才有FILE *fp指针的存在。当然最好还没有进行其它的操作,因为其它的操作是和缓冲的性质密切相关的。它们各自的特点
setbuf:如果buf为空,则将缓冲区的类型设为无缓冲;否则,设定为缓冲,全缓冲的大小为下义常数BUFSIZ,它一般情况下可以当作激活缓冲区的函数,把buf设为空就禁止缓冲效果了。
setbuffer:这个函数与setbuf比较一致,只是在buf不为空时,设定为全缓冲的大小不是系统预定值而是size。
setlinebuf:这个函数专门用来将缓冲区设定为行缓冲的
setvbuf:这个函数才是最基本的,前面的三个函数都可以从它演变过去.

流的定位操作(ftell,fseek)
#include <stdio.h>
long ftell(FILE *fp)
正确返回:讯写指针的位置
错误返回:-1
int fseek(FILE *fp,long offset,int whence);
正确返回:0;
错误返回:非零;
void rewind(FILE *fp)
无返回值
对以上三个函数的具体说明如下:
ftell:对于一个二进制文件来说,文件的讯写指针是从文件的开头,以字节为单位开始记数的,这个个值可以通过这个函数的调用来取得。
fseek:使用这个函数来定位二进制文件,我们必须指出偏程量的大小offset和解释使用这个偏量的方法whence 其中whence的取值可以有三种情况
SEEK_SET:从文件开头算偏移
SEEK_CUR:从文件当前位置偏移
SEEK_END:从文件结尾处计算偏移
rewind:这个函数用来将读写的指针移动到文件的开头,我们注意思到这个函数没有返回值,系统默认为这个函数调用总是成功的。
前面的介绍都是对二进制文件来说的,对于文本文件就有些不了,在一些非LINUX系统中文本文件读写指针的位置不是简单的以字节来记数的,因而不能使用ftell和fseek函数,在LINUX系统中使用fseek函数来定位文本文件时,也有一些限制。whence必须取SEEK_SET,offset的值只能取0或者由ftell得到的值,说明访问文本文件只能从开头或结尾进行。

fgetpos和fsetpos
#include <stido.h>
int fgetpos(FILE *fp,fpos_t *pos);
int fsetpos(FILE *fp,const fpos_t *pos);
正确返回:0
错误返回:非零
这两个函数也是定位流的操作,fgetpos可以得到读写指针的位置而fsetpos可以定位读写指针的位置,它们和前面介绍的ftell和fseek有些区别:
fgetpos和fsetpos使用了一种抽象的数据结构,fpos_t。这是一个存放指针位置的记录类型,在非LINUX系统中,fpos_t也可以被定义为存放文件讯写位置信息的记录类型。所以这两个函数也可用于非LINUX系统。像 前面所说的对于文本文件的顺就可以用这个函数来实现
ftell和fseek中读写指针的位置是用长整数来记录的,只能使用于LINUX系统中。

-------------------------------------------------------------------------------------------
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--------------------------------------------------------------------------------------------

字符型输入操作
下面三个系统调用就是允许我们一次读入一个字符的函数
#include <stdio.h>
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);
文件末尾或出错返回:EOF;
首先来看一下这三个函数区别与联系
1.函数getchar的作用相当于调用函数getc(stdin),将标准输入流作为能数传进去。
2.函数getc与fgetc的区别在于,getc可以被当作宏来调用,而fgetc只可以作为函数调用,所以它们有如下的不同之处:
 a.函数getc的参数不能是有副作用的表达式
 b.由于fgetc是个函数我们可以把它当成其它函数的参数传递,而getc不可以。
 c.函数fgetc的调用比getc要花费更长的时间,把get作为一个宏就是为了提高效率而设计的。
接下来看一下这三个函数的返回值的情况,它们都把下一个字符从unsigned char型转化为int型,返回这个整数值,这样做可以使所有可能的值能返回包括EOF字符,我们知道,在C语言中EOF的值为-1如果不是这样的话,EOF的值就不能被返回了

区分文件末尾和文件出错的方法
在前面的介绍中我们看到文件的出错和文件结束的返回值是相同的,都是EOF那么怎么区分这两种情况呢通过下面的系统调用可以实现
#include <stdio.h>
int ferror(FILE *fp)
int feof(FILE *fp);
输入正确时返回:非零
输入不正确时返回:零

大多数情况下FILE结构中保存这样两个标志,一个为出错标志,另一个为结尾标志,上面这两个函数就是根据这两个标志做出判断的,这两个标志都可以被 下面的函数清零
void clearerr(FILE *fp);

将字符推回缓冲区的操作
#include <stdio.h>
int ungetc(int c,FILE *fp)
正确返回:整数c
错语返回:EOF
被推回符将在下一次的讯操作中被返回,原则上说它可以支持任何次数的推回字符操作,但是,应用中只需要一次就足够了,而且推回多个字符也不是普启遍的支持的,所以我们不提倡使用推回多个字符。
我们推回的字符不一定要求是上一个读出的字符,EOF字符是不允许推回的,但当我们到达文的末尾时,我们可以推回某个字符,接下来的读操作中,我们将得到这个字符,继结的讯操作将得到EOF字符,
推回字符的操作用在编译程序中,在编译过程中,有时我们需要多看一个字符,来决定如何处理当前的字符,有了这个函数我们可以将多看的那个字符推回,以备下次调用讯作时取得。

字符型输出操作
#include <stdio.h>
int putc(int c,FILE *fp);
int fputc(int c,FILE *fp);
int putchar(int c,FILE *fp);
像三个输入函数的关系一样,putchar(c)相当于putc(c,stdout),而putc是作为宏来编码的,fputc只是一个普通的函数。

一行型的输入操作
#include <stdio.h>
char *fgets(char *buf,int n,FIEL *fp);
char *gets(char *buf);
正确返回:buf;
错语返回:空指针
其中这两个函数都需要指出接收输入缓冲区地址,即buf它们各自的特点如下:
 a. fgets需要明确接收的字符数n和流结构的指针fp,一般情况下它读完一行,将这一行的内容,包括行结尾标志,一起保存到buf中,用空字符0来结束,这要种情况要求这一行的内容包括行结尾标志在内,不能超过n-1个字符。如果超过了n-1个字符,那么只有行的一部分被读入,末尾用空字符来结束,下一次调用fgets时将读这一行接下来的部分。
 b. gets是从标准输入设备输入的。它是个有争议的函数。其问题是允许调用者指定缓冲区的大小,如果一行的大小比缓冲区的大小大时,允许缓冲区溢出这样一来,就会毁坏内存中缓冲区下面的内容。这种方法曾被用于制造病毒,所以虽然标准C提供了这个函数,但是用户最好不要使用。

 一行型的输出操作
 #include <stdio.h>
 int fputs(const char *str,FIEL *fp);
 int puts(const char *str);
 正确返回:非负数
 错误返回:EOF
 其中char *str为要输出的字符串,它们各自的特点如下:
  a. fputs函数的作用是把以字符0结尾的字符串输出到某个特定的流中,末尾字符0并不输出,由于字符串并没有要求一定以换行符结尾,所以这个函数也不一定是一次输出一行的,大多数情况下是一次输出一行但并不是必然的。
  b. puts函数的作用也是把以字符0结尾的字符串输出到标准输出设备上,同样不输出结尾字符0但是这个函数必定输出一个换行符,所以puts函数一定是一次输出一行的,这个函数不像它的对应函数gets那样不安全由于使用这个函数不必处理换行符问题,所以它比fputs的应用更简单

直接型输入输出操作
#include <stdio.h>
size_t fread(void *ptr,size_t size,size_t nobj,FILE *fp);
size_t fwrite(const void *ptr,size_t size,size_t nobj,FILE *fp);
返回:实际读出或写入的数目
其中,ptr是指向若干个结构的指针,这个结构就是输入输出的最小处理单位,size为结构的大小,一般用sizeof()函数求得;nobj是要处理的结构的个数,fp为流的指针。

载自:http://hi.baidu.com/phps/blog/item/5bf79613e410e4806438db31.html

抱歉!评论已关闭.