Linux环境编辑——文件IO(一)

Linux提供的文件操作类的系统调用接口

open/close(映射和注销)
read/write
lseek

Linux提供的文件系统操作类系统调用接口

stat
acces
chown/chmod
flock
link/symlink/unlink
mkdir/chdir/opendir/readdir

文件IO的注册与注销

1、如何创建空文件

文件描述符的获取: open() /create()
在这里插入图片描述

  • open()和create()调用成功返回文件描述符,失败返回-1,并设置errno
  • open()和create()调用返回的文件描述符一定是最小的未用描述符数字
  • create()等价于open(pathname,O_CREAT|O_WRONLY|O_TRUNC,mode)
  • open()可以打开设备文件,但是不能创建设备文件,设备文件必须使用mknod()创建
    这些函数完成的是将内核驱动跟用户空间中的文件描述符建立映射关系
    在这里插入图片描述

实验:

int main() {
    int fd;
    fd = open("a.txt",O_CREAT | O_RDWR ,0666);
    if (fd == -1){
        perror("open");
        return -1;
    }
//    getchar();
//    printf("Hello, World!\n");
     write(fd,"Hello, World!",15);
    close(fd);
    return 0;
}

第一次执行得到的a.txt的内容为:
在这里插入图片描述
修改一下代码,再次执行:

int main() {
    int fd;
    fd = open("a.txt",O_CREAT | O_RDWR ,0666);
    if (fd == -1){
        perror("open");
        return -1;
    }
//    getchar();
//    printf("Hello, World!\n");
     write(fd,"123",3);
    close(fd);
    return 0;
}

请问:此时的a.txt里面是什么?
A.123
B.123Hello, World!
C.Hello, World!123
D.Hello, World!


正确答案:E:123lo, World!
执行结果:
在这里插入图片描述
解析:因为光标每次是首位开始写的


文件编译工具
工程管理器:
以前:通过Makefile来管理哪些 .c文件编译
Clion
自带的Cmake:cmakelists.txt 《=》类似于以前的Makefile
Clion的cmakelists.txt创建工程时会自动生成,如:

版本限制
cmake_minimum_required(VERSION 3.22) 
工程名,以及工程使用的语言比如也可以增加为C、CPP、asm
project(ClionProject C)
设置一个变量,告诉我们当前使用的C的标准
set(CMAKE_C_STANDARD 99)
添加一个可执行文件  其中,前者表示生成的可执行文件,后者表示源文件
add_executable(ClionProject main.c)
编译后就会在当前工程目录看见一个可执行文件:

在这里插入图片描述

写文件案例实验:

/*
 * 1、在Linux下创建一个新文件,可以使用open/create系统调用接口
 * create实际是open的便捷写法,但缺乏灵活性,如果明确创建新文件,可以使用create
 * 2、create的flags等价O_CREAT|O_WRONLY|O_TRUNC
 * 3、如果文件存在,使用open打开,如果使用create,那么原文件内容将清除
 *
 * 思考题:
 * 1、为什么程序设计0666或者0777,实际创建的文件权限可能不是这个值
 * */
int lesson1() {
    int fd;

    fd = creat(NEW_FILE_NAME, 0666);
    if (fd == -1) {
        perror("open");
        return -1;
    }
    printf("create new file success!\n");

    close(fd);
    return 0;
}

/*
 * 1、如果文件不存在,直接open,将会报"No such file or directory"错误
 * 2、文件是否存在,使用O_CREAT不会出错影响,但只要加上O_EXCL才会报错,这个选项一般用作单例进程使用
 * 3、O_TRUNC代表文件内容清空,一般用于临时文件,只要打开就使用全新的内容
 * */
int lesson2() {
    int fd;

//    fd = open(NEW_FILE_NAME, O_CREAT | O_RDWR, 0666);
    fd = open(NEW_FILE_NAME, O_RDWR, 0666);
//    fd = open(NEW_FILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);
//    fd = open(NEW_FILE_NAME, O_CREAT | O_TRUNC | O_RDWR, 0666);
    if (fd < 0) {
        perror("open");
        return -1;
    }
    printf("open new file success!\n");

    close(fd);
    return 0;
}

int main()
{
    lesson1();

    return 0;
}

可以看到,此时,执行成功,在该目录下创建了文件
在这里插入图片描述
然后用vim 打开该文件,写入字符123并保存
在这里插入图片描述

可以看到最后显示该文件有4个字节,而实际只写入了3个字节
原因:vim创建打开的文件会自动添加一个换行符。


ps:
可以使用od命令:以二进制形式查看文件存储形式(看文件本身内容)
如果记不住了可以使用:od --help
在这里插入图片描述
在这里插入图片描述

