Linux 第二十三章

2024-05-08 16:44
文章标签 linux 第二十三章

本文主要是介绍Linux 第二十三章,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

回顾文件

fopen()

fwrite 

 fputs

>文件名

追加重定向 

 认识系统接口

open

linux中常见的函数传参数

umask

write

read

语言和系统的区别

文件描述符


回顾文件

文件=内容+属性

1.所有对文件的操作:

1)对内容操作

2)对属性操作

2.内容是数据,属性也是数据

3.我们要访问一个文件的时候,都是先把这个文件先打开

我们:进程(我们在访问文件,其实都是进程要访问这个文件)

打开前:这个文件是普通的磁盘文件

打开后:文件加载到内存

4.一个进程可以打开多个文件吗?多个进程可以打开多个文件吗?

加载到内存中,被打开的文件,可能会存在多个

文件加载内存中是由操作系统来做的

操作系统在运行中,可能会打开很多个文件

操作系统要不要管理打开的文件呢???如何管理呢??

先描述,在组织

一个文件要被打开,一定先在内核中形成被打开的文件对象

5.文件按照是否被打开,分为:被打开的文件(内存中),没有被打开的文件(磁盘中)

6.研究本次文件操作的本质:进程和打开文件的关系

fopen()

fopen是C语言标准库中的一个函数,用于打开一个文件,并返回一个指向该文件的指针。其原型如下:

FILE *fopen(const char *filename, const char *mode);
其中,filename表示要打开的文件名,可以包含路径信息,mode则表示打开文件的模式,包括读、写等操作,具体的取值包括:* "r":以只读方式打开文件,如果文件不存在则返回NULL;
* "w":以写方式打开文件,如果文件不存在则创建,如果文件存在则清空文件内容;
* "a":以追加方式打开文件,如果文件不存在则创建;
* "r+":以读写方式打开文件,如果文件不存在则返回NULL;
* "w+":以读写方式打开文件,如果文件不存在则创建,如果文件存在则清空文件内容;
* "a+":以追加方式打开文件,如果文件不存在则创建;

示例代码:

#include <stdio.h>int main() {FILE *fp = fopen("test.txt", "w");if(fp == NULL) {printf("Failed to open file.\n");return -1;}fprintf(fp, "Hello, world!\n");fclose(fp);return 0;
}

以上代码将会创建一个名为"test.txt"的文件,并向其中写入一行字符串"Hello, world!",然后关闭文件。

fwrite 

fwrite是C语言标准库中的一个函数,用于向文件中写入数据。

其原型如下:

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
其中,ptr表示要写入的数据指针,size表示每个数据元素的大小(单位为字节),
count表示要写入的数据元素的个数,stream表示要写入的文件流指针。

函数返回值为成功写入的数据元素个数。

示例代码:

#include <stdio.h>
int main() {int arr[3] = {1, 2, 3};FILE *fp = fopen("test.bin", "wb");if(fp == NULL) {printf("Failed to open file.\n");return -1;}fwrite(arr, sizeof(int), 3, fp);fclose(fp);return 0;
}

以上代码将会创建一个名为"test.bin"的二进制文件,并向其中写入一个包含三个整数的数组。通过fwrite函数,将整数数组arr的内容写入到文件中。注意,使用二进制模式打开文件时应该使用"wb"模式。

对于写入文本文件,我们可以使用fputs或fprintf函数。例如:

#include <stdio.h>
int main() {FILE *fp = fopen("test.txt", "w");if(fp == NULL) {printf("Failed to open file.\n");return -1;}fputs("Hello, world!\n", fp);fprintf(fp, "%d %s\n", 123, "abc");fclose(fp);return 0;
}

以上代码将会创建一个名为"test.txt"的文本文件,并向其中写入两行字符串。第一行是"Hello, world!\n",第二行是"123 abc\n"。注意,在文本模式下打开文件时应该使用"w"模式。

 fputs

fputs是C语言标准库中的一个函数,用于向文件中写入字符串。

其原型如下:

int fputs(const char *str, FILE *stream);
其中,str表示要写入的字符串,stream表示要写入的文件流指针。
函数返回值为成功写入的字符个数(不包括字符串结尾的空字符'\0')。

示例代码:

