目录
1.文件的认识
2.C语言的文件操作
3.系统接口IO
1.open
2.write
3.read
4.close
4.文件描述符fd
5.重定向
dup2 系统调用
6.软硬链接
硬链接
软链接
1.文件 = 文件内容 + 文件属性
2.文件在磁盘中放着,我们访问文件本质上是进程在访问文件,要想向硬件写入只有操作系统有权力,普通用户如果想写入,就必须让OS提供接口,文件类的系统调用接口
3.OS层面的文件接口,这样的接口只有一套,而且具有跨平台性
4.C、C++、Java等语言都有文件操作接口,它们上层提供的库函数不一样,但是底层实现是一样的,都是OS的操作接口。
fopen
FILE fopen(const char path, const char* mode)
其中,path
是文件路径,mode
表示打开文件的模式,可以是以下值之一:
fopen()
函数打开一个文件,需要指定文件名和打开模式("w"表示写入模式,如果文件不存在则创建,如果存在则清空原内容)。fwrite()
或fprintf()
函数将数据写入已打开的文件。fclose()
函数关闭已经打开的文件。fprintf 其作用是格式化输出到一个流文件中
int fprintf (FILE* stream, const char*format, ...);
第一个是文件流,表示要将内容传给谁。第二个参数和可变参数列表是要传的内容。
fwrite 向文件中写入二进制数据
size_t fwrite(void *ptr, size_t size, size_t count, FILE *stream)
fputs 将字符串 s 写入文件
int fputs(const char *s, FILE *stream)
下面代码是应用
fopen(追加方式写入 'a')
stdin & stdout & stderr
在C语言中,stdin
、stdout
和stderr
是三个标准的I/O流,用于处理标准输入、标准输出和标准错误输出。它们是在标准库中预定义的文件指针,在C/C++程序中是默认打开的。
open
是一个在 Unix/Linux 系统中用于打开文件的系统调用接口。它是进行文件操作的重要接口之一,用于打开文件以进行读取、写入或其他操作。下面是关于 open
函数的详细介绍:
open是系统调用接口,返回的是文件描述符,并非文件流指针
int open(const char *pathname, int flags, mode_t mode);
参数类型 :
pathname
:要打开的文件路径。flags
:打开文件的标志,用于指定打开模式和行为。这些标志可以使用按位或运算组合起来。mode
:当使用 O_CREAT
标志时,指定新文件的权限。这个参数通常需要八进制形式的权限值,如 0666
返回值:
errno
表示错误类型常用的 flags
参数:
O_RDONLY
:只读模式打开文件。O_WRONLY
:只写模式打开文件。O_RDWR
:读写模式打开文件。O_CREAT
:如果文件不存在,则创建文件。O_TRUNC
:如果文件已存在,在打开时清空文件内容。O_APPEND
:在写入时追加到文件末尾。#include
#include
int main() {
umask(0);
int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
//等价与 fopen("log.txt","w")
if (fd == -1) {
perror("无法打开文件");
return 1;
}
// 打开文件后可以进行写入操作
close(fd); // 关闭文件
return 0;
}
ssize_t write(int fd, const void *buf, size_t count);
作用:用于将数据从缓冲区写入文件。
参数:
fd:文件描述符,指示要写入的文件。
buf:要写入的数据的缓冲区。
count:要写入的字节数。
返回值:返回实际写入的字节数,如果返回值为 -1,则表示出错。
ssize_t read(int fd, void *buf, size_t count);
fd
:文件描述符,指示要读取的文件。buf
:存储读取数据的缓冲区。count
:要读取的字节数。int close(int fd);
fd
:文件描述符。在Unix/Linux系统中,文件描述符(File Descriptor,通常缩写为 fd
)是一个用于标识打开文件或其他I/O资源的整数。它是操作系统内核用来跟踪文件和I/O流的一种方式。文件描述符在C语言中通常用于标识和操作文件、套接字、管道等。
fd在内核中本质是一个数组下标
文件描述符的分配规则:在files_struct
数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符
原本要向显示器打印的数据通过我们的操作写入到其它文件,就这叫重定向。
重定向有 输出重定向: > 追加重定向 : >> 输入重定向 : <
下面是我们之前输出重定向的使用
重定向的本质是:上层用的fd不变,在内核中改变fd对应的struct file*的地址。
本来1里面是标准输出的地址,改变成log.txt的地址
在 Linux 中,dup2
是一个系统调用,用于创建一个文件描述符的副本,并将副本连接到另一个文件描述符。它的原型如下:
int dup2(int oldfd, int newfd);
newfd be the copy of oldfd,新的fd是旧的fd的拷贝,那么最终拷贝的结果是根据oldfd来的。而且这里说的拷贝是覆盖,最终剩下的是oldfd的内容
这个图里面把1断开显示器,并且里面的值换成3,最终和3一致,输出重定向所以3是oldfd
硬链接是指在文件系统中创建一个文件的副本,这个副本与原始文件共享相同的 inode
(索引节点)。因此,硬链接与原始文件在文件系统中的位置和属性是一样的,它们实际上指向同一个数据块。删除一个硬链接并不会影响其他硬链接或原始文件,只有所有的链接都被删除后,文件的内容才会真正被释放。
硬链接的特点:
[kingxzq@localhost Documents]$ ln original.txt hardlink.txt
这将在同一目录下创建了一个名为 hardlink.txt
的硬链接。现在,original.txt
和 hardlink.txt
是硬链接,它们共享相同的 inode 和数据块,如下输出。
[kingxzq@localhost Documents]$ ll -i
total 0
37444362 -rw-rw-r--. 2 kingxzq kingxzq 0 Aug 24 15:22 hardlink.txt
37444362 -rw-rw-r--. 2 kingxzq kingxzq 0 Aug 24 15:22 original.txt
软连接是一个指向目标文件或目录的特殊文件,其中包含了目标文件的路径。它实际上是一个指向另一个文件的快捷方式,就像 Windows 系统中的快捷方式一样。软连接与硬链接不同,它有自己的 inode,并且可以跨越文件系统边界。
软连接的特点:
[kingxzq@localhost Documents]$ ln -s original.txt symlink.txt
软链接symlink.txt
则拥有独立空间,所以inode
与源文件并不相同,可以理解为快捷方式
[kingxzq@localhost Documents]$ ll -i
total 0
37444362 -rw-rw-r--. 2 kingxzq kingxzq 0 Aug 24 15:22 hardlink.txt
37444362 -rw-rw-r--. 2 kingxzq kingxzq 0 Aug 24 15:22 original.txt
37444368 lrwxrwxrwx. 1 kingxzq kingxzq 12 Aug 24 15:28 symlink.txt -> original.txt
这将在同一目录下创建了一个名为 symlink.txt 的软链接。现在,symlink.txt 是一个指向 original.txt 的符号链接。
现在,假设你编辑了 original.txt 中的内容。然后你可以观察到:
硬链接:original.txt 和 hardlink.txt 都会反映出内容的更改,因为它们实际上是同一个文件的两个名称。
软链接:symlink.txt 也会反映出内容的更改,因为它指向了 original.txt 的路径,而不是实际的数据块。
删除 original.txt 文件,然后观察:
硬链接:即使删除了 original.txt,hardlink.txt 仍然存在,因为硬链接与原始文件共享相同的数据块。
软链接:删除了 original.txt 后,symlink.txt 将变为无效,因为它指向的目标不存在。
这个例子说明了硬链接和软链接的不同行为和特性。