• 05文件与IO


    这节主要学习了read、write、lseek、目录访问(opendir、readdir、closedir)这几个系统调用及其简单的应用。
    一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节

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

    fd :想要读的文件的文件描述符
    buf : 指向内存块的指针,从文件中读取来的字节放到这个内存块中
    count : 从该文件复制到buf中的字节个数

    返回值

      如果出现错误,返回-1

      读文件结束,返回0

      否则返回从该文件复制到规定的缓冲区中的字节数

    用write()系统调用将数据写到一个文件中

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

    fd:要写入的文件的文件描述符
    buf: 指向内存块的指针,从这个内存块中读取数据写入        到文件中
    count: 要写入文件的字节个数

    返回值

      如果出现错误,返回-1

      如果写入成功,则返回写入到文件中的字节个数

     下面是一个简单的从一个文件中读取内容写入到另一个文件中去:

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    #define ERR_EXIT(m) 
    	do 
    	{ 
    		perror(m); 
    		exit(EXIT_FAILURE); 
    	} while(0)
    
    int main(int argc, char *argv[])//这里用传参传入原文件和目标文件
    {
    	int infd;
    	int outfd;
    	if (argc != 3)
    	{
    		fprintf(stderr, "Usage %s src dest
    ", argv[0]);
    		exit(EXIT_FAILURE);
    	}
    	infd = open(argv[1], O_RDONLY);//打开原文件
    	if (infd == -1)
    		ERR_EXIT("open src error");
    	//打开目标文件
    	if ((outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
    		ERR_EXIT("open dest error");
    	
    	char buf[1024];
    	int nread;
    	while ((nread = read(infd, buf, 1024)) > 0)
    	{
    		write(outfd, buf, nread);
    	}
    
    	close(infd);
    	close(outfd);
    	return 0;
    }
    

    值得注意的是在用完文件描述符后最好的习惯就是关闭,做到随用随关。

    要做到文件的随机读写就要涉及到另一个系统调用lseek了:

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

    fd:需设置的文件标识符

    ofset:偏移量

    base:搜索的起始位置

    返回值:返回新的文件偏移值
    base有以下几种取值:

    base

    文件位置

    SEEK_SET

    从文件开始处计算偏移

    SEEK_CUR

    从当前文件的偏移值计算偏移

    SEEK_END

    从文件的结束处计算偏移

    看一个小例子:

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    
    #define ERR_EXIT(m) 
    	do 
    	{ 
    		perror(m); 
    		exit(EXIT_FAILURE); 
    	} while(0)
    
    int main(void)
    {
    	int fd;
    	fd = open("test.txt", O_RDONLY);
    	if (fd == -1)
    		ERR_EXIT("open error");
    
    	char buf[1024] = {0};
    	int ret = read(fd, buf, 5);
    	if (ret == -1)
    		ERR_EXIT("read error");
    	printf("buf=%s
    ", buf);
    	
    	ret = lseek(fd, 0, SEEK_CUR);//从当前位置偏移0个量即获取当前偏移位置
    	if (ret == -1)
    		ERR_EXIT("lseek");
    
    	printf("current offset=%d
    ", ret);
    	return 0;
    	
    }
    

    下面介绍一下目录的相关操作:

    打开一个目录:

    DIR*  opendir(char *pathname);

    pathname:目录的路径,路径可以是相对的也可以是绝对的

    返回值:

      打开成功,返回一个目录指针

      打开失败,则返回0

    下面是涉及到访问打开的目录中的一些连接的细节:

    struct  dirent*  readdir(DIR  *dirptr);

    这里用到了打开目录返回的DIR指针

    返回值:

      返回一个指向dirent结构的指针,它包含指定目录中下一个连接的细节;

      没有更多连接时,返回0

    当然最后也是一样,打开目录,用完了也要习惯的关闭一下:

    int closedir (DIR  *dirptr);

    返回值:调用成功返回0,失败返回-1
    这里还要介绍一下一个非常重要的结构体:

     struct dirent

      {

          long d_ino;                 

          off_t d_off;                

          unsigned short d_reclen;   

          char d_name [NAME_MAX+1];   //这是我们比较关心和常用的就是目录下的文件名字

      }

    下面是一个实现基本ls功能的小程序:

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <dirent.h>
    
    
    #define ERR_EXIT(m) 
    	do 
    	{ 
    		perror(m); 
    		exit(EXIT_FAILURE); 
    	} while(0)
    
    int main(void)
    {
    	DIR *dir = opendir(".");  //打开当前目录
    	struct dirent *de;      //定义一个包含文件细节的结构题
    	while ((de = readdir(dir)) != NULL)  //循环读取目录中的信息
    	{
    		if (strncmp(de->d_name, ".", 1) == 0)   //这个起到过滤以.开始的文件
    			continue;
    
    		printf("%s
    ", de->d_name);   
    	}
    
    	closedir(dir);   //最后关闭
    	exit(EXIT_SUCCESS);   //和return 0作用类似
    }
    

      

  • 相关阅读:
    linux 内核优化
    ip_forward与路由转发
    mysql 集群 galera
    mysql 中间件 mycat
    mysql 主-主-从-从
    mysql 主从复制
    mysql 备份
    mysql 日志
    java中四种权限修饰符区别
    Java中关于Math的几个取整方法的区别
  • 原文地址:https://www.cnblogs.com/DamonBlog/p/4364362.html
Copyright © 2020-2023  润新知