基于文件描述符的文件操作

文件打开、关闭:open、close

文件读、写:       read、write

改变文件大小:   ftruncate

文件定位:          lseek

获取文件信息:   stat、fstat

文件描述符的复制:dup、dup2

文件描述符:

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每个进程所维护的该进程打开文件的记录表。当进程打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

标准输入文件描述符             #define   STDIN_FILENO          0

标准输出文件描述符             #define   STDOUT_FILENO      1 

标准错误输出文件描述符      #define   STDERR_FILENO      2 

自己新建的文件,是从3开始的。而0,1,2默认已经打开。

printf("abcdef"); 等价于:write(1,"abcdef",6);

                         等价于:write(STDOUT_FILENO,"abcdef",6);

文件打开、关闭:open、close    

int open(const char *pathname, int flags);                           //文件名  打开方式 

int open(const char *pathname, int flags, mode_t mode);     //文件名  打开方式  权限 。要创建文件时,使用该接口。不要用上面2个参数

                                                                                         的接口。因为如果不指定权限,文件的权限默认为进程的权限。所以,要创建                                                                                          文件,就使用第二个接口。如果不适用文件,就使用第一个接口。

例1:

#include <sys/types.h>      //以下三个为open()的头文件

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

int main(int argc,char* argv[]){

        if(argc!=2){

                printf("error args\n");

                return -1;

        }

        int fd;

   fd=open(argv[1],O_RDONLY);                                  //文件想读的话

        fd=open(argv[1],O_WRONLY);                                 //文件想写的话

        fd=open(argv[1],O_RDWR);                                      //文件又想读又想写。

        fd=open(argv[1],O_RDONLY|O_CREAT);                 //这是错误写法。虽然也能创建文件,但是文件的权限跟进程的权限相同。

   fd=open(argv[1],O_RDONLY|O_CREAT,0666);        //创建的文件的权限为0666与umask作用后的权限。如果文件存在,则打开

        fd=open(argv[1],O_RDONLY|O_CREAT|O_EXCL,0666);    //O_EXCL一定与O_CREAT连用。如果文件存在,则open返回失败(-1).

        fd=open(argv[1],O_RDONLY|O_CREAT|O_TRUNC,0666); //O_TRUNC。如果文件存在,则把它变成0.相当于删了,重建。

        fd=open(argv[1],O_RDWR|O_APPEND);                  //无论光标在哪里,每次调用write时,都从最后开始写。

        if(fd <0){

                perror("open");

                return -1;

   }

        printf("fd=%d\n",fd);                                                   //第一次建文件的话,输出3

        close(fd);

}

例2:O_APPEND实验 

    简要代码:

 int fd=open(argv[1],O_RDWR|O_APPEND);

    char buf[128]={0};

    int ret=read(fd,buf,3);                                    //从fd中读3个字节,此时光标应该在第三个位置后。         

    printf("%s",buf);

    memset(buf,0,sizeof(buf));             

    strcpy(buf,"world");

    int ret1=write(fd,buf,strlen(buf));                  //然后往fd写字符串,结果字符串添加到了光标的最后

文件读写:read、write 

例1:

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>              //read和write使用的头文件

int main(int argc,char* argv[]){

        if(argc!=2){

                printf("error args\n");

                return -1;

        }

        int fd;

        fd=open(argv[1],O_RDONLY|O_RDWR);

        if(fd <0){

                perror("open");

                return -1;

        }

        printf("fd=%d\n",fd);

        char buf[128]={0};

        int ret=read(fd,buf,sizeof(buf));               //从fd读到buf,读多大。

        if(ret <0){

                perror("read");

                return -1;

        }

        char buf1[128]="hello";

        int ret=write(fd,buf,strlen(buf1));             //从buf1写到fd,写多少。如果这里写sizeof(buf1),会把128个都读进去,包括0也会读进去。

        if(ret <0){

                perror("write");

                return -1;

        }

        printf("buf=%s\n",buf);

        close(fd);

}

例2:结构体的输入输出

#include <stdio.h>                                                                                                                                                             

#include <stdlib.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <string.h>

typedef struct student{

    int no;

    char name[20];

    float score;

}stu;

int main(int argc,char * argv[]){

    if(argc!=2){

        write(1,"error\n",6);

        return -1;

    }  

    stu s[3]={{1001,"liming",89.5},{1001,"liming",89.5},{1001,"liming",89.5}};

    int fb=open(argv[1],O_RDWR|O_CREAT,0666);

    if(fb<0){

        perror("open");

        return -1;

    }  

    int ret=write(fb,s,sizeof(s));

    if(ret<0){

        perror("write");

        return -1;

    }  

    int ret2=lseek(fb,0,SEEK_SET);

    stu s1[3]={0};

    int ret1=read(fb,s1,sizeof(s1));

    if(ret1<0){

        perror("read");

        return -1;

    }  

    int i=0;

    for(i=0;i<3;i++){

        printf("%d%s%f\n",s1[i].no,s1[i].name,s1[i].score);

    }  

    close(fb);

}

文件描述符:

记录表:结构体数组。

Linux与Windows关于标准输入中涉及EOF的处理方式

在window下,在行尾加Ctrl+Z并且enter后并不会结束程序的运行,而只会将Ctrl+Z当成一个字符来解释,并且将在输入缓冲区中存储的本行数据输出。

要结束输入必须在新的一行(输入enter迫使输出"标准输入"缓存区之后)使用Ctrl+Z。

在linux下,可以在输入enter迫使输出"标准输入"缓存区之后,在新行按Ctrl-D结束输入,这种方法类似于windows的处理方式。也可以在行尾连续两次键入Ctrl-D。

相关解析:

Linux中,在新的一行的开头,按下Ctrl-D,就代表EOF。

如果在一行结束时按下Ctrl-D,则表示输出"标准输入"缓存区,所以这时再按一次Ctrl-D就代表EOF,从而就可以结束输入;

那么,如果真的想输入Ctrl-D怎么办?这时必须先按下Ctrl-V,然后就可以输入Ctrl-D,系统就不会认为这是EOF信号。Ctrl-V表示按"字面含义"解读下一个输入,要是想按"字面含义"输入Ctrl-V,连续输入两次就行了。

注:Linux中按下Ctrl-Z,表示将该进程中断,在后台挂起,用fg命令可以重新切回到前台;按下Ctrl-C表示终止该进程。

Windows中,在新的一行(输入enter迫使输出"标准输入"缓存区之后)开头按下Ctrl-Z表示EOF;如果真的想输入Ctrl-Z,在非行开头的地方输入Ctrl-Z即可,在windows中不能将Ctrl-Z表示为行首字符。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值