Linux系统编程内容
Linux 系统编程涵盖了众多方面的知识和技术:
1. 文件 I/O 操作:包括打开、读取、写入、关闭文件,以及处理文件的权限、属性等。
2. 进程管理:创建新进程、进程的终止、等待进程结束、进程的执行状态控制等。
3. 信号处理:接收和处理系统发送的各种信号,以响应特定的事件。
4. 线程编程:创建、同步和管理线程,实现多线程并发执行。
5. 进程间通信(IPC):如管道、消息队列、共享内存、信号量等方式,实现不同进程之间的数据交换和协调工作。
6. 套接字编程:用于网络通信,实现客户端与服务器之间的数据传输。
7. 系统调用和库函数:熟练使用 Linux 提供的系统调用和相关的库函数来完成各种任务。
8. 内存管理:包括动态内存分配(如 malloc 和 free )以及对内存映射文件的操作。
这些是 Linux 系统编程的核心内容,通过学习和实践这些方面,可以开发出高效、稳定的 Linux 应用程序。从今天开始就正式进入系统编程内容了
文件IO
1. 标准IO的概念
标准输入输出(I/O)是与计算机程序交互的基本方式。ISO C标准提供了一套标准的输入输出库,使程序能够方便地处理输入输出操作。
- **输入(I)**:在C语言中,通常情况下,标准输入设备是键盘。程序默认从键盘读取数据。Linux中,标准输入对应的设备为`/dev/input`。
- **输出(O)**:标准输出设备通常是显示器,程序默认将结果输出到屏幕。
在Linux操作系统中,I/O操作都是围绕文件进行的。标准I/O库是对文件I/O的封装,使得任何支持C语言的系统都能通用地处理文件存储。
标准I/O操作通常是针对普通文件的,它采用了缓冲机制。缓冲区位于文件I/O与用户程序之间,这种设计可以有效减少系统调用的次数,从而提高效率并节省IO调度资源。
2. 文件的概念及作用
在Linux及Unix-like操作系统中,一切皆文件。文件不仅存储数据,还可以存储指令和配置。在这种模型中,文件可以分为几种类型:
- **普通文件**:用于存储数据,比如文本文件和二进制文件。
- **目录文件**:用于组织文件系统中的其他文件。
- **设备文件**:用于与硬件设备交互,比如硬盘、打印机等。
文件在操作系统中扮演了重要的角色:
- **数据持久化**:文件可存储重要数据和状态,使其在程序结束后不丢失。
- **信息共享**:不同程序可以通过文件共享数据。
- **配置管理**:许多程序使用配置文件来设定选项和参数,便于用户调整行为。
通过标准I/O操作,程序可以方便地读写各种类型的文件,实现更复杂的数据处理和交互功能。
在Linux中,文件的类型有以下7种:
- "d" - 目录文件(directory file)
- "-" - 普通文件(regular file)
- "l" - 符号链接文件(symbolic link file)
- "p" - 命名管道文件(named pipe file)
- "s" - 套接字文件(socket file)
- "c" - 字符设备文件(character device file)
- "b" - 块设备文件(block device file)
其中,d表示目录文件,-表示普通文件,l表示符号链接文件,p表示命名管道文件,s表示套接字文件,c表示字符设备文件,b表示块设备文件。
关于IO的分类,有以下几种:
- 标准IO(Standard IO):ANSI C设计的一组用文件IO封装的操作库函数,通过头文件stdio.h进行操作。
- 文件IO(File IO):底层软件的系统调用,用于对文件进行读写操作。
- ASCII码数据流:以ASCII码作为数据流的文本流。
- 二进制数据流:以二进制数据作为数据流的二进制流。
文件流是通过FILE结构定义的对象,用FILE指针来表示。文件流可以理解为数据从文件中流入和流出所体现出来的字节流,它由文件的头部和尾部组成。
在Linux中,可以使用man命令来查看有关命令、系统调用函数和标准库函数的帮助信息。man命令后面跟着的数字表示查看的是哪个部分的帮助信息,例如man 1 xxx表示查看命令xxx的帮助信息,man 2 xxx表示查看系统调用函数xxx的帮助信息,man 3 xxx表示查看标准库函数xxx的帮助信息。
对于文件IO相关的标准库函数,可以使用stdio.h头文件来使用,该头文件位于/usr/include/stdio.h。标准库函数分为系统库函数和用户自定义函数,系统库函数的默认路径是/usr/include/,而用户自定义函数的默认路径是当前路径。例如,可以使用printf、scanf、getc等函数来进行标准输入输出的操作。
文件内容可以分为文本文件和二进制文件。文本文件是以ASCII码数据流的形式存储的文件,而二进制文件是以二进制数据流的形式存储的文件。
3.文件流(File stream)
文件流(File stream)是指将文件的读写操作视为数据流的形式。在编程中,文件流可以用于读取和写入文件中的数据。
文件流有两种类型:输入流和输出流。输入流用于从文件中读取数据,输出流用于向文件中写入数据。
使用文件流进行文件读写的过程如下:
1. 打开文件流:使用相应的编程语言提供的函数或方法,打开要读取或写入的文件,并创建文件流对象。
2. 读取或写入数据:使用文件流对象的读取或写入方法,进行数据的读取或写入操作。读取操作会从文件中读取一定数量的数据,写入操作会将指定的数据写入文件。
3. 关闭文件流:使用相应的编程语言提供的函数或方法,关闭文件流并释放相关资源。
文件流的优点是可以按照流的方式读取或写入文件,适合处理大文件或需要逐行读取的场景。文件流也可以按字节进行读写,适合处理二进制文件。
文件流在编程中广泛应用于文件读写、日志记录、数据备份等场景。常用的编程语言如C、C++、Java、Python等都提供了对文件流的支持。
4.相关函数
fopen
在 C 语言中, fopen 函数用于打开文件。
其函数原型为:
FILE *fopen(const char *filename, const char *mode);
- filename :要打开的文件名(包括路径)。
- mode :指定打开文件的模式,常见的模式有:
- "r" :以只读方式打开文件,如果文件不存在则打开失败。
- "w" :以只写方式打开文件,如果文件不存在则创建,如果存在则清空文件内容。
- "a" :以追加方式打开文件,如果文件不存在则创建,写入的数据会添加到文件末尾。
- "r+" :以读写方式打开文件,文件必须存在。
- "w+" :以读写方式打开文件,如果文件不存在则创建,如果存在则清空文件内容。
- "a+" :以读和追加方式打开文件,如果文件不存在则创建。
fopen 函数成功打开文件时返回一个 FILE 类型的指针,该指针用于后续对文件的读写操作。如果打开文件失败,则返回 NULL 。
在使用 fopen 后,务必在操作完成后使用 fclose 函数关闭文件,以释放相关资源。
例如:
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("example.txt", "w");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
// 在这里进行文件写入操作
fclose(fp);
return 0;
}
fclose
在 C 语言中, fclose 函数用于关闭一个之前通过 fopen 函数打开的文件。
其函数原型为:
int fclose(FILE *stream);
stream 是指向要关闭的文件的 FILE 指针。
fclose 函数执行以下重要操作:
1. 刷新输出缓冲区中的数据,确保所有未写入的数据都被实际写入到文件中。
2. 释放与该文件相关的系统资源。
fclose 函数返回 0 表示成功关闭文件,返回 EOF (通常定义为 -1)表示关闭文件时发生错误。
例如:
#include <stdio.h>
int main() {
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
// 写入一些数据
fprintf(fp, "这是一些测试数据");
// 关闭文件
if (fclose(fp) == EOF) {
printf("关闭文件时出错\n");
return 1;
}
return 0;
}
fgetc
在 C 语言中, fgetc 函数用于从指定的文件流中读取一个字符。
其函数原型为:
int fgetc(FILE *stream);
stream 是指向要读取的文件流的 FILE 指针。
fgetc 函数从文件流中读取下一个字符,并将其作为 unsigned char 类型的值转换为 int 类型后返回。如果到达文件末尾或发生读取错误,它将返回 EOF (通常定义为 -1)。
以下是一个简单的示例,展示如何使用 fgetc 函数读取文件中的字符:
#include <stdio.h>
int main() {
FILE *fp;
char ch;
fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
while ((ch = fgetc(fp))!= EOF) {
putchar(ch);
}
fclose(fp);
return 0;
}
在这个示例中,不断使用 fgetc 函数读取文件中的字符,并通过 putchar 函数输出到屏幕上,直到遇到文件末尾。
fputc
在 C 语言中, fputc 函数用于将一个字符写入到指定的文件流中。
其函数原型为:
int fputc(int c, FILE *stream);
c 是要写入的字符(以 int 类型传递,实际存储的是字符的 ASCII 值)。 stream 是指向目标文件流的 FILE 指针。
fputc 函数返回写入的字符,如果发生错误则返回 EOF 。
以下是一个使用 fputc 函数向文件写入字符的示例:
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("output.txt", "w");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
fputc('H', fp);
fputc('e', fp);
fputc('l', fp);
fputc('l', fp);
fputc('o', fp);
fclose(fp);
return 0;
}
在这个示例中,依次向文件 "output.txt" 写入了字符 'H'、'e'、'l'、'l'、'o' 。
fgets
在 C 语言中, fgets 函数用于从指定的文件流中读取一行字符串。
其函数原型为:
char *fgets(char *str, int n, FILE *stream);
- str :指向用来存储读取字符串的字符数组。
- n :指定读取的最大字符数(包括最后的 '\0' 字符)。
- stream :指向要读取的文件流。
fgets 函数从文件流中读取最多 n - 1 个字符,并在读取的字符串末尾添加 '\0' 作为字符串结束标志。如果在达到 n - 1 个字符之前遇到换行符 '\n' 或文件结束标志,读取操作也会停止。
如果成功读取到字符串(包括读到空行), fgets 函数返回 str ;如果遇到文件结束或发生错误,则返回 NULL 。
以下是一个示例代码:
#include <stdio.h>
int main() {
FILE *fp;
char str[100];
fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
if (fgets(str, sizeof(str), fp)!= NULL) {
printf("%s", str);
}
fclose(fp);
return 0;
}
fputs
在 C 语言中, fputs 函数用于将一个字符串写入到指定的文件流中。
其函数原型为:
int fputs(const char *str, FILE *stream);
- str :要写入的字符串。
- stream :指向目标文件流的 FILE 指针。
fputs 函数将字符串 str 写入到指定的文件流中,但它不会自动添加换行符。如果写入成功,函数返回一个非负值;如果发生错误,则返回 EOF 。
以下是一个简单的示例:
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("output.txt", "w");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
fputs("这是写入的字符串", fp);
fclose(fp);
return 0;
}
fwrite
在 C 语言中, fwrite 函数用于将数据块写入到指定的文件流中。
其函数原型为:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- ptr :指向要写入数据的指针。
- size :每个数据项的大小(以字节为单位)。
- nmemb :要写入的数据项的数量。
- stream :指向目标文件流的 FILE 指针。
fwrite 函数返回实际写入的数据项的数量。如果返回值小于 nmemb ,则表示发生了错误。
以下是一个示例代码,展示如何使用 fwrite 函数写入数据:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {1, 2, 3, 4, 5};
fp = fopen("data.bin", "wb");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
size_t written = fwrite(data, sizeof(int), sizeof(data) / sizeof(int), fp);
if (written!= sizeof(data) / sizeof(int)) {
printf("写入错误\n");
}
fclose(fp);
return 0;
}
在这个示例中,将一个整数数组写入到二进制文件中。
fread
在 C 语言中, fread 函数用于从指定的文件流中读取数据块。
其函数原型为:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- ptr :指向用于存储读取数据的内存缓冲区的指针。
- size :每个数据项的大小(以字节为单位)。
- nmemb :要读取的数据项的数量。
- stream :指向要读取的文件流的 FILE 指针。
fread 函数返回实际读取到的数据项的数量。如果返回值小于 nmemb ,可能表示到达了文件末尾或者发生了错误。
以下是一个简单的示例,展示如何使用 fread 函数读取数据:
#include <stdio.h>
int main() {
FILE *fp;
int data[5];
fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
size_t read = fread(data, sizeof(int), 5, fp);
if (read!= 5) {
printf("读取错误或未读取到完整数据\n");
}
fclose(fp);
// 打印读取到的数据
for (int i = 0; i < 5; i++) {
printf("%d ", data[i]);
}
printf("\n");
return 0;
}
标签:fp,第十八天,FILE,文件,函数,写入,IO,Linux,读取
From: https://blog.csdn.net/qq_64792908/article/details/141134315