• linux系统编程之文件与io(二)


    今天继续学习文件与io,话不多说,开始进入正题:

    文件的read和write系统调用:
    说明:函数中出现在size_t和ssize_t是针对系统定制的数据类型:
     
     
    下面以一个实现文件简单拷贝的示例(类似于cp命令,但是没cp命令强大),来对其文件的读写有个感性的认识:
    #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; }

    编译运行:

    对于read和write,下面再来探讨一下它们之间细微的区别:
    1、read读取过程中,有可能被某些信号给中断,这个在之后的信号中断时再学习。
    2、read读指定字节的数据时,如果返回值大于0,表示已经从文件中将数据读到缓冲区当中了,但是write就不一定了,当我们写入时,如果返回大于0并非代表已经将缓冲区中的数据写入到磁盘当中了,仅仅只是表示数据缓冲区已经拷到内核缓冲区了,并未同步到磁盘上,如果想立即同步到磁盘中的话,可以利用下面这个函数既时同步:
    实际上,我们也可以通过给open函数,设定一个flags,来达到同步的效果:
    这时写文件时,就会一直阻塞到数据缓冲区写到物理磁盘。
     
    文件的随机读写:
     
    说明:lseek对应于c语言fseek函数
    下面用具体实例来理解一下lseek函数的用法:
    实例一:
    #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);//从文件中读取5个字节,这时文件指针就会偏移到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;
        
    }

    首先我们创建一个test.txt,以便进行程序测试:

    编译运行:

    实例二:利用lseek产生空洞文件
    首先先了解下什么是空洞文件:
    好了,下面用程序进行说明:
    编译运行:
     
    我们来查看一下它的内容:
    这时,采用另外一个命令:
     
    这时,我们查看一下其大小:
     
    这时,为了说明空洞内容是没有存放在磁盘中的,这时,我们将偏移量加大:
    编译运行,来查看下内容大小:
    总结:
    一个文件的大小不等于一个文件在磁盘所占用的空间,下面再来简单说明下:
     
    目录访问:
    说明:struct dirent目录信息结构体的核心结构如下:
    下面以一个具体示例来使用上面的这些目录函数【功能跟ls命令类似,简易版】
    编译运行:
    如果想过滤掉隐藏文件,则可以修下代码如下:
    再次运行:
     
    下面还有一些命令函数,比较简单,这里就不练习了,贴出来参考:
    mkdir:
    rmdir:
    chmodfchmod:
     
    chownfchown:
     
    好了,今天的内容学到这,下回见!
  • 相关阅读:
    [转]直接拿来用!最火的Android开源项目(一)
    [原] jQuery EasyUI 1.3.2 离线API、Demo
    [原]通过GitHub Pages建立个人站点(详细步骤)
    [转]直接拿来用!最火的Android开源项目(二)
    堆排序
    单例模式
    【面试题】:火车运煤问题
    Aptana Studio 2.0 对JQuery的智能提示的支持
    vs2005 常用快捷键(备忘)
    关于ASP.NET在IIS上的一些问题的解决办法
  • 原文地址:https://www.cnblogs.com/webor2006/p/3493218.html
Copyright © 2020-2023  润新知