Linux内核编程 文件IO系统调用

目录

一:Linux内核函数

二:ubuntu环境下的文件掩码

三:VS2019 Linux跨平台开发

四:Linux控制台输出

五:open函数

六:write函数

七:read函数

八:文件的拷贝操作


一:Linux内核函数

Linux内核函数【文件系统调用】

open系统调用

read系统调用

write系统调用

create系统调用

close系统调用

mkdir系统调用

 需要学会在ubuntu中自己查看函数,并且学会使用函数

命令示例              man 2 open        查看open函数的使用说明

man open
man 2 open

查看完使用手册之后,按下q退出手册

二:ubuntu环境下的文件掩码

umask 文件掩码             umask查看 默认文件掩码是 0022  如下图所示

umask

默认的文件掩码是0022 

对于0022,首先需要先了解一下 9个权限位

目录第一位是 d

文件第一位是 -

9个权限位 3个为一组 分为:

文件拥有者 、同组 、其他用户

                                    rwx                         rwx                      rwx 

[3个为一组,第一组文件拥有者、第二组为同组、第三组为其他用户] 

r:  可读        4

w: 可写        2

x:  可执行    1

都可以则4+2+1=7

可读可写可执行 : 0777

三:VS2019 Linux跨平台开发

对初次使用VS2019,在Linux控制台编译运行     这个使用过程不大了解的朋友们

可以阅读下这个小节

【window下创建工程编写代码        Linux环境下编译运行程序】

首先 右键新建项目

选择空项目 

选择C++

选择Linux

 工程名称命令 存储位置设置 

右键项目、添加、新建项 

  可以规范命名为:main.cpp

运行测试中必须要设置断点    (window下编程,Linux下运行,跨平台开发)

对于跨平台编程要求:严格编写代码、换行必不可少

因为 Linux控制台输出,需要换行标识、断点,来确定结束位

点击全部保存

点击运行

在运行结束后可以点击上方小红框结束运行

以上即为VS2019跨平台编程的基础使用

四:Linux控制台输出

window环境下 VS2019编写的代码工程

保存在

Linux环境下 home目录下 project中

open函数 使用示例

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

using namespace std;

int main()
{
    open("/root/123.txt", O_CREAT | O_WRONLY, 0777);

	return 0;
}

在Linux环境下,看出 123.txt创建成功 

可视化操作查看一下新创建的123.txt的文件权限 


也可以使用 命令的方式 来查看一下新创建的123.txt的文件权限

在这个查看过程中可以发现

无论可视化还是命令行查看文件权限

均不符合自己代码所设置的文件权限 [0777 可读可写可执行]

现在查看到的权限位是

-rwxr-xr-x也就是0755

为什么编程中设置文件权限为0777,最后创建的文件权限却是0755呢???

因为权限掩码umask 0022的存在:0777-0022即是0755

清除命令                 clear

clear

umask                    查看一下文件掩码         0022

umask

权限掩码也就是做一个权限保护

不过可以在编程中也是可以修正的:umask(0);【文件权限设置为所写即所得】

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


using namespace std;

int main()
{
	umask(0);
    open("/root/123.txt", O_CREAT | O_WRONLY, 0777);

	return 0;
}

 在使用了umask(0);后,再可视化查看一下123.txt的文件权限

也可以使用 命令的方式 查看一下123.txt的文件权限

可以看到123.txt权限为可读可写可执行,因此umask(0);需要记得在设置权限时补充

五:open函数

在Linux环境下

可以使用命令查看手册进行学习open函数              man 2 open

man 2 open

如上图,可以看出两种写法的返回都是int类型 

往下 可以查看 参数说明

再往下可以看到return value返回值说明

都会返回一个新的[文件描述符 (fd)]

file descriptor文件描述符,可简写为fd

或者会返回-1(代表错误)

对于文件描述符的值也是可以打印查看的

可以先把linux环境下的123.txt文件删掉

再次运行代码

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


using namespace std;

int main()
{
	umask(0);
	int fd = open("/root/123.txt", O_CREAT | O_WRONLY, 0777);

	cout << "fd = " << fd << endl;

	return 0;
}

可以看到:fd文件描述符值为3 ,为什么呢?

特殊文件描述符号

标准输入STDIN_FILENO

标准输出STDOUT_FILENO

标准错误STDERR_FILENO

每个进程被加载后,默认打开0,1,2这三个文件描述符 

操作系统本身有的0 1 2已经占用,所以自己创建的文件描述符fd=3 

	int fd = open("/root/123.txt", O_CREAT | O_WRONLY, 0777);

再次执行如上代码:文件不存在会创建文件,文件存在则是打开而不是再创建

perror 来自库函数    stdio.h

六:write函数

