本块内容学习
文件:文件内容操作:
创建,打开文件
读写文件
文件内容指针操作
关闭保存文件
文件操作:
拷贝,复制,移动,获取文件信息
文件映射
文件夹遍历
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 参数