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换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

Linux安装MySQL的教程

《Linux安装MySQL的教程》:本文主要介绍Linux安装MySQL的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux安装mysql1.Mysql官网2.我的存放路径3.解压mysql文件到当前目录4.重命名一下5.创建mysql用户组和用户并修

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置