如:od -t x tmp_new.txt
在这里插入图片描述
ps:1、2、3对应的16进制字符的ACSII码是31、32、33
但是这样看着是挤在一起的,x后面不跟是默认是4个一起,因此x后面加一个1,一个字符一个字符的来看

od -t x1 tmp_new.txt
在这里插入图片描述
再在tmp_new.txt文件中的123后面写一个中国会怎么样?
在这里插入图片描述
此时的字符数量变成了10个
在这里插入图片描述
再执行 od -t x1 tmp_new.txt
在这里插入图片描述
一个字用三个字符来表示


回到代码,在文件已经存在的情况再次执行代码:
没有报错,还是文件创建成功:
在这里插入图片描述
之前是10个,再次执行后又变成了0个
在这里插入图片描述
Creat()函数在原始文件存在的情况下仍然可以创建 是因为,create的flags是等价于:O_CREAT|O_WRONLY|O_TRUNC
O_CREAT:如果该文件不存在就创建,并用mode的参数值为其设置权限
O_WRONLY:可写的方式打开文件
O_TRUNC:如果文件已经存在,那么打开文件时先删除文件中原有数据

ps:参考数值权限:
对于某一个文件,Linux系统中分为三类处理的人:
1、文件和文件目录的拥有者:u-user
2、文件和文件目录拥有者所在的组的用户:g-Group
3、其他用户:o-Others

可以看到对于每一个文件都有:
在这里插入图片描述
这里主要说权限:

r: 只读、w: 写入、x: 可执行

-rw——- (即110 000 000,二进制对应10进制就为:6 0 0) 只有所有者才有读和写的权限,因此,代码为600

-rw-r–r– (644) 只有所有者才有读和写的权限,组群和其他人只有读的权限

-rwx—— (700) 只有所有者才有读,写,执行的权限

-rwxr-xr-x (755) 只有所有者才有读,写,执行的权限,组群和其他人只有读和执行的权限

-rwx–x–x (711) 只有所有者才有读,写,执行的权限,组群和其他人只有执行的权限

-rw-rw-rw- (666) 每个人都有读写的权限

-rwxrwxrwx (777) 每个人都有读写和执行的权限


继续回到实验:
有一种场景:文件不存在我就创建再打开,但是文件在每次打开时不能清空,此时creat()不能使用,只能用open()

先把当前目录下的tmp_new.txt删掉

选择 lesson2()再次执行代码

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

#define NEW_FILE_NAME "/tmp/temp/tmp_new.txt"

/*
 * 1、在Linux下创建一个新文件,可以使用open/create系统调用接口
 * create实际是open的便捷写法,但缺乏灵活性,如果明确创建新文件,可以使用create
 * 2、create的flags等价O_CREAT|O_WRONLY|O_TRUNC
 * 3、如果文件存在,使用open打开,如果使用create,那么原文件内容将清除
 *
 * 思考题:
 * 1、为什么程序设计0666或者0777,实际创建的文件权限可能不是这个值
 * */
int lesson1() {
    int fd;

    fd = creat(NEW_FILE_NAME, 0666);
    if (fd == -1) {
        perror("open");
        return -1;
    }
    printf("create new file success!\n");

    close(fd);
    return 0;
}

/*
 * 1、如果文件不存在,直接open,将会报"No such file or directory"错误
 * 2、文件是否存在,使用O_CREAT不会出错影响,但只要加上O_EXCL才会报错,这个选项一般用作单例进程使用
 * 3、O_TRUNC代表文件内容清空,一般用于临时文件,只要打开就使用全新的内容
 * */
int lesson2() {
    int fd;

    fd = open(NEW_FILE_NAME, O_CREAT | O_RDWR, 0666);
//    fd = open(NEW_FILE_NAME, O_RDWR, 0666);
//    fd = open(NEW_FILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);
//    fd = open(NEW_FILE_NAME, O_CREAT | O_TRUNC | O_RDWR, 0666);
    if (fd < 0) {
        perror("open");
        return -1;
    }
    printf("open new file success!\n");

    close(fd);
    return 0;
}

int main()
{
    lesson2();

    return 0;
}


在这里插入图片描述
重新生成了该文件
在这里插入图片描述
然后再在该文件中写上123
在这里插入图片描述
然后再次运行代码:
这里只使用O_RDWR参数

fd = open(NEW_FILE_NAME, O_RDWR, 0666);

删除文件,再次执行该种参数下的open函数:
在这里插入图片描述
总结:如果没有文件,使用open时应该加上O_CREAT参数,该参数可以保证每次运行文件都是空的.

再修改open函数的参数为:

 fd = open(NEW_FILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);

再次运行:
第一次运行结果:
创建成功!
在这里插入图片描述
第二次运行:
报错
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Asita_c

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

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

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

打赏作者

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

抵扣说明:

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

余额充值