#include <stdio.h>int main() {FILE *fp = fopen("test.txt", "w");if(fp == NULL) {printf("Failed to open file.\n");return -1;}fputs("Hello, world!\n", fp);fclose(fp);return 0;
}

以上代码将会创建一个名为"test.txt"的文本文件,并向其中写入一行字符串"Hello, world!\n"。注意,在文本模式下打开文件时应该使用"w"模式。

>文件名

 >文件名,1.如果文件不存在,就会创建文件 2.如果文件存在则会清空文件

[BCH@hcss-ecs-6176 testfile]$ >log.txt//>重定向log.txt文件时,需要打开文件,
但是也没有做什么,所以就会关闭文件,此时文件就会被清空,和"w"打开文件一样
[BCH@hcss-ecs-6176 testfile]$ ll
总用量 20
-rw-rw-r-- 1 BCH BCH    0 11月 23 23:16 log.txt
-rw-rw-r-- 1 BCH BCH   65 11月 23 22:51 Makefile
-rwxrwxr-x 1 BCH BCH 8512 11月 23 23:12 myfile
-rw-rw-r-- 1 BCH BCH  414 11月 23 23:15 myfile.c

追加重定向 

[BCH@hcss-ecs-6176 testfile]$ ll
总用量 24
-rw-rw-r-- 1 BCH BCH   63 11月 23 23:24 log.txt
-rw-rw-r-- 1 BCH BCH   65 11月 23 22:51 Makefile
-rwxrwxr-x 1 BCH BCH 8512 11月 23 23:20 myfile
-rw-rw-r-- 1 BCH BCH  502 11月 23 23:23 myfile.c
[BCH@hcss-ecs-6176 testfile]$ echo "hello linux" >>log.txt//>>和”a"打开文件一样
[BCH@hcss-ecs-6176 testfile]$ ll
总用量 24
-rw-rw-r-- 1 BCH BCH   75 11月 23 23:24 log.txt
-rw-rw-r-- 1 BCH BCH   65 11月 23 22:51 Makefile
-rwxrwxr-x 1 BCH BCH 8512 11月 23 23:20 myfile
-rw-rw-r-- 1 BCH BCH  502 11月 23 23:23 myfile.c

 认识系统接口

open

open是Linux系统中的一个系统调用,用于打开文件或创建文件。
其原型如下:

#include <fcntl.h>//头文件
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
其中,pathname表示要打开或创建的文件路径名,flags表示打开或创建文件的方式和权限,mode表示创建文件时的权限。
flags参数可以使用以下常量进行组合:
* O_RDONLY:只读打开;
* O_WRONLY:只写打开;
* O_RDWR:读写打开;
* O_CREAT:如果文件不存在则创建;
* O_TRUNC:打开文件时截断文件长度为0;
* O_APPEND:在文件末尾追加数据;
* O_EXCL:与O_CREAT一起使用,如果文件已经存在则报错。
mode参数可以使用以下常量进行组合:
* S_IRWXU:用户具有读、写、执行权限;
* S_IRUSR:用户具有读权限;
* S_IWUSR:用户具有写权限;
* S_IXUSR:用户具有执行权限;
* S_IRWXG:组具有读、写、执行权限;
* S_IRGRP:组具有读权限;
* S_IWGRP:组具有写权限;
* S_IXGRP:组具有执行权限;
* S_IRWXO:其他用户具有读、写、执行权限;
* S_IROTH:其他用户具有读权限;
* S_IWOTH:其他用户具有写权限;
* S_IXOTH:其他用户具有执行权限。

示例代码:

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() 
{int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);if(fd == -1) {printf("Failed to open file.\n");return -1;}write(fd, "Hello, world!\n", 14);close(fd);return 0;
}


以上代码将会创建一个名为"test.txt"的文件,并向其中写入一行字符串"Hello, world!\n",然后关闭文件。注意,在Linux系统中,文件的读写需要使用文件描述符来进行操作,因此需要先通过open函数打开文件,并返回一个文件描述符,然后使用write或read等函数进行读写操作,最后通过close函数关闭文件。

linux中常见的函数传参数

