文件的通用操作方法

本文主要讲述内容:建立文件、打开文件、读取和写入数据,主要是所用到的open()、create()、close()、read()、write()函数


1.文件描述符


     文件描述符是一个整型的数据,Linux中用它来表示一个文件,所有的文件操作都是通过文件描述符来实现的,文件描述符是文件系统中连接用户空间和内核空间的枢纽,当打开或者创建一个文件的时候内核空间创建响应的结构,并生成一个整型的变量传给用户空间的对应进程。进程用这个文件描述符,对文件进行操作,用户空间的文件操作例如读或者写一个文件的时候,将文件描述符作为参数传给read或write.读写函数的调用到内核时,内核解析作为文件描述符的整型变量,找出对应的设备文件运行相应的函数,并返回到用户空间

    **文件描述符在系统中表示某一文件

    **文件描述符的范围0~OPEN_MAX,是有限的,使用完毕需要释放,close()函数
    **文件描述符的值仅在同一个进程中有效
    **3个已经分配的文件描述符,标准输入0,标准输出1,标准错误输出2。

 

2.打开创建文件open()、create()函数

        open()用于创建打开或者创建一个新文件,create用于创建一个新文件

        2.1.open()函数原型

          int open(const char*pathname,int flags);

                           int open(const char *pathname,int flags,mode_t mode);

             注意事项

                **需要包含头文件sys/types.h sys/stat.h fcntl.h

                **成功执行返回文件描述符的值,失败返回-1

      **pathname 的长度在不同的系统上有所不同,通常情况下为1024字节,超出后会对字符串进行截断处理
      **flags为文件的打开标志,定义文件打开后允许的操作方式可选值如下:

                        O_RDONLY:文件打开后可读

                        O_WRNLY:文件打开后only可写

                        O_RDWR:文件打开后可读可写

         O_APPEND:对文件的写为追加写,就是写入的内容是从文件的结尾处开始续写的。
         O_CREAT:文件不存在就创建,同时mode需要同时设定,用来说明新文件的权限(在创建新文件的时候需要指定文件的权限)
         O_EXCL:查看文件是否存在,用户安全的打开一个文件,如果同时指定了O_CREAT,而文件已经存在,会返回错误(即存在返回-1)
         O_TRUNC:将文件的长度截断为0(文件存在,打开的时候将结果清零)
         O_NONBLOCK打开文件为非阻塞方式。不指定此项在默认为阻塞的。
     **mode是指定权限的,mode的使用必须是和flage的O_CREAT结合的。
mode的选项和含义:.......

            **在用open函数的时候,必选O_RDONLY、O_WRNLY、O_RDWR之一,即第二个参数可以是多个,如:

open(pathname,O_RDONLY|O_CREAT|O_TRUNC,mode)    


2.2 使用函数open()打开文件的的例子
#include<sys/types.h>/*open()必须要包含的头文件*/
#include<sys/stat.h>
#include<fcntl.h>/*open()必须要包含的头文件*/
#include<stdio.h>
int main(void)
{
int fd = -1; /*定义fd,用于接受返回的文件描述符*/
char filename[] = "test22.txt";/*当前路径下的文件text22.txt*/
fd = open(filename,O_RDWR);/*指定打开后可读可写*/
if(-1 == fd) /*打开失败*/
{
printf("Open file %s failure!,fd:%d\n",filename,fd);
}else{
printf("open file %s success,fd:%d\n",filename,fd);
}
return 0;
}
该路径下没有目标文件(test22.txt)的时候,会打开失败。当创建文件之后文件打开成功,返回的文件描述符为3。linux下如果之前没有打开其他的文件,第一次打开文件成功的程序返回的描述符为最低值(0,1,2系统已指定)。

2.3 open()函数还可以打开设备文件 :如打开设备文件/dev/ada1
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main(void)
{
int fd = -1;
char filename[] = "/dev/sda1";/*对磁盘的分区进行打开操作*/
fd = open(filename,O_RDWR);
if(-1 == fd)
{
                printf("Open file %s failure!,fd:%d\n",filename,fd);
}else{
                printf("open file %s success,fd:%d\n",filename,fd);
}

return 0;

}


2.4 用参数O_CREAT创建文件。与O_EXCL结合创建容错性的程序

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(void){
int fd = -1;

char filename[] = "test_creat.txt";     /*需要打开的文件名*/

fd = open(filename,O_RDWR|O_CREAT|O_EXCL,S_IRWXU);      //同时的使用参数O_CREAT|O_EXCL,如果当前文件存在就会返回-1,不存在就会创建并返回文件描述符


if(-1 == fd){/*O_CREAT|O_EXCL的结合使用文件存在返回-1*/
              printf("File %s exist!,reopen it",filename);
                fd = open(filename,O_RDWR);             //重新打开
                printf("fd:%d\n",fd);  //返回文件描述符
}else{                                         //文件不存在,创建斌打开,文件不存在机会自动建立,并返回文件描述符
                printf("Open file %s success,fd:%d\n",filename,fd);
}
return 0;
}


2.5 create()函数
    create()函数用来创建一个文件,open是用来打开一个文件的,但是文件不存在的情况先可以用来创建文件。

    函数原型:

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int creat(const char*pathname,mode_t mode);            //创建一个文件
    create()等效于如下的打开方式:
        open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);//创建一个长度为0的文件
