Linux 系统编程 开篇/ 文件的打开/创建

从本节开始学习关于Linux系统编程的知识!

学习Linux的系统编程有非常多的知识点,在应用层面,很重要的一点就是学习如何“用代码操作文件来实现文件创建,打开,编辑等自动化执行

那如何自动化实现对文件的创建,打开,编辑等呢?答案就是使用Linux系统提供的一系列API函数(如 open, write/read, lseek,close等等)。

Linux文件编程的一般步骤

总结一下就是,打开文件,以及读写操作之后关闭文件的操作都不是必不可少的。 

Linux 文件管理 

简单来说,现在学习的用户层面的操作就是给内核发送指令,让内核来驱动物理磁盘进行操作 

 

打开/创建文件

需要包含的头文件:

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

相关的API函数: 

int open(const char *pathname, int flags); //pathname是文件路径,flags是权限
int open(const char *pathname, int flags, mode_t mode);

int creat(const char *pathname, mode_t mode);

open函数

当调用open打开一个文档之后,open函数会返回一个非负整数,这个整数就是文件描述符

如果对一个文档都进行了open,并返回了“2”,之后又想对其进行write,就是write(2)

如果返回为负数,则说明open失败!

也就是说,

文件标识符0可以指代键盘输入

文件标识符1可以指代键盘输出

且文件描述符只在当前进程有效!

参数说明

pathname

  • 要打开的文件名(含路径)

flags : 

  • O_RDONLY 只读打开
  • O_WRONLY 只写打开
  • O_RDWR 可读可写打开

当附带了权限后,打开的文件就只能按照这种权限来操作

以上这三个参数中应当只指定一个。下列参数是可选择的:

  • O_CREAT:若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode.用其说明该新文件的存取许可权限。
  • O_EXCL:以这种属性去打开文件时,如果同时指定了O_CREAT,而文件已经存在,则打开文件失败(也可以说返回值是-1)。
  • O_APPEND:以这种属性去打开文件时,每次写时都加到文件的尾端。(不想写入时文件被覆盖,用这个flag,正常写入没有加其他条件的话,原来文件中的数据内容会被覆盖,注意是覆盖,覆盖本身的字节长度,没有覆盖的会保留,不是删除)
  • O_TRUNC:以这种属性去打开文件时,如果这个文件中本来是有内容的, 而且为只读或只写成功打开,则将其长度截短为0,通俗点的意思就是把原来的文件中的内容删除,写入你自己要的数据内容
  • Mode:一定是在flags中使用了 O-CREAT 标志, mode 记录待创建的文件的访问权限

关于mode的值和权限的对应关系:

共有三种权限

  • 是否可读(r), 对应数字4
  • 是否可写(w), 对应数字2
  • 是否可执行(x), 对应数字1

共有三个权限分配的对象

  • 主用户
  • 同组用户
  • 其他组用户

比如:给的是0600时,则对应权限“-rw-------”,即只给主用户分配可读可写(4+2=6)的权限同组用户(第三位)和其他组用户(第四位)没有任何权限

除了0600这种表达方式,Linux也直接提供了一些宏来表示:

其中较为常用的是:

  • S_IRWXU:对主用户来说可读,可写,可执行
  • S_IRUSR:对主用户来说可读
  • S_IWUSR:对主用户来说可写
  • S_IXUSR:对主用户来说可执行

实操演示

1. 创建一个名为“FILE”的文件夹,将文件部分的学习代码都放进去,并在cmd中cd到FILE:

2. 使用touch指令创建一个新的文件:

关于touch指令,可以参考:

Linux命令之touch命令_touch linux_恒悦sunsite的博客-CSDN博客

3.  使用vi命令创建一个c文件:

关于vi模式下的一些操作,之前接触过,参考:

Linux 系统初识_mjmmm的博客-CSDN博客

4.  使用man命令查看open相关的函数:

man的使用参考:

Linux下的man命令_linux man命令_邓永豪的博客-CSDN博客

简单来说就是 “man + 函数对应的手册号 + 函数名” 其中手册号是1~9,常用前3个,实在不知道可以一个个试,手册号不加也没事

