Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Linux】基础I/O>文件系统&&软硬链接&&动静态库详解

【Linux】基础I/O>文件系统&&软硬链接&&动静态库详解

作者头像
用户10925563
发布于 2024-06-04 06:04:46
发布于 2024-06-04 06:04:46
14600
代码可运行
举报
文章被收录于专栏:c/c++&&linuxc/c++&&linux
运行总次数:0
代码可运行

1.C语言文件接口

1.1 hello.c写文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
int main()
{
	FILE* fp = fopen("myfile", "w");
	if (!fp) {
		printf("fopen error!\n");
	}
	const char* msg = "hello bit!\n";
	int count = 5;
	while (count--) {
		fwrite(msg, strlen(msg), 1, fp);
	}
	fclose(fp);
	return 0;
}

1.2 hello.c读文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
int main()
{
	FILE* fp = fopen("myfile", "r");
	if (!fp) {
		printf("fopen error!\n");
	}
	char buf[1024];
	const char* msg = "hello bit!\n";
	while (1) {
		//注意返回值和参数,此处有坑,仔细查看man手册关于该函数的说明
		size_t s = fread(buf, 1, strlen(msg), fp);
		if (s > 0) {
			buf[s] = 0;
			printf("%s", buf);
		}
		if (feof(fp)) {
			break;
		}
	}
	fclose(fp);
	return 0;
}

1.3 输出信息到显示器

输出信息到显示器,你有哪些方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
int main()
{
	const char* msg = "hello fwrite\n";
	fwrite(msg, strlen(msg), 1, stdout);
	printf("hello printf\n");
	fprintf(stdout, "hello fprintf\n");
	return 0;
}

1.4 stdin & stdout & stderr

  • C默认会打开三个输入输出流,分别是stdin, stdout, stderr
  • 仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针

1.5 总结打开文件的方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
r	Open text file for reading.
	The stream is positioned at the beginning of the file.

r +	Open for readingand writing.
	The stream is positioned at the beginning of the file.

w	Truncate(缩短) file to zero length or create text file for writing.
	The stream is positioned at the beginning of the file.

w + Open for readingand writing.
	The file is created if it does not exist, otherwise it is truncated.
	The stream is positioned at the beginning of the file.
a   Open for appending(writing at end of file).
	The file is created if it does not exist.
	The stream is positioned at the end of the file.

a + Open for readingand appending(writing at end of file).
	The file is created if it does not exist.The initial file position
	for reading is at the beginning of the file,
	but output is always appended to the end of the file

2.系统文件I/O

操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问,先来直接以代码的形式,实现和上面一模一样的代码

2.1 hello.c 写文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
	umask(0);
	int fd = open("myfile", O_WRONLY | O_CREAT, 0644);
	if (fd < 0) {
		perror("open");
		return 1;
	}
	int count = 5;
	const char* msg = "hello bit!\n";
	int len = strlen(msg);
	while (count--) {
		write(fd, msg, len);// msg:缓冲区首地址, len: 本次读取,期望写入多少个字节的数据。 返回值:实际写了多少字节数据
	}
	close(fd);
	return 0;
}

2.2 hello.c 读文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
	int fd = open("myfile", O_RDONLY);
	if (fd < 0) {
		perror("open");
		return 1;
	}
	const char* msg = "hello bit!\n";
	char buf[1024];
	while (1) {
		size_t s = read(fd, buf, strlen(msg));//类比write
		if (s > 0) {
			printf("%s", buf);
		}
		else {
			break;
		}
	}
	close(fd);
	return 0;
}

2.3 接口介绍

2.3.1 open
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char* pathname, int flags);
int open(const char* pathname, int flags, mode_t mode);

pathname: 要打开或创建的目标文件
flags : 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。

参数 :
O_RDONLY: 只读打开
O_WRONLY : 只写打开
O_RDWR : 读,写打开

这三个常量,必须指定一个且只能指定一个

O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND : 追加写

返回值:
成功:新打开的文件描述符
失败: - 1
2.3.2 mode_t

open 函数具体使用哪个,和具体应用场景相关,如目标文件不存在,需要open创建,则第三个参数表示创建文件的默认权限,否则,使用两个参数的open

write read close lseek ,类比C文件相关接口

2.3.3 open函数返回值

在认识返回值之前,先来认识一下两个概念: 系统调用 库函数

  • 上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
  • 而open close read write lseek 都属于系统提供的接口,称之为系统调用接口

系统调用接口和库函数的关系,一目了然。

所以,可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发

2.4 文件描述符fd

通过对open函数的学习,我们知道了文件描述符就是一个小整数

