文件的写入 和 读取

文件的写入

需要包含的头文件

 #include 

相关的API函数

ssize_t write(int fd, const void *buf, size_t count);

参数说明

  • int fd :文件描述符
  • const void *buf :一个无类型的指针buf,是一个缓冲区
  • size_t count:要写入文件的大小

可以理解为write函数就是将count大小的数据,从buf缓冲区写到fd对应的文件里去

  • 返回值:成功则返回 写入的字节数,失败则返回 -1

实操演示

1. 将上节的demo1.c 复制一份并重命名为 demo2.c:

2. 同样使用man函数来查看write函数相关信息:(man 2 write)

文件的写入 和 读取_第1张图片

3. 在demo2.c中修改代码并保存退出:

#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
        int fd; // file description
        char *buf = "mjmmjm";

        fd = open("./file1",O_RDWR|O_CREAT, 0600);

        printf("file description = %d, open successfully!\n",fd);

        write(fd, buf, strlen(buf)); //对于字符串常量来说,使用sizeof求出的是系统用多少字节表示一个字符型指针,必须使用strlen才可以表示字符串的有效长度

        close(fd); //close after writing 

        return 0;
}

注释中提到过,这里再强调一下:

对于字符串常量来说,使用sizeof求出的是系统用多少字节表示一个字符型指针,必须使用strlen才可以表示字符串的有效长度

详见:C语言的字符串_mjmmm的博客-CSDN博客

4. 运行程序,并查看file1:

可见,成功写入!

 

文件的读取

需要包含的头文件

 #include 

相关的API函数

ssize_t read(int fd, void *buf, size_t count);

参数说明

  • int fd :文件描述符
  • const void *buf :一个无类型的指针buf,是一个缓冲区
  • size_t count:要读取文件的大小

可以理解为read函数就是从fd对应的文件中,读取count大小的数据放到buf缓冲区

  • 返回值:成功则返回 读取到的字节数,失败则返回 -1

这里涉及到一个从哪里开始读的问题,答案是从光标处开始读

实操演示

1. 将demo2.c 复制一份并重命名为 demo3.c:

2.  同样可以使用 man 2 read:

文件的写入 和 读取_第2张图片

3. 在demo3.c中修改代码并保存退出:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
	int fd; // file description
	char *buf = "mjmmjm";
	char *buf_read;

	fd = open("./file1",O_RDWR|O_CREAT, 0600);

	printf("file description = %d, open successfully!\n",fd);

	int count_write = write(fd, buf, strlen(buf));
	if(count_write != -1){
		printf("%d bytes data has been written",count_write);
		buf_read = (char *)malloc(sizeof(char)*count_write + 1); //为野指针开辟空间防止段错误,且由于malloc返回值是void类型的指针,所以需要强制类型转换成char类型的指针
	}else{
		printf("fail to write");
		exit(-1);
	}

	int count_read = read(fd, buf_read, count);
	if(count_read != -1){
                printf("%d bytes data has been read, context:%s\n",count_read, buf_read);
        }else{
                printf("fail to read");
        }


	close(fd); //close after reading 

	return 0;
}

4. 删除file1(避免之前写入过,导致结果不准确),并运行代码:

文件的写入 和 读取_第3张图片

可见,虽然代码的逻辑似乎没有问题,但是却一个字节都没有读到,原因就是刚刚提到的,读取文件存在一个“从哪里开始读”的问题,而由于刚刚对文件进行write操作之后,光标处于文件的末尾,所以从此时如果从光标处read,注定是无法读到任何信息的。

解决这个问题的方法有两种:

  • 将光标移到头再读
  • 将文件重新打开

5. 完善代码:

使用“重新打开文件”的方法解决问题:

这种方式比较好实现,但是效率不高而且思路有些反人类

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
	int fd; // file description
	char *buf = "mjmmjm";
	char *buf_read;

	fd = open("./file1",O_RDWR|O_CREAT, 0600);

	printf("file description = %d, open successfully!\n",fd);

	int count_write = write(fd, buf, strlen(buf));
	if(count_write != -1){
		printf("%d bytes data has been written\n",count_write);
		buf_read = (char *)malloc(sizeof(char)*count_write + 1);
	}else{
		printf("fail to write\n");
		exit(-1);
	}

	close(fd); //关闭文件
	fd = open("./file1",O_RDWR, 0600); //重新打开文件

	int count_read = read(fd, buf_read, count_write);
	if(count_read != -1){
                printf("%d bytes data has been read, context:%s\n",count_read, buf_read);
        }else{
                printf("fail to read\n");
        }


	close(fd); //close after reading 

	return 0;
}

实现效果:

文件的写入 和 读取_第4张图片

 

使用“移动光标”的方法解决问题:

关于光标的控制:

需要包含的头文件

#include 
#include 

相关的API函数

off_t lseek(int fd, off_t offset, int whence);

参数说明

  • int fd :文件描述符
  • off_t offset:偏移多少个字节
  • int whence:光标偏移位置

其中whence可以设置为 以下3个值中的一个

  • SEEK_SET:文件开头
  • SEEK_CUR:光标当前位置
  • SEEK_END:文件尾

可以理解为lseek函数就是将光标移到whence+offset的位置

  • 返回值:成功则 返回从文件开始的偏移了多少字节;发生错误时,返回 -1
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
	int fd; // file description
	char *buf = "mjmmjm";
	char *buf_read;

	fd = open("./file1",O_RDWR|O_CREAT, 0600);

	printf("file description = %d, open successfully!\n",fd);

	int count_write = write(fd, buf, strlen(buf));
	if(count_write != -1){
		printf("%d bytes data has been written\n",count_write);
		buf_read = (char *)malloc(sizeof(char)*count_write + 1);
	}else{
		printf("fail to write\n");
		exit(-1);
	}

	lseek(fd, 0, SEEK_SET); //将光标移到最开头

	int count_read = read(fd, buf_read, count_write);
	if(count_read != -1){
                printf("%d bytes data has been read, context:%s\n",count_read, buf_read);
        }else{
                printf("fail to read\n");
        }


	close(fd); //close after reading 

	return 0;
}

实现效果:

文件的写入 和 读取_第5张图片

你可能感兴趣的:(算法,linux,C语言)