Linux学习(四)文件及虚拟内存

本块内容学习

文件:文件内容操作:

                创建,打开文件

                读写文件

                文件内容指针操作

                关闭保存文件

        文件操作:

                拷贝,复制,移动,获取文件信息

        文件映射

        文件夹遍历


1.文件基本操作

在linux中使用int类型来对应一个文件相对C中的File*,相当于C++中的fstream

linux中文件相关函数

int open(                           失败返回-1,成功返回fd(file descriptor)

const char* filename,        文件名称

int flags,                            创建或打开文件方式

mode_t mode);                 文件权限
#include <unistd.h>

int close(int fd);  //文件对象fd

用法与C语言基本一致,但比C语言中的简单,可使用man 2 open 或者man 2 close来查看相关使用手册。

read函数

ssize_t read(int fd, void *buf, size_t count);
//fd,文件对象
//buf,用来存储读取的值的变量
//buf的大小(字节)

成功返回读取到的字节数,0表示读取结束

发生错误返回-1
 


文件指针

lseek函数

off_t lseek(int fd, off_t offset, int whence);//fd,文件对象
//offset移动位置数,//whence指针的位置状态
(SEEK_SET
              The file offset is set to offset bytes.

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

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

文件复制相关

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int srcFd;
    int dstFd;

    srcFd = open(argv[1], O_RDONLY);
    dstFd = open(argv[2], O_WRONLY | O_CREAT, 0666); //代表八进制666

    char buf[1024]; // 读取到的内容的存放区域
    int r;          // 每次读取字节数
    while (1)
    {
        r = read(srcFd, buf, 1024);
        if (r > 0)
        {
            write(dstFd, buf, r);
        }
        else
        {
            break;
        }
    }
    close(srcFd);
    close(dstFd);

    return 0;
}

还可以使用cp命令的方式来执行 


获取文件状态

int stat(const char *pathname, struct stat *statbuf);

可获取到很多文件的状态。


2.文件映射及虚拟内存

把文件映射到内存中

文件映射虚拟内存编程模型

1.打开文件  open

2.修改文件大小   ftruncate

3.挂载映射   使用mmap函数

4.使用虚拟内存(文件)  指针方式使用

5.卸载映射  munmap

6.关闭文件  close

void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);
//addr,地址
//length,长度
//prot,保护方式,PROT_READ|PROT_WRITE
//flags,flags参数决定对映射的更新是否对映射同一区域的其他进程可见,以及是否将更新传递到底层文件。
//int fd,文件描述符号(文件)
//offset,文件开始偏移位置
void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);

映射内存方式操作文件与普通文件读写对比:

// 使用内存映射的方式操作文件
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <time.h>
#include <string.h>

typedef struct student
{
    int age;
    char name[20];
    double score;
} student;

int main()
{
    int fd = open("2.txt", O_RDWR | O_CREAT, 0666);

    ftruncate(fd, 100000 * sizeof(student));

    student *p = mmap(NULL, 100000 * sizeof(student), PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    if ((void *)-1 == p)
    {
        printf("映射内存失败:%m");
        close(fd);
        exit(-1);
    }
    printf("映射内存成功\n");
    student *pp = p;

    printf("开始循环操作内存\n");
    int n = 100000;
    time_t begin = time(NULL);
    while (n--)
    {
        pp->age = 24;
        strcpy(pp->name, "梁志雄");
        pp->score = 99.9;
        if (n != 0)
        {
            pp++;
        }
    }
    time_t end = time(NULL);
    printf("使用的秒数:%ld\n", end - begin);
    int ret = munmap(p, 100000 * sizeof(student));
    if (ret)
    {
        printf("munmap失败\n");
        close(fd);
        exit(-1);
    }
    printf("munmap成功\n");
    close(fd);
    return 0;
}

以上是使用内存操作文件进行写入内容的代码,使用了一秒时间。

以下是使用常规方式操作文件进行写入的代码:

// 使用普通文件写入的方式操作文件
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

typedef struct student
{
    int age;
    char name[20];
    double score;
} student;

int main()
{
    int fd;

    fd = open("1.txt", O_WRONLY | O_CREAT, 0666);

    student p = {24, "梁志雄", 99.9};
    // char buf[1024]; // 读取到的内容的存放区域
    int r; // 每次读取字节数
    int n = 100000;
    time_t begin = time(NULL);
    while (n--)
    {
        write(fd, &p, sizeof(student));
    }
    close(fd);
    time_t end = time(NULL);
    printf("使用的秒数:%ld\n", end - begin);
    return 0;
}

该方式使用了17秒,如下图,可见,使用内存映射操作文件的方式速度快了不止一点。短短的1秒就进行了10万次数据写入操作。


3.文件复制

使用cp命令来完成操作Linux常用命令cp详解_cp指令-CSDN博客


4.文件移动

Linux基础命令(三)文件的移动、删除、复制 详细_将/mnt下文件hello.txt文件移动到/tmp下-CSDN博客


 5.文件夹遍历

使用shell脚本及递归实现

function getdir(){
    echo $1
    for file in $1/*
    do
    if test -f $file
    then
        echo $file
        arr=(${arr[*]} $file)
    else
        getdir $file
    fi
    done
}
getdir .
echo ${arr[@]}

函数调用方式getdir 参数

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay/.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值