2.4.1 0 & 1 & 2
  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.
  • 0,1,2对应的物理设备一般是:键盘,显示器,显示器

所以输入输出还可以采用如下方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
	char buf[1024];
	size_t s = read(0, buf, sizeof(buf));
	if (s > 0) {
		buf[s] = 0;
		write(1, buf, strlen(buf));
		write(2, buf, strlen(buf));
	}
	return 0;
}

而现在知道,文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件

2.4.2 文件描述符的分配规则
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
	int fd = open("myfile", O_RDONLY);
	if (fd < 0) {
		perror("open");
		return 1;
	}
	printf("fd: %d\n", fd);
	close(fd);
	return 0;
}

关闭0或者2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
	close(0);
	//close(2);
	int fd = open("myfile", O_RDONLY);
	if (fd < 0) {
		perror("open");
		return 1;
	}
	printf("fd: %d\n", fd);
	close(fd);
	return 0;
}

发现是结果是: fd: 0 或者 fd 2

可见,文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符

2.4.3 重定向

那如果关闭1呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
	close(1);
	int fd = open("myfile", O_WRONLY | O_CREAT, 00644);
	if (fd < 0) {
		perror("open");
		return 1;
	}
	printf("fd: %d\n", fd);
	fflush(stdout);

	close(fd);
	exit(0);
}

此时,我们发现,本来应该输出到显示器上的内容,输出到了文件 myfile 当中,其中,fd=1。这种现象叫做输出重定向。常见的重定向有:>, >>, <

那重定向的本质是什么呢?

2.5 使用 dup2 系统调用

函数原型如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <unistd.h>
int dup2(int oldfd, int newfd);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main() {
    int fd = open("log.txt", O_CREAT | O_RDWR, 0644);
    if (fd < 0)
    {
        perror("open");
    }
    dup2(fd, 1);                      // 文件重定向

    printf("newfd: hello, world\n");  // 向1号文件描述符写入内容

    const char* buf = "oldfd: hello, world\n";
    write(fd, buf, strlen(buf));      // 向原本的log.txt对应的文件描述符写入内容

    return 0;
}

可以通过下面的文章了解:文件操作(五)—— 文件重定向(dup2)-CSDN博客

3.FILE

  • 因为IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过fd访问的
  • 所以C库当中的FILE结构体内部,必定封装了fd
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
	const char* msg0 = "hello printf\n";
	const char* msg1 = "hello fwrite\n";
	const char* msg2 = "hello write\n";
	printf("%s", msg0);
	fwrite(msg1, strlen(msg0), 1, stdout);
	write(1, msg2, strlen(msg2));
	fork();
	return 0;
}

但如果对进程实现输出重定向呢? ./test > file , 我们发现结果变成了

我们发现 printf 和 fwrite (库函数)都输出了2次,而 write 只输出了一次(系统调用)。为什么呢?肯定和fork有关!

  • 一般C库函数写入文件时是全缓冲的,而写入显示器是行缓冲
  • printf fwrite 库函数会自带缓冲区(进度条例子就可以说明),当发生重定向到普通文件时,数据的缓冲方式由行缓冲变成了全缓冲
  • 而我们放在缓冲区中的数据,就不会被立即刷新,甚至fork之后
  • 但是进程退出之后,会统一刷新,写入文件当中
  • 但是fork的时候,父子数据会发生写时拷贝,所以当你父进程准备刷新的时候,子进程也就有了同样的一份数据,随即产生两份数据
  • write 没有变化,说明没有所谓的缓冲

综上: printf fwrite 库函数会自带缓冲区,而 write 系统调用没有带缓冲区。另外,我们这里所说的缓冲区,都是用户级缓冲区。其实为了提升整机性能,OS也会提供相关内核级缓冲区,不过不再我们讨论范围之内。

那这个缓冲区谁提供呢? printf fwrite 是库函数, write 是系统调用,库函数在系统调用的“上层”, 是对系统调用的“封装”,但是 write 没有缓冲区,而 printf fwrite 有,足以说明,该缓冲区是二次加上的,又因为是C,所以由C标准库提供

4.理解文件系统

我们使用ls -l的时候看到的除了看到文件名,还看到了文件元数据

每行包含7列:

  • 模式
  • 硬链接数
  • 文件所有者
  • 大小
  • 最后修改时间
  • 文件名

ls -l 读取存储在磁盘上的文件信息,然后显示出来

其实这个信息除了通过这种方式来读取,还有一个stat命令能够看到更多信息

上面的执行结果有几个信息需要解释清楚

