Linux下编程之I/O操作(一)

Linux下编程I/O操作(一)

最近刚刚回国, 因为疫情的缘故在上海隔离. 闲来无事,想要复习复习Linux的相关知识, 最近看到了关于文件的I/O操作, 特来此记录一下, 以后忘记了也能看看.
Linux下的I/O 操作比较常用的有4个函数, 分别是: open(), read(),write(),close.()和windows下的fopen()之类的函数相似.

open()

函数原型如下:

#include <sys/stat.h>
#include <fcntl.h>

//函数原型
int open(const char* pathname, int flags, .../*mode_t mode*/);
//Returns file descriptor on success, or -1 on error

顾名思义, 这个函数是用来打开文件的,当文件打开成功时, 会返回一个int型文件描述符,以便后面的read(),write()使用.
现在让我们来分析分析其中的参数:
pathname : 文件名称或者是路径
flags: 这个参数意味着访问文件的模式,
第三个参数可有可无: 如果你要访问的文件不存在的话, 可以在flags(第二个参数)使用O_CREATE创建一个, 创建之后需要对该文件的一些访问权限进行初始化, 这第三个参数就是用来设置文件的访问权限的.

下面来看一下都有些什么标志(flags):

标志用途
O_RDONLY以只读的方式打开
O_WRONLY以只写的方式打开
O_RDWR以读写的方式打开
O_CLOEXEC设置 close-on-exec 标志
O_CREAT若文件不存在则创建之
O_DIRECT无缓冲的输出/输出
O_DIRECTORY如果pathname不是目录, 则失败
O_EXCL结合O_CREAT参数使用, 专门用于创建文件
O_LARGEFILE在32位系统中使用此标志打开大文件
O_NOATIME调用read()时,不修改文件最近访问的时间
O_NOCTTY不要让pathname成为控制终端
O_NOFOLLOW对符号链接不予解引用
O_TRUNC截断已有文件,使其长度为零
O_APPEND总在文件尾部追加数据
O_ASYNC当I/O操作可行时,产生信号同志进程
O_DSYNC提供同步的I/O数据完整性
O_NONBLOCK以非阻塞方式打开
O_SYNC以同步方式写入文件

下面介绍一下第三个参数中的可选项

标志语义
S_IRUSR用户可读
S_IWUSR用户可写
S_IRGRP用户组可读
S_IWGRP用户组可写
S_IROTH其他人可读
S_IWOTH其他人可写

上面的选项挑着用就行了, 我一般时这么写的:

mode_t open_perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH|;
//--rw-r-r

read()

函数原型如下:

#include <unistd.h>
//函数原型
ssize_t read(int fd, void *buffer, size_t count);
//Returns number of bytes read, 0 on EOF, or -1 on error

这个函数可以读取文件中的数据, 并且将数据保存在buffer中,以供使用.
并且这个函数会反悔读取了多少的字节数.
分析一下参数:
fd: open()函数返回的文件描述符.
buffer: 文件中的数据将被保存在这里.
count: 限制了一次读取多少字符,这与buffer的大小有关.

write()

#include <unistd.h>
//函数原型
ssize_t write(int fd,void *buffer, size_t count);
//Returns number of bytes written, or -1 on error

write的调用与read类似,只不过是将读取的buf写入到文件中罢了.
分析一下参数:
fd: open()函数返回的文件描述符.
buffer: buffer参数为要写入文件中数据的内存地址.
count: 为欲从buffer写入文件的数据自己数.

close()

函数原型:

#include <unistd.h>
int close(int fd);
//Returns 0 on success, or -1 on error

关闭文件,没什么可说的

lseek()

函数原型:

#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
//Returns new file offset if successful, or -1 on error

这个函数是用来指定文件偏移量的。
对于每个打开的文件, 系统内核会记录其文件偏移量。文件偏移量是指执行下一个read()或write()操作的文件起始位置,会以相对于文件头部起始点的文件当前位置来表示。文件第一个字节的偏移量为0.

文件空洞(科普向)

如果程序的文件偏移量依然跨越文件结尾, 然后再执行I/O操作, 将会发生什么情况呢?
read()调用将会反回0, 表示文件结尾. 从文件结尾后到新写入数据见的这段空间被称为文件空洞. 从编程的角度来看,文件空洞中是存在字节的,读取空洞将返回以0填充的缓冲区.

模仿linux下CP命令

#include <stdio.h> //C标准库
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define BUF_SIZE 1024

int main(int argc, char *argv[])
{
	char BUF[BUF_SIZE];
	ssize_t read_size;
	if(argc < 3 || strcmp(argv[1],"--help") == 0)
	{
		printf("按以下格式输入: /.CP file_name1 file_name2\n");
		exit(0);//进程退出
	}
	else
	{
		int inputfd = open(argv[1],O_RDONLY);
		if(inputfd == -1)
		{
			printf("找不到该文件\n");
			exit(0);
		}

		//经过测试 上下两行没有区别
	//	int open_flags = O_CREAT|O_TRUNC|O_WRONLY;
		int open_flags = O_CREAT|O_TRUNC|O_RDWR;
		//文件访问权限, --rw--rw--rw
	       	mode_t file_perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;


		int outputfd = open(argv[2],open_flags,file_perms);
		while((read_size = read(inputfd,BUF,BUF_SIZE)) > 0)
		{
			if(write(outputfd,BUF,read_size)!=read_size)
				printf("没有完全复制\n");
		}
		if(read_size == -1)
		{
			printf("打开文件失败\n");
		}

		//关闭被复制的文件

		close(inputfd);
		close(outputfd);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值