#include<stdio.h>#define PRINT1 1 //0001//1
#define PRINT2 (1<<1) //0010//2
#define PRINT3 (1<<2) //0100//4
#define PRINT4 (1<<3) //1000//8void print(int flags)
{if(flags&PRINT1)printf("print : 1\n");if(flags&PRINT2)printf("print : 2\n");if(flags&PRINT3)printf("print : 3\n");if(flags&PRINT4)printf("print : 4\n");
}
int main()
{print(PRINT1);print(PRINT1|PRINT2);print(PRINT1|PRINT2|PRINT3);print(PRINT1|PRINT2|PRINT3|PRINT4);return 0;
}

umask

在Linux中,umask也是一个系统调用,用于设置当前进程的文件创建屏蔽字(file creation mask)。它可以通过umask()函数来调用。

#include <sys/stat.h>
#include <sys/types.h>
mode_t umask(mode_t mask);
umask函数接受一个八进制数作为参数,表示要屏蔽的权限位。它返回先前的屏蔽字值。

以下是一个示例代码,展示了如何使用umask系统调用:

#include <stdio.h>
#include <sys/stat.h>
int main() {mode_t old_mask = umask(022);  // 设置屏蔽字为022printf("Old umask: %o\n", old_mask);// 创建文件FILE *file = fopen("test.txt", "w");if (file == NULL) {perror("Failed to create file");return -1;}fclose(file);return 0;
}

在上述示例中,首先使用umask(022)将屏蔽字设置为022,然后创建一个名为"test.txt"的文件。由于屏蔽字的设置,该文件的权限将是644(666 & ~022 = 644)。

需要注意的是,umask调用仅对当前进程及其子进程有效,不会永久更改系统的默认umask值。如果希望永久更改umask值,可以将其添加到shell的配置文件中,例如~/.bashrc或/etc/profile。
 

write

在Linux中,write是一个系统调用,用于将数据写入文件描述符(file descriptor)所指向的文件中。

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
* fd:文件描述符,表示要写入的文件。
* buf:指向要写入的数据的缓冲区。
* count:要写入的字节数。
write函数返回实际写入的字节数,如果出现错误则返回-1。

以下是一个示例代码,展示了如何使用write系统调用:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
int main() {int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);if (fd == -1) {perror("Failed to open file");return -1;}const char *data = "Hello, world!";ssize_t bytes_written = write(fd, data, strlen(data));if (bytes_written == -1) {perror("Failed to write to file");close(fd);return -1;}printf("Bytes written: %zd\n", bytes_written);close(fd);return 0;
}


在上述示例中,首先使用open函数打开或创建一个名为"test.txt"的文件,并获得对应的文件描述符。然后使用write函数将字符串"Hello, world!"写入文件中。最后,关闭文件。

需要注意的是,文件需要以适当的方式打开(例如O_WRONLY表示只写),并且需要在使用write函数之前打开文件。并且,在写入数据时,需要确保缓冲区中的数据不会超过指定的字节数。
 

当我们想想向一个文件中写入字符串的时候,我们不需要在strlen()+1,\0是c语言的规定,不是文件的规定

read

在 Linux 中,read 系统调用用于从文件描述符读取数据。

它的原型如下:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
fd 是要读取的文件描述符,可以是文件、套接字、管道等。
buf 是用来存储读取数据的缓冲区的指针。
count 是要读取的字节数。
read 函数返回值为读取的字节数。如果返回 -1,则表示读取出错;如果返回 0,则表示已到达文件末尾(或者读取的字节数为 0)。

以下是一个简单的示例,演示如何使用 read 系统调用从文件中读取数据:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main() {char buffer[1024];ssize_t bytes_read;// 打开文件int fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open");exit(EXIT_FAILURE);}// 从文件中读取数据bytes_read = read(fd, buffer, sizeof(buffer));if (bytes_read == -1) {perror("read");exit(EXIT_FAILURE);}// 输出读取的数据printf("Read %zd bytes: %s\n", bytes_read, buffer);// 关闭文件close(fd);return 0;
}


在这个示例中,程序打开名为 "example.txt" 的文件,并使用 read 函数从文件中读取数据到 buffer 中。然后输出读取的数据,并关闭文件。

语言和系统的区别

c语言函数接口

FILE* fp=fopen("log.txt","w");
FILE* fp=fopen("log.txt","a");