可以打开手册学习函数使用

man write

这个BSD不是自己想查看的

在ubuntu中查看内核函数使用手册

man xxx 若是不可以查看到,就 man 2 xxx

man 2 write

如上图才是write函数的使用手册

在编程时候,可复制头文件,使用write函数

文件分为两种:

一种是纯字符文件(文件中只有字符,没有其他,如txt,cpp,.h文件)

还有一个叫二进制文件(音频视频压缩包图片)

以ppt为例,ppt是二进制文件(因为可以放视频图片)

                    word文档是二进制文件(可以放图片)

如果成功,已经写入的字节会被返回(写入多少字节),返回写入的字节数,写成功返回大于0的数字

七:read函数

查看函数说明手册 

man read

如上图,由void *buf 知道 write和read函数是可以操作任意数据的

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


using namespace std;

int main()
{
	char buf[50] = {"hello linux"};
	umask(0);
	int fd = open("/root/123.txt", O_CREAT | O_WRONLY, 0777);

	if (fd == -1)
	{
		perror("open error");
	}
	else
	{
		cout << "fd = " << fd << endl;
		int res = write(fd, buf, sizeof(buf));
		cout << "res = " << res << endl;
	}

	return 0;
}
int res = write(fd, buf, sizeof(buf));

write函数返回

sizeof是要写入的长度,在代码中开空间是50

最后写入的字节数也是50

但是\00是属于没用的字符

可以先删除123.txt文件,再重新休整

因此需要将sizeof修改为strlen

忘记strlen头文件可以man查看一下 

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


using namespace std;

int main()
{
	char buf[50] = {"hello linux"};
	umask(0);
	int fd = open("/root/123.txt", O_CREAT | O_WRONLY, 0777);

	if (fd == -1)
	{
		perror("open error");
	}
	else
	{
		cout << "fd = " << fd << endl;
		int res = write(fd, buf, strlen(buf));
		cout << "res = " << res << endl;
	}

	return 0;
}

若Linux中没有删除123.txt文件

将char buf[50] = {"hello linux"};修改为char buf[50] = {"xxx"};

看下文件内容是否会被覆盖

这里的res是3字节(xxx)


但查看到的是11字节

因此说明是 从头覆盖了文件内容

由上述可知 若要追加内容,就直接使用追加(如下)

八:文件的拷贝操作

read函数

头文件、函数原型、函数返回

返回值是0就是文件末尾

错误是返回-1或者返回错误码

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


using namespace std;

int main()
{
	char buf[50] = { 0 };

	umask(0);
	int wfd = open("/root/copy1.txt", O_CREAT | O_WRONLY, 0777);
	int rfd = open("/root/123.txt", O_RDONLY, 0777);

	if (wfd == -1 || rfd == -1)
	{
		perror("open error");
	}
	else
	{
		int res = 0;
		while ((res = read(rfd, buf, sizeof(buf))) > 0)
		{
			int ws = write(wfd, buf, res);
			cout << "ws = " << ws << endl;
		}
		close(rfd);
		close(wfd);
		cout << "success" << endl;
	}
	return 0;
}

Linux控制台窗口中显示:6X50+30=330 

成功拷贝     123.txt文件

拷贝生成有  copy1.txt

若是将res修改sizeof,如下修改,再测试

int ws = write(wfd, buf, res);
int ws = write(wfd, buf, sizeof(buf));

Linux控制台显示:都是50 

Linux环境下,查看copy1.txt是350字节[出错]

对比上下图,不难看出拷贝出来的内容是错误的 

若是res修改为strlen,如下修改,再测试

int ws = write(wfd, buf, strlen(buf));

Linux控制台显示:都是54明显出错

原先330字节后面拷贝出378字节[明显出错]

 

对比查看,可以明显看出拷贝出的是错误的信息

综上测试

只能 res   读多少写多少 符合标准

int ws = write(wfd, buf, res);

当然,也可以拷贝图片

如下图所示,将3.jpg图片拷贝一份

拷贝图片 

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


using namespace std;

int main()
{
	char buf[50] = { 0 };

	umask(0);
	int wfd = open("/root/copy3.jpg", O_CREAT | O_WRONLY, 0777);
	int rfd = open("/root/3.jpg", O_RDONLY, 0777);

	if (wfd == -1 || rfd == -1)
	{
		perror("open error");
	}
	else
	{
		int res = 0;
		while ((res = read(rfd, buf, sizeof(buf))) > 0)
		{
			int ws = write(wfd, buf, res);
			cout << "ws = " << ws << endl;
		}
		close(rfd);
		close(wfd);
		cout << "success" << endl;
	}
	return 0;
}

图片成功拷贝 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chenruhan_QAQ_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值