Linux基础IO

目录

1.文件的认识

2.C语言的文件操作

3.系统接口IO

1.open

2.write

3.read

4.close

4.文件描述符fd 

5.重定向

dup2 系统调用

6.软硬链接

硬链接

软链接


1.文件的认识

1.文件 = 文件内容 + 文件属性

2.文件在磁盘中放着,我们访问文件本质上是进程在访问文件,要想向硬件写入只有操作系统有权力,普通用户如果想写入,就必须让OS提供接口,文件类的系统调用接口

3.OS层面的文件接口,这样的接口只有一套,而且具有跨平台性

4.C、C++、Java等语言都有文件操作接口,它们上层提供的库函数不一样,但是底层实现是一样的,都是OS的操作接口。

2.C语言的文件操作

fopen

FILE fopen(const char path, const char* mode)	

其中,path 是文件路径,mode 表示打开文件的模式,可以是以下值之一:

Linux基础IO_第1张图片

  1. 打开文件:使用fopen()函数打开一个文件,需要指定文件名和打开模式("w"表示写入模式,如果文件不存在则创建,如果存在则清空原内容)。
  2. 写入数据:使用fwrite()fprintf()函数将数据写入已打开的文件。
  3. 关闭文件:使用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)

下面代码是应用

Linux基础IO_第2张图片

Linux基础IO_第3张图片

fopen(追加方式写入 'a')

Linux基础IO_第4张图片

Linux基础IO_第5张图片

stdin & stdout & stderr

在C语言中,stdinstdoutstderr是三个标准的I/O流,用于处理标准输入、标准输出和标准错误输出。它们是在标准库中预定义的文件指针,在C/C++程序中是默认打开的

Linux基础IO_第6张图片

3.系统接口IO

1.open

open 是一个在 Unix/Linux 系统中用于打开文件的系统调用接口。它是进行文件操作的重要接口之一,用于打开文件以进行读取、写入或其他操作。下面是关于 open 函数的详细介绍:

open是系统调用接口,返回的是文件描述符,并非文件流指针

int open(const char *pathname, int flags, mode_t mode);

参数类型 :

  • pathname:要打开的文件路径。
  • flags:打开文件的标志,用于指定打开模式和行为。这些标志可以使用按位或运算组合起来。
  • mode:当使用 O_CREAT 标志时,指定新文件的权限。这个参数通常需要八进制形式的权限值,如 0666

返回值:

  • 成功时,返回文件描述符(一个非负整数),用于以后的文件操作。
  • 失败时,返回 -1,并设置全局变量 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;
}

2.write

ssize_t write(int fd, const void *buf, size_t count);


作用:用于将数据从缓冲区写入文件。

参数:
fd:文件描述符,指示要写入的文件。
buf:要写入的数据的缓冲区。
count:要写入的字节数。


返回值:返回实际写入的字节数,如果返回值为 -1,则表示出错。

Linux基础IO_第7张图片

3.read

ssize_t read(int fd, void *buf, size_t count);
  • 作用:从文件中读取数据到缓冲区。
  • 参数:
    • fd:文件描述符,指示要读取的文件。
    • buf:存储读取数据的缓冲区。
    • count:要读取的字节数。
  • 返回值:返回实际读取的字节数,如果返回值为 0,则表示已到达文件末尾;如果为 -1,则表示出错。

Linux基础IO_第8张图片

4.close

int close(int fd);
  • 作用:关闭打开的文件。
  • 参数:fd:文件描述符。
  • 返回值:成功返回 0,出错返回 -1

4.文件描述符fd 

在Unix/Linux系统中,文件描述符(File Descriptor,通常缩写为 fd)是一个用于标识打开文件或其他I/O资源的整数。它是操作系统内核用来跟踪文件和I/O流的一种方式。文件描述符在C语言中通常用于标识和操作文件、套接字、管道等。

Linux基础IO_第9张图片

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

Linux基础IO_第10张图片

 fd在内核中本质是一个数组下标

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

5.重定向

原本要向显示器打印的数据通过我们的操作写入到其它文件,就这叫重定向。

重定向有   输出重定向:  >      追加重定向 : >>     输入重定向 : <

下面是我们之前输出重定向的使用

Linux基础IO_第11张图片

重定向的本质是:上层用的fd不变,在内核中改变fd对应的struct file*的地址。

Linux基础IO_第12张图片

本来1里面是标准输出的地址,改变成log.txt的地址

dup2 系统调用

在 Linux 中,dup2 是一个系统调用,用于创建一个文件描述符的副本,并将副本连接到另一个文件描述符。它的原型如下:

int dup2(int oldfd, int newfd);

Linux基础IO_第13张图片

newfd be the copy of oldfd,新的fd是旧的fd的拷贝,那么最终拷贝的结果是根据oldfd来的。而且这里说的拷贝是覆盖,最终剩下的是oldfd的内容

这个图里面把1断开显示器,并且里面的值换成3,最终和3一致,输出重定向所以3是oldfd 

Linux基础IO_第14张图片

6.软硬链接

硬链接是指在文件系统中创建一个文件的副本,这个副本与原始文件共享相同的 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 将变为无效,因为它指向的目标不存在。


这个例子说明了硬链接和软链接的不同行为和特性。
 

总结

Linux基础IO_第15张图片

你可能感兴趣的:(linux)