系统调用接口

int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC);
int fd=open("log.txt",O_WRONLY|O_CREAT|O_APPEND);

文件描述符fd是一个连续的小整数理解文件,在操作系统中的表现:

fd的本质其实就是数组的下标
进程在运行的时候,默认是把
标准输入 键盘        stdin      0
标准输出 显示器    stdout    1
标准错误 显示器    stdout    2

操作系统访问文件,只认文件描述符


FILE是一个C语言提供的结构体类型,这个结构体必定封装了文件描述符

int main()
{printf("stdin:%d\n",stdin->_file);printf("stdin:%d\n",stdout->_file);printf("stdin:%d\n",stderr->_file);FILE* fp=fopen("log.txt","w");printf("fp:%d\n",fp->_file);fclose(fp);
}结果:
stdin:0
stdin:1
stdin:2
fp:3

1.OS/C语言为什么默认要把0,1,2,stdin、stdout、strerr打开呢??就是为了让程序员默认进行输入输出代码编写

2.stderr是什么?

3.如何理解一切皆文件呢?

文件描述符

在Linux中,文件描述符fd(file descriptor)是一个非负整数,用于唯一标识打开的文件或其他输入/输出资源。文件描述符是操作系统内部维护的,应用程序通过文件描述符来访问文件、套接字、管道等。

下面是一些关于文件描述符的常见概念和用法:

1. 标准文件描述符:
    * 0:标准输入(STDIN_FILENO),通常关联到键盘输入。
    * 1:标准输出(STDOUT_FILENO),通常关联到屏幕输出。
    * 2:标准错误(STDERR_FILENO),通常关联到屏幕输出。
2. 打开文件:
    * 当你使用open函数打开一个文件时,它会返回一个文件描述符。
    * 文件描述符从3开始递增,每次成功打开一个文件就会分配一个新的文件描述符。
3. 文件描述符的读写:
    * 使用read函数从文件描述符中读取数据。
    * 使用write函数将数据写入文件描述符。
4. 关闭文件:
    * 使用close函数关闭文件描述符。
    * 关闭文件描述符后,它可以被重用。
5. 其他操作:
    * 可以使用dup或dup2函数复制文件描述符。
    * 使用fcntl函数进行更高级的文件描述符操作,如非阻塞模式、文件状态标志等。

下面是一个简单的示例,演示了打开文件、读取内容并关闭文件的过程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>int main() {int file_desc = open("example.txt", O_RDONLY);if (file_desc == -1) {perror("Error opening file");exit(1);}char buffer[100];ssize_t bytes_read = read(file_desc, buffer, sizeof(buffer));if (bytes_read == -1) {perror("Error reading file");exit(1);}printf("Read %zd bytes: %s\n", bytes_read, buffer);close(file_desc);return 0;
}


在这个例子中,我们使用open函数打开一个名为"example.txt"的文件,并通过read函数读取文件内容到缓冲区中。最后,使用close函数关闭文件描述符。
 

  🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 

这篇关于Linux 第二十三章的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/970866

相关文章

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

linux报错INFO:task xxxxxx:634 blocked for more than 120 seconds.三种解决方式

《linux报错INFO:taskxxxxxx:634blockedformorethan120seconds.三种解决方式》文章描述了一个Linux最小系统运行时出现的“hung_ta... 目录1.问题描述2.解决办法2.1 缩小文件系统缓存大小2.2 修改系统IO调度策略2.3 取消120秒时间限制3

Linux alias的三种使用场景方式

《Linuxalias的三种使用场景方式》文章介绍了Linux中`alias`命令的三种使用场景:临时别名、用户级别别名和系统级别别名,临时别名仅在当前终端有效,用户级别别名在当前用户下所有终端有效... 目录linux alias三种使用场景一次性适用于当前用户全局生效,所有用户都可调用删除总结Linux

Linux:alias如何设置永久生效

《Linux:alias如何设置永久生效》在Linux中设置别名永久生效的步骤包括:在/root/.bashrc文件中配置别名,保存并退出,然后使用source命令(或点命令)使配置立即生效,这样,别... 目录linux:alias设置永久生效步骤保存退出后功能总结Linux:alias设置永久生效步骤

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对