4.1 inode

为了能解释清楚inode我们先简单了解一下文件系统

Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。而上图中启动块(Boot Block)的大小是确定的

  • Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。政府管理各区的例子
  • 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
  • GDT,Group Descriptor Table:块组描述符,描述块组属性信息,有兴趣的同学可以在了解一下
  • 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
  • inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
  • i节点表:存放文件属性 如 文件大小,所有者,最近修改时间等
  • 数据区:存放文件内容

将属性和数据分开存放的想法看起来很简单,但实际上是如何工作的呢?我们通过touch一个新文件来看看如何工作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost linux]# touch abc
[root@localhost linux]# ls -i abc
263466 abc

为了说明问题,我们将上图简化:

创建一个新文件主要有一下4个操作:

  1. 存储属性 内核先找到一个空闲的i节点(这里是263466)。内核把文件信息记录到其中
  2. 存储数据 该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第一块数据复制到300,下一块复制到500,以此类推
  3. 记录分配情况 文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表
  4. 添加文件名到目录 新的文件名abc。linux如何在当前的目录中记录这个文件?内核将入口(263466,abc)添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来

4.2 硬链接

我们看到,真正找到磁盘上文件的并不是文件名,而是inode。 其实在linux中可以让多个文件名对应于同一个inode。

硬链接就是一个文件名和inode的映射关系,建立硬链接就是在指定目录下添加一个新的文件名和inode number的映射关系(类似于重命名)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost linux]# touch abc 
[root@localhost linux]# ln abc def 
[root@localhost linux]# ls -1i
    abc def 263466 abc 263466 def
  • abc和def的链接状态完全相同,他们被称为指向文件的硬链接。内核记录了这个连接数,inode 263466 的硬连接数为2(任何一个目录刚开始新建的时候引用计数一定是2) 目录A内部,新建一个目录会让目录A的引用计数自动+1
  • 我们在删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放
4.2.1 硬链接的作用
  1. 构建Linux的相对路径结构,让我们可以通过. ..来进行路径定位(Linux中,不允许给目录建立硬链接),但是.和..可以,因为.和..对应的文件名是固定的,所有的系统指令在设定的时候几乎都知道.和..是干什么的
  2. 一般用硬链接来做文件备份

4.3 软链接

硬链接是通过inode引用另外一个文件,软链接是通过名字引用另外一个文件,有独立的inode(类似于windows中的快捷方式)

软链接的内容:目标文件所对应的路径字符串

在shell中的做法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
263563 -rw-r--r--. 2 root root 0 915 17:45 abc
261678 lrwxrwxrwx. 1 root root 3 915 17:53 abc.s -> abc
263563 -rw-r--r--. 2 root root 0 915 17:45 def

4.4 acm

下面解释一下文件的三个时间:

  • Access 最后访问时间
  • Modify 文件内容最后修改时间
  • Change 属性最后修改时间

5.动态库和静态库

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
测试程序
/add.h/
#ifndef __ADD_H__
#define __ADD_H__ 
int add(int a, int b);
#endif // __ADD_H__
/add.c/
#include "add.h"
int add(int a, int b)
{
	return a + b;
}
/sub.h/
#ifndef __SUB_H__
#define __SUB_H__ 
int sub(int a, int b);
#endif // __SUB_H__
/add.c/
#include "add.h"
int sub(int a, int b)
{
	return a - b;
}
///main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"

int main(void)
{
	int a = 10;
	int b = 20;
	printf("add(10, 20)=%d\n", a, b, add(a, b));
	a = 100;
	b = 20;
	printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
}

5.1 生成静态库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost linux]# ls
add.c add.h main.c sub.c sub.h
[root@localhost linux]# gcc -c add.c -o add.o
[root@localhost linux]# gcc -c sub.c -o sub.o
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o 
ar是gnu归档工具,rc表示(replace and create)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
查看静态库中的目录列表
[root@localhost linux]# ar -tv libmymath.a 
rw-r--r-- 0/0 1240 Sep 15 16:53 2017 add.o
rw-r--r-- 0/0 1240 Sep 15 16:53 2017 sub.o
t:列出静态库中的文件
v:verbose 详细信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost linux]# gcc main.c -L. -lmymath
-L 指定库路径
-l 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行
5.1.1 库搜索路径
  • 从左到右搜索-L指定的目录。
  • 由环境变量指定的目录 (LIBRARY_PATH)
  • 由系统指定的目录 /usr/lib /usr/local/lib

