Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析

Linux文件系统基本概念

在这里插入图片描述

文件系统接口
文件系统 -一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问。
在这里插入图片描述

文件系统缓存
主存(通常是DRAM)的一块区域,用来缓存文件系统的内容,包含各种数据和元数据。
在这里插入图片描述

文件I0访问方式概述

标准文件访问方式
在这里插入图片描述
在这里插入图片描述
直接IO
在这里插入图片描述
实现方式
open +O_DIRECT = 绕过内核缓冲区的直接访问,便有效避免了CPU和内存的多余时间开销。
在这里插入图片描述
在这里插入图片描述
如果读取的数据只用一次,就不用读取了(如数据库)。就没有必要,使用高速页缓冲。

直接IO代码演示

在这里插入图片描述

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

#define TOTAL 10

int main(int argc, char *argv[])
{
    const char *TEXT = "This is a test.\n";
    const char *filename = "./write.txt";
    int fd = -1;
    int i = 0;

    fd = open(filename, O_RDWR|O_TRUNC|O_CREAT|O_DIRECT);
    if (fd < 0)
    {
        fprintf(stderr, "fopen %s failed, reason: %s. \nexit.\n", filename, strerror(errno));
        return -1;
    }

    for (i = 0; i < TOTAL; i++)
    {
        //sleep(1);
        if (writeToFile(fd, TEXT, strlen(TEXT)) < 0)
        {
            fprintf(stderr, "write to %s failed, reason: %s. \nexit. \n", filename, strerror(errno));
        }

        printf(" %d\n", i+1);
    }
    printf(" finished. \n");

    //int ret = fsync(fd);
    //if (ret) fprintf(stderr, "write failed. reason: %s\n", strerror(errno));

    printf("Start to sleep 30 seconds .......\n");
    sleep(30);

    close(fd);
    return 0;
}

int writeToFile(int fd, char *buf, int len)
{
    int wlen = 0;
    if (wlen = write(fd, buf, len) < 0)
    {
        fprintf(stderr, "write to %d failed. reason: %s \n", fd, strerror(errno));
        return -1;
    }

    //fsync(fd);
    return wlen;
}

编译执行
在这里插入图片描述
这里报错了
在这里插入图片描述

原因直接访问硬盘, 硬盘的单位是扇区-硬盘的最小存储单位(Sector), 一般每个扇区存储存储512字节(相当于0.5KB), 因此必须是512字节.
这样子还是不行的(要求太多, 因为是直接访问硬盘), 还需分配的地址是512的整数倍.
这里用到了 posix_memalign

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

#define TOTAL 10
#define BUF_LEN 512

int main(int argc, char *argv[])
{
    //const char *TEXT = "This is a test.\n";
    char *buf = NULL;
    const char *filename = "./write.txt";
    int fd = -1;
    int i = 0;

    //buf = (char *)malloc(BUF_LEN); //error
    posix_memalign((void **)&buf, 512, BUF_LEN);
    strcpy(buf, "This is a test.\n");

    fd = open(filename, O_RDWR|O_TRUNC|O_CREAT|O_DIRECT);
    if (fd < 0)
    {
        fprintf(stderr, "fopen %s failed, reason: %s. \nexit.\n", filename, strerror(errno));
        return -1;
    }

    for (i = 0; i < TOTAL; i++)
    {
        //sleep(1);
        //if (writeToFile(fd, TEXT, strlen(TEXT)) < 0)
        if (writeToFile(fd, buf, BUF_LEN) < 0)
        {
            fprintf(stderr, "write to %s failed, reason: %s. \nexit. \n", filename, strerror(errno));
        }

        printf(" %d\n", i+1);
    }
    printf(" finished. \n");

    //int ret = fsync(fd);
    //if (ret) fprintf(stderr, "write failed. reason: %s\n", strerror(errno));

    printf("Start to sleep 30 seconds .......\n");
    if (buf) free(buf);
    sleep(30);

    close(fd);
    return 0;
}

int writeToFile(int fd, char *buf, int len)
{
    int wlen = 0;
    if (wlen = write(fd, buf, len) < 0)
    {
        fprintf(stderr, "write to %d failed. reason: %s \n", fd, strerror(errno));
        return -1;
    }

    //fsync(fd);
    return wlen;
}

运行结果
在这里插入图片描述
在这里插入图片描述
只需512内存边界分配的地地址
在这里插入图片描述

在这里插入图片描述

硬件开发和驱动开发, 分配的内存要有一定的要求.

结语:

在这里插入图片描述

时间: 2020-08-15

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值