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

Linux文件系统基本概念

Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第1张图片

文件系统接口
文件系统 -一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问。
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第2张图片

文件系统缓存
主存(通常是DRAM)的一块区域,用来缓存文件系统的内容,包含各种数据和元数据。
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第3张图片

文件I0访问方式概述

标准文件访问方式
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第4张图片
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第5张图片
直接IO
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第6张图片
实现方式
open +O_DIRECT = 绕过内核缓冲区的直接访问,便有效避免了CPU和内存的多余时间开销。
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第7张图片
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第8张图片
如果读取的数据只用一次,就不用读取了(如数据库)。就没有必要,使用高速页缓冲。

直接IO代码演示

Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第9张图片

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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;
}

编译执行
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第10张图片
这里报错了
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第11张图片

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

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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;
}

运行结果
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第12张图片
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第13张图片
只需512内存边界分配的地地址
Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第14张图片

Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第15张图片

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

结语:

Linux服务器 - 文件操作 | 标准I/O库 | Linux文件IO深入剖析_第16张图片

时间: 2020-08-15

你可能感兴趣的:(Linux服务器,内核,linux,嵌入式)