5.2 生成动态库

  • shared: 表示生成共享库格式
  • fPIC:产生位置无关码(position independent code)
  • 库名规则:libxxx.so
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
示例: 
[root@localhost linux]# gcc -fPIC -c sub.c add.c 
[root@localhost linux]# gcc -shared -o libmymath.so *.o 
[root@localhost linux]# ls add.c add.h add.o libmymath.so main.c sub.c sub.h sub.o
5.2.1 使用动态库

编译选项:

  • l:链接动态库,只要库名即可(去掉lib以及版本号)
  • L:链接库所在的路径
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
示例: 
gcc main.o -o main –L. -lhello
5.2.2 运行动态库

拷贝.so文件到系统共享库路径下, 一般指/usr/lib

更改 LD_LIBRARY_PATH

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 [root@localhost linux]# export LD_LIBRARY_PATH=.
 [root@localhost linux]# gcc main.c -lmymath
 [root@localhost linux]# ./a.out
 add(10, 20)=30
 sub(100, 20)=80

ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 [root@localhost linux]# cat /etc/ld.so.conf.d/bit.conf 
 /root/tools/linux
 [root@localhost linux]# ldconfig

5.3 使用外部库

系统中其实有很多库,它们通常由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况的函数(ncurses库)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <math.h>
#include <stdio.h>
int main(void)
{
     double x = pow(2.0, 3.0);
     printf("The cubed is %f\n", x);
     return 0;
}

gcc -Wall calc.c -o calc -lm

-lm表示要链接libm.so或者libm.a库文件

5.4 库文件名称和引入库的名称