create和open的返回值是相同的

2.5.1 create()函数的例子

    #include<sys/types.h>

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

    #include<stdio.h>

    int main(){

        int fd = -1;

        char filename[] = "test5.txt";

        fd = creat(filename,S_IRWXU)

        if(fd == -1){

            printf("文件:%s创建失败",filename);

        }else{

            printf("文件:%s创建成功",filename);

        }

       }
3 关闭文件close()函数
close()函数关闭一个打开的文件,释放之前打开的文件所占的资源
 
    函数原型:
        #include<unistd.h>
        int close(int fd);
        注意:

        **close()函数关闭一个文件描述符,关闭以后此文件描述符不在指向任何一个文件,从而描述符可以再 次使用
        **执行成功返回0,失败返回-1
        **使用此函数,通常不检查返回值
        **再打开文件之必须关闭文件,进程没有正常的关闭文件,在进程退出的时候系统会自动的关闭打开的文件。
        **文件描述符达到最大值,会因为没有文件描述符可以分配造成打开文件失败。

3.1.close()函数的例子
测试当前系统文件描述符的最大支持量
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
    int i=0;                /*循环变量*/
    int fd = 0;
    for(;;i++)
    {
        fd = open("test.txt",O_RDONLY);
        if(fd < 0){
        printf("error,can't open file\n");
        printf("the maxnumber of fd:%d\n",i+3);
        exit(0);
    }
}
return 0;
}




4.读取文件read()
    4.1函数原型:
            #include <unistd>
            ssize_t read(int fd,void *buf,size_t count);
            注意:

            **从文件描述符fd对应的文件中读取count字节,放到buf开始的缓冲区。
            **read的返回值返回值为的类型可能是不同于int long的,但是在实现的时候可能定义为int或者long
            **count的值为0,read()函数的返回值为0;如果已经到达文件末尾,返回为0;正常情况read返回为正确读取的字节数;返回值为-1的时候出错
            **如果count的值的大于SSIZE_MAX,结果不可预料。
            **在读取成功的时候,文件对应的读取位置指针(指向缓冲区的),向后移动的位置,大小为成功读取的字节数
            **fd是一个文件描述符,通常是open()函数和create()函数的返回值,
            **一定要注意数据缓冲区的大小和,请求读取的字节数的大小关系
   4.2 read()函数的例子
        #include<stdio.h>
        #include<stdlib.h>
        #include<sys/types.h>
        #include<sys/stat.h>
        #include<fcntl.h>
        #include<unistd.h>
        int main(){
            int fd,i;
            ssize_t size = -1;                      /**/
            char buff[10];                          /*接收数据缓冲区*/
            char filename[] = "test.txt";


            fd = open(filename,O_RDONLY);           /*打开文件,文件不存在返回-1*/
            if(fd == -1){
                printf("file:%sopen failure,fd:%d\n",filename,fd);
                exit(0);
            }else{
                printf("file:%sopen success,fd:%d\n",filename,fd);
            }


            while(size){
                size = read(fd,buff,10);
                if(size == -1){                 /*读取文件失败,*/
                        close(fd);              /*关闭文件套接字*/
                        printf("read file error occurs\n");
                        return -1;
                }else{
                        if(size > 0){
                                printf("read %d bytes:",size);
                                printf("\"");
                                for(i = 0;i<size;i++){
                                        printf("%c",*(buff+i));
                                }
                                printf(""\n");
                        }else{
                                printf("reach the end of file\n");
                                 close(fd);
                        }
                }
           }
        return 0;
}
                                                                                                                                                     
5.写文件write()函数
write()向文件中写入数据,将用户的数据保存到文件中
    5.1.write()函数原型:
        #include<unistd.h>
        ssize_t write(int fd,const void *buf,size_t count)
            **向文件描述符fd中写入数据,数据的大小由count指定,buf为要写入数据的指针(指向写入缓冲区)。
            **函数返回为成功写入数据的字节数,
            **操作的是普通文件时,写文件的位置从文件的当前开始,操作成功后,写入的位置会增加写入字节数的值,如果打开文件的时候指定了O_APPEND项,每次操作之前,会将写操作的位置移到文件的结尾处
            **函数操作成功会返回写入的字节数,
            **出错的时候返回为-1.
            **返回值(实际写入的字节)与想写入的字节数会存在差异
    5.1 write()函数的例子

        #include<stdio.h>
        #include<string.h>
        #include<sys/types.h>
        #include<sys/stat.h>
        #include<fcntl.h>
        int main(){
            int fd = -1,size;
            char filename[]="test.txt";
            har buf[] = "quick brown fox jumps over the lazy dog";
            fd = open(filename,O_RDWR|O_CREAT|O_EXCL,S_IRWXU);              /*打开文件, 不存在就创建*/
            if(fd == -1){                                                 /*文件存在*/
                printf("file:%s exit,reopen it",filename);
                open(filename,O_RDWR);
                printf("fd:%d\n",fd);
            }else{                            //不存在主动创建,并返回成功创建的文件的描述符
                printf("Open file:%s success,fd:%d",filename,fd);
            }
        

            size = write(fd,buf,strlen(buf));
            if(size != -1){
                printf("write %d bytes to file %s\n",size,filename);
            }
            close(fd);
            return 0;
            }