第1关:文件的读写

任务描述

本关任务:编写一个从一个文件中读取最后10KB数据并复制到另一个文件,注意观察缓存大小OFFSET对运行效率的影响。

相关知识

为了完成本关任务,你需要掌握:
1.如何使用C语言读取文件;
2.如何使用C语言写入文件。

open函数

open是UNIX系统(包括LINUX、Mac等)的系统调用函数。
lseek函数需要的头文件及原型如下:

//头文件
#include <unistd.h>
#include <fcntl.h>
//原型
int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);

打开/创建文件时,至少得使用下述三个常量中的一个:

O_RDONLY只读模式
O_WRONLY只写模式
O_RDWR读写模式

以下常量是选用的:

O_APPEND每次写操作都写入文件的末尾
O_CREAT如果指定文件不存在,则创建这个文件
O_EXCL如果要创建的文件已存在,则返回-1,并且修改errno的值
O_TRUNC如果文件存在,并且以只写/读写方式打开,则清空文件全部内容(即将其长度截短为0)
O_NOCTTY如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O
O_DSYNC等待物理I/O结束后再write。在不影响读取新写入的数据的前提下,不等待文件属性更新。
O_RSYNCread等待所有写入同一区域的写操作完成后再进行
O_SYNC等待物理I/O结束后再write,包括更新文件属性的I/O

以只写模式并且当文件不存在时创建该文件的方式打开文件名为"a.txt"的文件。
示例如下:

file = open("a.txt", O_WRONLY, O_CREAT);

lseek函数

lseek是一个用于改变读写一个文件时读写指针位置的一个系统调用,系统调用用来移动读写指针的位置,指针位置可以是绝对的或者相对的;
调用成功时返回当前的读写位置,也就是距离文件开始处多少字节,若有错误返回-1

lseek函数需要的头文件及定义函数如下:

//头文件
#include<sys/types.h>
#include<unistd.h>
//原型
lseek(int filde,off_t offset ,int whence);

可以用以下常量进行操作:

EEK_SET 将读写位置指向文件头后再增加offset个位移量。
SEEK_CUR 以目前的读写位置往后增加offset个位移量。
SEEK_END 将读写位置指向文件尾后再增加offset个位移量。

read函数

read函数是系统调用从文件描述符fd指向的文件中,读取count个字节到buf中;
如果read成功,则返回读到的字节数,如果已达到结尾,则返回0,出错,返回-1
函数原型:

//头文件
#include <unistd.h>
//原型
ssize_t read(int fd, void *buf, size_t count);

参数说明:

fd:文件描述符
buf:保存读入信息的缓存
count:要读取的字节数

write函数

write系统调用将buf所指向的缓冲区的count个字节内容写入fd指向的文件;
如果write成功,则返回写入的字节数,出错返回-1
函数原型:

//头文件
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

参数说明:

fd:要写入的文件
buf:要写入的信息所在的缓存
count:要写入的字节数

编程要求及注意事项

根据提示,在右侧编辑器注释处补充代码,一共需要补充四处;
已生成读取的文件src_file, SRC_FILE_NAME为其所在位置;
预期输出目标文件为dest_file,DEST_FILE_NAME为其预期所在位置;
注意观察缓存大小OFFSET对运行效率的影响。

测试说明

平台会对你编写的代码进行测试,比对输出结果。


开始你的任务吧,祝你成功!

代码参考

 #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

#define BUFFER_SIZE 1024
//请不要更改文件路径!!!
#define SRC_FILE_NAME "/data/workspace/myshixun/fileSystem/src/fileProgram/src_file"
//请不要更改文件路径!!!
#define DEST_FILE_NAME "dest_file"
#define OFFSET 10240

int main()
{
    
    
	int src_file,dest_file;
	unsigned char buff[BUFFER_SIZE];
	int real_read_len;

    //请在此处填入代码,使用合适的模式打开源目标SRC_FILE_NAME文件
	src_file = open(SRC_FILE_NAME, O_RDONLY);
    //请在此处填入代码,使用合适的模式打开写入文件目标DEST_FILE_NAME文件,需要考虑到文件是否存在?
    dest_file = open(DEST_FILE_NAME, O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    // dest_file = open(DEST_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0777);
    
	if(src_file < 0 || dest_file < 0)
	{
    
    
		printf("Open file error!\n");
		exit(1);
	}

    //请在此处填入代码,设置偏移量读取文件最后10KB数据
    lseek(src_file, - OFFSET, SEEK_END);

	while((real_read_len =  read(src_file,buff,sizeof(buff))) > 0)
	{
    
    
        //请在此处填入代码,使用buff写入目标文件
		write(dest_file, buff, real_read_len);
	}
	close(dest_file);
	close(src_file);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_46373141/article/details/131102347