然后就可以看到对于open函数的描述,这样就方便在Linux系统里面直接查阅和复制

5. 编写demo1.c,然后保存退出:

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

int main()
{       
        int fd; // file description
        fd = open("./file1",O_RDWR);
        
        printf("file description = %d\n",fd);
        return 0;
}       

 6. 运行demo1.c:

可见,我创建的文档“file1”被自动打开,并分配了文件描述符“3”

7. 此时,如果将 file1 删除,再执行一遍代码:

可见,返回-1,返回失败

O_CREAT参数的应用

在实际应用中,我如果不希望一个文件不存在就直接返回失败,那么可以在open函数中,添加上面提到的“O_CREAT”参数,就可以“若文件不存在则创建它”,并按要求增加“mode”参数:

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

int main()
{
        int fd; // file description
        fd = open("./file1",O_RDWR|O_CREAT, 0600); //0600代表即将创建的文件“可读可写”

        printf("file description = %d\n",fd);
        return 0;
}

此时,在file1不存在的情况下open,依然会返回正常的文件标识符,并创建file1:

O_EXCL参数的应用

O_EXCL:以这种属性去打开文件时,如果同时指定了O_CREAT,而文件已经存在,则打开文件失败(也可以说返回值是-1)。

重写demo1.c:

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

int main()
{
	int fd; // file description
	fd = open("./file1",O_RDWR|O_CREAT|O_EXCL, 0600);

	if(fd == -1){
		printf("fail to open, file already exit\n");
	}else{
		printf("file description = %d\n",fd);
	}
	return 0;
}

可见,当file1存在时,会返回-1,无法打开文件;只有将file1删除,才会正常返回文件标识符。 

O_APPEND参数的应用

O_APPEND:以这种属性去打开文件时,每次写时都加到文件的尾端。(不想写入时文件被覆盖,用这个flag,正常写入没有加其他条件的话,原来文件中的数据内容会被覆盖,注意是覆盖,覆盖本身的字节长度,没有覆盖的会保留,不是删除)

关于写入的操作,在下一节有介绍!

不加O_APPEND写入时:

使用demo2.c的代码执行两边,第二遍的时候,将写入的数据从“mjmmjm”改成“123”:

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

int main()
{
	int fd; // file description
	char *buf = "mjmmjm"; //第一遍
    char *buf = "123"; //第二遍

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

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

	write(fd, buf, strlen(buf));

	close(fd); //close after writing 

	return 0;
}

 

可见,如果没有添加O_APPEND,则第二次写入的数据会覆盖在原数据之上。

加入O_APPEND写入时:

依然使用demo2.c的代码执行两边,第二遍的时候,将写入的数据从“mjmmjm”改成“123”:

唯一的区别时这一次加上O_APPEND参数:

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

可见,添加了O_APPEND了之后,就自动在文件末尾添加内容了。

O_TRUNC参数的应用

O_TRUNC:以这种属性去打开文件时,如果这个文件中本来是有内容的, 而且为只读或只写成功打开,则将其长度截短为0,通俗点的意思就是把原来的文件中的内容删除,写入你自己要的数据内容

在刚刚O_APPEND的实验中,file1的内容被修改成了“mjmmjm123”,现在修改demo2.c的代码,加入O_RRUNC参数,不删除file1的前提下编译运行 demo2.c:

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

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

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

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

	write(fd, buf, strlen(buf));

	close(fd); //close after writing 

	return 0;
}

可见,文件的内容被完全替换成了新的写入内容,原来的内容全部被删除了。

creat函数

(需要添加的库在开头就说明了)

int creat(const char *pathname, mode_t mode);

参数说明

  • pathname:要打开的文件名(含路径)
  • mode:待创建的文件的访问权限

mode值的选择见上面的说明。

  • 返回值:文件标识符

creat函数的原型等价于 open(pathname,O_CREAT | O_TRUNC | O_WRONLY,mode);

其中,O_CREAT和O_TRUNC上面已经提到过,一个负责“文件不存在就创建它”,一个负责“每次写入就将之前内容全部删除”,最后一个O_WRONLY就是open函数中的flag参数,表示“只写打开

