Linux下编程-----文件与IO(一)基本API

I/O是什么

输入/输出是内存和外设之间拷贝数据的过程:

   设备->内存: 输入操作

   内存->设备: 输出操作

 高级I/O: ANSI C提供的标准I/O库函数成为高级I/O, 也称为带缓冲的I/O;

 低级I/O: Linux 提供的系统调用通常也称为不带缓冲的I/O;

文件描述符

  在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCBProcess Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。一个进程启动时,默认打开了3个文件,标准输入、标准输出、标准错误,对应的文件描述符是0(STDIN_FILENO)、1(STDOUT_FILENO)、2(STDERR_FILENO),这些常量定义在unistd.h头文件中。注:括号内的就代表文件指针File*。

文件描述符和文件指针的转换函数

fileno: 将文件指针转换成文件描述符

       int fileno(FILE *stream);

fdopen: 将文件描述符转换成文件指针

       FILE *fdopen(int fd, const char *mode);

int main()
{
	printf("fileno(stdin)= %d\n",fileno(stdin));
	// res: fileno(stdin)=0
} 

基本API

1.open
打开成功返回文件描述符;打开失败返回-1。

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

参数:

   pathname:  文件名, 可以包含[绝对/相对]路径名;

   flags: 文件打开模式;

   mode: 用来指定对文件所有者, 文件用户组以及系统中的其他用户的访问权限;


#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#define ERR_EXIT(m) \
        do \
        { \
            perror(m); \
            exit(EXIT_FAILURE); \
        }while(0)

int main()
{  
   int fd;
   umask(0);
   fd=open("test.txt",O_RDONLY,0666);
   if(fd==-1)
   ERR_EXIT("open failure");
   printf("Open OK!\n");
   return 0;
}

注意两点:

  1.我们使用#define定义出错的函数,这样更加专业

  2.umask是从我们定义的权限中再“拿走”相应的位,注意这里是逻辑减。我们定义权限666,系统一般默认umask是022(使用umask命令查看),所以剩下的是644,我们也可以将umask的值置为0,这样在程序中就不受其影响了。

2.close

  int close(int fd);

  关闭文件描述符, 使得文件描述符得以重新利用,一个进程结束时也会主动关闭所有的文件。

3.read

    ssize_t read(int fd, void *buf, size_t count);

  返回从文件复制到缓冲区的字节数,count:从该文件复制到buf的字节个数。

4.write

    ssize_t write(int fd, const void *buf, size_t count);  

返回值:

   错误: -1

   什么都没做: 0

   成功: 返回成功写入文件的字节数

注意:

   write返回大于0时, 并不代表buf的内容已经写入到磁盘上的文件中了, 其仅仅代表buf中的数据已经copy到相应的内核缓冲区了. 要实现将缓冲区的内容真正”冲洗”到磁盘上的文件, 需要调用fsync函数;

     int fsync(int fd);

   其将内核缓冲区中尚未写入磁盘的内容同步到文件系统中;

   其实在open调用的时候也可以指定同步选项:O_SYNC  O_SYNC The file is opened for synchronous I/O.   Any  write(2)s  on  the  resulting  file  descriptor will block the calling process until the data has been physically written to the underlying hardware.

   write会等到将buf的内容真正的写入到磁盘才真正返回;

#define ERR_EXIT(m) \
        do \
        { \
            perror(m); \
            exit(EXIT_FAILURE); \
        }while(0)

int main()
{  
   int fd;
   umask(0);
   fd=open("test.txt",O_RDONLY,0666);
   if(fd==-1)
   ERR_EXIT("open failure");
   printf("Open OK!\n");
    int outfd;
   outfd=open("temp.txt",O_RDWR | O_CREAT,0666);
   if(outfd==-1)
   {
       ERR_EXIT("open dest error");
   }
   char buff[1024];
   int nread;
   while((nread=read(fd,buff,1024))>0)
   write(outfd,buff,nread);
   close(fd);
   close(outfd);
   return 0;
}

实现了简单的cp功能。

5.lseek

off_t lseek(int fd, off_t offset, int whence);  

Whence取值:

SEEK_SET

   The offset is set to offset bytes.

SEEK_CUR

   The offset is set to its current location plus offset bytes.

SEEK_END

   The offset is set to the size of the file plus offset bytes.

int ret =lseek(fd,0,SEEK_CUR);
 printf("current offset =%d\n",ret);

6。目录访问之opendir,readdir

DIR *opendir(const char *name);  //打开一个目录

struct dirent *readdir(DIR *dirp);

int closedir(DIR *dirp);  //关闭目录

int mkdir(const char *pathname, mode_t mode);  //创建目录

int rmdir(const char *pathname);  //删除一个空目录

struct dirent  
{  
    ino_t          d_ino;       /* inode number */  
    off_t          d_off;       /* not an offset; see NOTES */  
    unsigned short d_reclen;    /* length of this record */  
    unsigned char  d_type;      /* type of file; not supported 
                                         by all filesystem types */  
    char           d_name[256]; /* filename */  
};  

成功: 返回一个指向dirent结构的指针, 它包含指定目录的下一个连接的细节;
失败:NULL


 DIR* dir=opendir(".");
   struct direnn *de;
   while((de=readdir(dir))!=NULL)
   {
       if(strncmp(de->d_name,".",1)==0)
           continue;
       printf("%s\n",de->d_name);
   
   closedir(dir);
   exit(EXIT_SUCCESS);

上面代码的功能是实现简单的ls操作,列出目录下的普通文件。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值