原文:

Linux – 基础 IO

文件的宏观理解:

狭义理解:

广义理解:

文件操作的归类认知:

系统角度:

文件 IO 相关操作

linux换行符_隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行

int fputs(const char *s, FILE *stream);

fputs 函数是将 s 所指向的数据往 stream 中所指向的文件中写

div不换行与div换行_隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

char * fgets ( char * str, int num, FILE * stream )

注:

fwrite 的使用方法

stdin & stdout & stderr

div不换行与div换行_linux换行符_隔世醒人香巴拉秘符·1^^^香巴拉秘符2

div不换行与div换行_linux换行符_隔世醒人香巴拉秘符·1^^^香巴拉秘符2

注:

系统文件 I/Oopen

#include 
#include 
#include 

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

注:

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符_div不换行与div换行

注:write read close lseek…… 与 C 语言文件相关接口用法类似

文件描述符 fd

div不换行与div换行_linux换行符_隔世醒人香巴拉秘符·1^^^香巴拉秘符2

注:

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

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

补充:

文件描述符的分配规则

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

总结:

重定向

linux换行符_div不换行与div换行_隔世醒人香巴拉秘符·1^^^香巴拉秘符2

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

补充:程序替换的时候不会影响重定向对应的数据结构的数据(程序替换影响的是进程虚拟地址空间部分,而重定向影响的是 files_struct 部分)

使用 dup2 系统调用

#include 
int dup2(int oldfd, int newfd);

注:

linux换行符_div不换行与div换行_隔世醒人香巴拉秘符·1^^^香巴拉秘符2

FILE

因为 IO 相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上linux换行符,访问文件都是通过 fd 访问的。因此 C 库当中的 FILE 结构体内部,必定封装了 fd

typedef struct _IO_FILE FILE; 在/usr/include/stdio.h
在/usr/include/libio.h
struct _IO_FILE {
 int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags
 //缓冲区相关
 /* The following pointers correspond to the C++ streambuf protocol. */
 /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
 char* _IO_read_ptr; /* Current read pointer */
 char* _IO_read_end; /* End of get area. */
 char* _IO_read_base; /* Start of putback+get area. */
 char* _IO_write_base; /* Start of put area. */
  char* _IO_write_ptr; /* Current put pointer. */
 char* _IO_write_end; /* End of put area. */
 char* _IO_buf_base; /* Start of reserve area. */
 char* _IO_buf_end; /* End of reserve area. */
 /* The following fields are used to support backing up and undo. */
 char *_IO_save_base; /* Pointer to start of non-current get area. */
 char *_IO_backup_base; /* Pointer to first valid character of backup area */
 char *_IO_save_end; /* Pointer to end of non-current get area. */
 struct _IO_marker *_markers;
 struct _IO_FILE *_chain;
 int _fileno; //封装的文件描述符
#if 0
 int _blksize;
#else
 int _flags2;
#endif
 _IO_off_t _old_offset; /* This used to be _offset but it's too small. */
#define __HAVE_COLUMN /* temporary */
 /* 1+column number of pbase(); 0 is unknown. */
 unsigned short _cur_column;
 signed char _vtable_offset;
 char _shortbuf[1];
 /* char* _save_gptr; char* _save_egptr; */
 _IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符_div不换行与div换行

总结:

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

printf fputs 等 库函数会自带缓冲区,而 write 系统调用没有带缓冲区。另外,我们这里所说的缓冲区,都是用户级缓冲区。其实为了提升整机性能,OS 也会提供相关内核级缓冲区。printf fprintf 是库函数, write 是系统调用,库函数在系统调用的 “上层”, 是对系统调用的 “封装”,但是 write 有内核级缓冲区linux换行符,而 printf fwrite fputs 等缓冲区是用户级缓冲区,由 C 标准库提供

注:系统调用函数与库函数尽量不要混在一起使用,可能会与统一使用的函数的运行结果有所差异

文件系统

文件:打开的文件、普通未打开的文件

打开的文件:属性与操作方法的表现就是 struct file{} 属于内存级文件

普通未打开的文件:磁盘上面未被加载到内存的

文件系统功能:将上述的这些文件管理起来

磁盘

磁盘是计算机主要的存储介质,可以存储大量的二进制数据,并且断电后也能保持数据不丢失。早期计算机使用的磁盘是软磁盘(Floppy Disk,简称软盘),如今常用的磁盘是硬磁盘(Hard disk,简称硬盘)。

补充:

磁盘的划分

我们可以将磁盘想象成磁带(线性结构),将磁盘看成一个线性空间(数组),类型为扇区的数组、数组个数为 10 亿多

div不换行与div换行_linux换行符_隔世醒人香巴拉秘符·1^^^香巴拉秘符2

这样划分就不用让 OS 读取数据时在哪个盘面、哪个磁道、哪个扇区找了,OS 与磁盘映射关系可以通过磁盘驱动来完成,这样也就做到强解耦性。无论换机械硬盘还是固态硬盘,OS 都不用改变读取磁盘数据的数据结构,只需改变磁盘的驱动程序即可

注:操作系统读取磁盘数据时的下标——LBA

inode

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

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

注:

总结:

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

大多是操作系统在同一个目录下是不允许存在同名文件的删除文件不需要清空该文件占据的所有的空间数据(只需将该文件的 inode 和对应的数据块无效化即可(文件对应 inode 和 Block 位图中的数字 1 设置为 0,并将该文件所对应的目录中的数据块的关于该文件内容清空即可)Linux 下属性和内容是分离的,属性 inode 保存的(在同一块块组 inode 编号是不同的,但是跨组的 inode 编号可能相同),内容 Data blocks 保存的

补充:

软硬连接

硬链接:

硬链接的应用场景:方便进行相对路径的路径的设置

因此,可以看出.、… 的底层实现是通过硬链接的方式来实现的

注:

软链接:

div不换行与div换行_隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符

注:硬链接是通过 inode 引用另外一个文件,软链接是通过名字引用另外一个文件

总结:软硬链接的区别:本质是是否是独立文件,有无独立 inode;用途:软链接可以指向特定的文件方便进行快速索引,硬链接是能进行相对路径设置

补充:

文件的 ACM

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符_div不换行与div换行

总结:

文件的 ACM 的应用场景:

动态库和静态库静态库与动态库

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_div不换行与div换行_linux换行符

注:

总结:

生成静态库

[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
生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o 
ar是gnu归档工具,rc表示(replace and create)
查看静态库中的目录列表
[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 详细信息
[root@localhost linux]# gcc main.c -I -L. -lmymath
-L 指定库路径
-I 指定头文件路径
-l 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行

隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符_div不换行与div换行

注:

C 语言编译时直接编译不用任何选项:

当自己的可执行程序编译时不想用这些选项:将头文件和库文件分别拷贝到默认路径下——库的安装(第三方库)(使用时必须带上 – l 库名称)当只有静态库时,没有动态库,用 gcc 编译(不加 – static)会直接用静态链接生成可执行程序

补充:

生成动态库

补充:

运行动态库

1.拷贝. so 文件到系统共享库路径下, 一般指 / usr/lib2.更改 LD_LIBRARY_PATH(当系统重启时使用之前添加的是无效的,应重新添加)

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:路径

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

div不换行与div换行_隔世醒人香巴拉秘符·1^^^香巴拉秘符2_linux换行符

【Linux常用命令速查手册】关注【入门小站】,后台回复 「1001」 自取。

近期热文

———END———
限 时 特 惠:本站每日持续更新海量各大内部创业教程,一年会员只需128元,全站资源免费下载点击查看详情
站 长 微 信:jiumai99

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注