实操演示

修改demo1.c:

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

int main()
{
	int fd; // file description
	fd = creat("./file2", S_IRWXU); //给主用户赋予可读可写可执行的权限

	if(fd == -1){
		printf("fail to open, file already exit\n");
	}else{
		printf("file description = %d\n",fd);
	}
	return 0;
}

可见,creat函数 在file2不存在的情况下,会自动创建,印证了creat函数天生就带有open函数中的O_CREAT功能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《君正Linux开发指南》是一本面向初学者的Linux软件开发书籍。本书主要介绍Linux的开发环境以及如何使用常见的开发工具如gcc、make、gdb等构建和调试软件程序。书中对Linux环境下的文件操作、进程管理、信号处理等也有详细的讲解,让读者对Linux系统的运作有更加深入的理解。 本书分为10章,每章都按照某个主题介绍不同的知识点。第一章是介绍Linux的安装和使用,难度不大,适合初学者入门。接下来的几章主要介绍了例如文件操作、进程控制等开发中会常用的操作。其中第7章讲解了socket编程,这一部分对于网络编程初学者非常有帮助。接下来的章节则介绍一些高级话题,如内存管理、线程编程以及设备驱动开发等。 除了上述的内容,本书总结了Linux软件开发的一些最佳实践和规范,如使用GNU C库、Makefile的写法、调试技巧等。这些经验都是作者多年的Linux软件开发实践总结而来,对于初学者来说应该是非常有价值的参考。 总之,《君正Linux开发指南》适合想要学习Linux软件开发的初学者阅读,对于高级开发者可能过于简单,但作为入门读物也非常实用。 ### 回答2: 君正 Linux 开发指南是一本非常实用的技术书籍,其内容主要围绕在 Linux 开发方面展开,包括 Linux 内核、驱动开发、系统调用、多线程编程、网络编程等多个方面,对于想要深入了解 Linux 系统编程的开发人员来说,这本书将是非常有价值的参考资料。 本书开篇介绍了 Linux 的发展历程及其内核架构,让读者对 Linux 系统有一个基本的认识。接下来,书中详细阐述了 Linux 文件系统、进程管理、内存管理等方面的知识,并通过大量的示例代码,让读者更加深入地理解这些概念。 此外,本书还详细讲解了 Linux 内核编程的相关知识,包括内核模块开发、字符设备驱动程序的编写、中断处理程序的编写、系统调用的使用等。同时,本书对于多线程编程、网络编程的内容也做了非常详细的讲解。 总之,君正 Linux 开发指南是一本非常好的技术书籍,适合于需要深入学习 Linux 系统编程的开发人员阅读。它涵盖了 Linux 系统开发的方方面面,具有很强的实用性,读者可以通过学习本书,获得非常丰富的知识和经验。 ### 回答3: 《君正 Linux 开发指南》是一本非常实用的书籍,主要介绍了 Linux 操作系统的开发环境搭建、核心机制、系统调用、进程管理、线程管理、网络编程文件系统等方面的知识。 随着 Linux 操作系统在服务器、嵌入式等领域的广泛应用,对于 Linux 开发者来说,熟悉 Linux 操作系统的开发和调试已经成为必备的技能。而《君正 Linux 开发指南》针对这一需求,提供了一套系统而且深入的学习方法,使读者可以更透彻地理解和运用 Linux 操作系统。 具体来说,《君正 Linux 开发指南》通过对于 Linux 操作系统的分层结构和内部机制的解析,帮助读者深入了解 Linux 操作系统的本质,掌握 Linux 内核的设计原则和实现方法。同时,该书也通过实际的案例,讲解了 Linux 下的进程管理、线程管理、文件操作、网络编程等具体实现方式,使读者在学习过程中能够较为灵活的运用所学的知识完成实际项目开发工作。 总的来说,作为一本针对初学者和实际开发人员的书籍,《君正 Linux 开发指南》内容充实,介绍了涉及到 Linux 开发的方方面面,同时也有很多例子和实践操作,形式多样,便于读者学习理解,是一本值得推广和使用的学习教材。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值