如:libc.so -> c库,去掉前缀lib,去掉后缀.so,.a

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Linux】从open到write:系统文件I/O 的奥秘与实战指南
在使用C语言时,我们需要访问文件通常会用到fopen、 fwrite、和fread还有fclose等函数。
Yui_
2024/11/19
1030
【Linux】从open到write:系统文件I/O 的奥秘与实战指南
【Linux】基础IO_文件操作
对于该函数path表示打开或创建的目标文件(默认会在当前路径下创建/打开),mode表示文件的打开方式。对于mode来说,这里就简单介绍以下几种(更多的在前文:点击跳转):
诺诺的包包
2023/04/07
7310
【Linux】基础IO_文件操作
【在Linux世界中追寻伟大的One Piece】IO基础
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问,先来直接以代码的形式,实现和上面一模一样的代码:
枫叶丹
2024/09/07
1230
【在Linux世界中追寻伟大的One Piece】IO基础
【读懂Linux】基础IO
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问:
小文要打代码
2024/10/22
1190
【读懂Linux】基础IO
嵌入式Linux:文件I/O和标准I/O库
文件 I/O (Input/Output)和标准 I/O 库是用于在 C 语言中进行文件操作的两种不同的方法。
不脱发的程序猿
2024/05/26
1750
【Linux】探索文件I/O奥秘,解锁软硬链接与生成动静态库知识
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针,那什么是FILE类型呢?这是C标准库自己封装的一个结构体。
用户11316056
2024/10/16
1140
【Linux】探索文件I/O奥秘,解锁软硬链接与生成动静态库知识
基础I/O--重定向&&缓冲区&&stderr
代码解释: 在这段代码中,使用了 open 函数打开文件,并通过 fd 文件描述符来引用该文件。然后,您使用 printf 和 fprintf 函数向标准输出写入内容,并使用 fflush 函数刷新标准输出缓冲区,确保内容被写入文件。最后,使用 close 函数关闭文件。
南桥
2024/05/26
1030
基础I/O--重定向&&缓冲区&&stderr
Linux基础IO全面介绍
原文:https://blog.csdn.net/AI_ELF/article/details/122547439
入门笔记
2022/06/03
4220
Linux基础IO全面介绍
Linux 之 详谈系统I/O文件及内核级缓冲区(看这一篇就够了)
打开文件的方式不仅仅是fopen, ifstream等流式, 语言层的方案, 其实系统才是打开文件最底层的方案. 不过, 在学习文件IO之前, 先要了解一下如何给函数传递标志位, 该方法在系统文件IO接口中会使用到:
用户11317877
2025/02/16
810
Linux 之 详谈系统I/O文件及内核级缓冲区(看这一篇就够了)
【Linux】文件操作、系统IO相关操作、inode和输入输出重定向
C语言中文件操作,在操作一个文件之前我们首先要打开它,那么在学了一段时间操作系统后,你知道在操作一个文件之前为什么要先打开吗? 文件存储在磁盘上,CPU执行进程访问文件,而CPU不能直接访问磁盘,所以对于存储在磁盘上的文件如果要被进程访问,首先应该加载到内存中,所以打开文件的过程就是将文件从磁盘加载到内存。
_小羊_
2025/01/24
920
【Linux】文件操作、系统IO相关操作、inode和输入输出重定向
【Linux】理解Linux中一切皆文件、缓冲区、ext2文件系统、软硬链接
在windows中是文件的东西,在linux中也是文件;其次一些在windows中不是文件的东西,比如进程、磁盘、显示器、键盘这样硬件设备也被抽象成了文件,你可以使用访问文件的方法访问它们获得信息;甚至管道,也是文件;将来我们要学习网络编程中的socket(套接字)这样的东西,使用的接口跟文件接口也是一致的。
_小羊_
2025/01/24
960
【Linux】理解Linux中一切皆文件、缓冲区、ext2文件系统、软硬链接
【Linux篇】文件描述符背后的秘密:让你的代码更加高效
功能:函数 fwrite() 将 nmemb 个数据项写入由 stream 指针指向的流中,每个数据项的长度为 size 字节,这些数据项从 ptr 所指向的位置获取。 返回值:fwrite() 返回已写入的数据项数量。注意:数据项并不是返回字节数,返回的是指定类型准确写入的个数。
熬夜学编程的小王
2025/04/09
1070
【Linux篇】文件描述符背后的秘密:让你的代码更加高效
基础I/O--文件系统
我们要进行文件操作,前提是程序运行起来了,所谓的文件的打开和关闭是CPU执行我们的代码才被打开或者关闭的。 fopen()函数:
南桥
2024/05/06
980
基础I/O--文件系统
【Linux】 拿下 系统 基础文件操作!!!
在C语言已经掌握文件操作的一些接口,接下来我们来从操作系统的层面来理解文件操作!!! 基础IO的篇章我们将讲解以下内容:
叫我龙翔
2024/05/26
1160
【Linux】 拿下 系统 基础文件操作!!!
【Linux】基础IO——系统文件IO&fd&重定向&理解
对于C语言的文件操作,首先我们需要打开(fopen)文件,打开失败将会返回NULL ,而打开成功则返回文件的指针(FILE*)
平凡的人1
2023/10/15
6020
【Linux】基础IO——系统文件IO&fd&重定向&理解
Linux:基础IO(一.C语言文件接口与系统调用、默认打开的文件流、详解文件描述符与dup2系统调用)
当在 C 语言中进行文件操作时,fopen() 和 fclose() 是两个非常重要的函数。下面我将详细讲解它们的作用和用法:
是Nero哦
2024/06/13
4000
Linux:基础IO(一.C语言文件接口与系统调用、默认打开的文件流、详解文件描述符与dup2系统调用)
Linux系统-基础IO
Linux基础IO 零、前言 一、C语言文件IO 1、C库函数介绍 2、stdin/stdout/stderr 二、系统文件IO 1、系统调用介绍 2、系统调用和库函数 三、文件描述符 1、open返回值 2、fd分配规则 四、重定向 1、概念及演示 2、dup2系统调用 3、重定向的原理 4、缓冲区和刷新策略 五、文件及文件系统 1、FILE 2、文件系统 3、软硬链接 六、动静态库 1、制作使用静态库 2、制作使用动态库 零、前言 本章主要讲解学习Linux基础IO流的知识 一、C语言文件IO 1
用户9645905
2022/11/30
1.5K0
Linux系统-基础IO
Linux-基础IO
  在刚开始学习Linux的时候,我们记住了Linux下一切皆文件,我们通过这篇文章来深入了解Linux下文件的构成及应用。
用户11029129
2024/06/04
1320
Linux-基础IO
【Linux】基础IO ——文件(上)
文件= 内容+属性 对应文件的操作,对内容的操作,对属性的操作 当文件没有被操作的时候,一般在磁盘中 当对文件进行操作的时候,一般在内存中,因为冯诺依曼体系规定 当我们对文件进行操作的时候,文件需要提前加载到内存中,提前加载的是属性 当我们对文件进行操作的时候,文件需要提前加载到内存中,不只有你在load,内存中一定存在大量的不同文件属性
lovevivi
2023/04/28
7610
【Linux】基础IO ——文件(上)
【Linux探索学习】第二十弹——基础IO:深入理解C语言文件I/O与Linux操作系统中的文件操作
https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482
GG Bond1
2024/12/10
1420
【Linux探索学习】第二十弹——基础IO:深入理解C语言文件I/O与Linux操作系统中的文件操作
推荐阅读
相关推荐
【Linux】从open到write:系统文件I/O 的奥秘与实战指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验