Linux基础篇十 ——文件操作

原创 2016年06月23日 20:02:29

提起文件操作我们就不得不说起两个重要的部分,文件描述符和文件指针,相信很多人都会分不清这两个看起来十分相似的东西,但是,实际上他们两的差别是十分大的。我们先来看看他们到底是什么。

文件描述符:在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCB中保存着一份文件描述符表文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。

文件指针:C语言中使用文件指针做为I/O的句柄。文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构包括一个缓冲区和一个文件描述符。而文件描述符是文件描述符表的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在Windows系统上,文件描述符被称作文件句柄)。

每个进程在PCB中都保存着一份文件描述符表,文件描述符就是这个表的索引,已打开的文件在内核中用file结构体表示,文件描述符表中的指针指向file结构体。在file结构体中维护File Status Flag(file结构体的成员f_flags)和当前读写位置(file结构体的成员f_pos)。每个file结构体都指向一个file_operations结构体,这个结构体的成员都是函数指针,指向实现各种文件操作的内核函数。

eg:在用户程序中read一个文件描述符,read通过系统调用进入内核,然后找到这个文件描述符所指向的file结构体,找到file结构体所指向的file_operations结构体,调用它的read成员所指向的内核函数以完成用户请求。

每个file结构体都有一个指向dentry结构体的指针我们传给openstat等函数的参数的是一个路径,例如/home/akaedu/a,需要根据路径找到文件的inode为了减少读盘次数,内核缓存了目录的树状结构,称为dentry cache,其中每个节点是一个dentry结构体,只要沿着路径各部分的dentry搜索即可

每个dentry结构体都有一个指针指向inode结构体inode结构体保存着从磁盘inode读上来的信息。

inode结构体有一个指向super_block结构体的指针。super_block结构体保存着从磁盘分区的超级块读上来的信息

#include <stdio.h>
#include <errno.h>
#include <string.h>
#define _PATH_ "./log"
int main()
{
FILE *fp = fopen(_PATH_, "w");
if( NULL == fp ){
printf("%s open file %s error, error code is : %d\n",__FUNCTION__, _PATH_, error);
return 1;
}
char *str = "this is a test\n";
int i=0;
while( i<100 ){
fwrite(str, 1, strlen(str),fp);
i++;
}
fclose(fp);
return 0;
}
上面的例子里我们使用的是fwrite,接下来再让我们看一个write符来操作文件的例子

#include <unistd.h>
#include <stdio.h>
int glob = 6; 
char buf[] = "a write to stdout\n";
int
main(void)
{
int var;
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
perror("write error");
printf("before fork\n"); /* we don't flush stdout */
if ((pid = fork()) < 0) {
perror("fork error");
}else if (pid == 0) { /* child */
glob++; /* modify variables */
var++;
}else {
sleep(2); /* parent*/
}
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob,var);
exit(0);
}
**write是不带缓冲的(系统调用不带缓冲)

**标准I/O是缓冲的,标准输出到终端是行缓冲,否则就变成了全缓冲。

有时将结构定位到标准输出和文件里出现的结果是不同的,但是我们不必感到困惑,只不过是父进程的缓冲区的内容还没被刷新出来之前就被子进程复制了,所以子进程也会在

程序结束的时候在文件里刷新出重复的内容。

**父子进程的使用相同的描述符共享操作同一个文件。

fork之后处理的⽂件描述符有两种常见的情况:
⽗进程等待⼦进程完成。在这种情况下,⽗进程⽆需对其描述符做任何处理。当⼦进程终⽌后,⼦进程对⽂件偏移量的修改已执⾏的更新。
⽗⼦进程各⾃执⾏不同的程序段这种情况下,在fork之后,⽗⼦进程各⾃关闭他们不需要使⽤的⽂件描述符,这样就不会⼲扰对⽅使⽤⽂件描述符。




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux基础回顾(3)——常用命令及文件操作

问题来自Linux教材,答案自我整理难免会有不足之处。这是我Linux期末的总结 1. 简述Linux命令的一般格式。 命令+参数+对象 2.请说明下属命令的功能:dat...
  • C_Major
  • C_Major
  • 2014年12月16日 21:52
  • 1148

linux基础教程-----目录文件操作(1)

目录操作 目录的 创建、移动、改名字、复制、删除   ① 创建 make directory >mkdir 目录名字 >mkdir -p newdir/newdir [-p] //通过递归方式创...

linux学习之路(4)基础使用和常用文件操作命令

1、学会使用快捷键 Ctrl + C:这个是用来终止当前命令的快捷键,当然你也可以输入一大串字符,不想让它运行直接Ctrl + C,光标就会跳入下一行。  Tab: 这个键是最有用的键了,也是笔者...

黑马程序员——ios开发基础之C语言预处理命令与文件操作

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 第一讲  预处理命令...

黑马程序员——ios基础---C语言:结构体、条件编译、文件操作

一、结构体: 1、安全的字符串读取和输出的函数  读入字符串的方法:  1) scanf 缺点:不能接收空格  2) gets 优点:可以接受含有空格的字符串  3) fgets(); 优点:可以帮我...

Linux基础编程-文件操作open,lseek,read,write,close

Linux基础编程-文件操作open,lseek,read,write,closeLinux上面对文件的操作可以分为两种:1.Linux系统提供的API; 2.C标准的文件操作函数。前者依赖于Linu...
  • Yao_GUET
  • Yao_GUET
  • 2011年06月02日 11:10
  • 12451

Java基础——IO流和文件操作(下)

创建java文件列表 将一个指定目录下的java文件的绝对路径,存储到一个文件列表中,建立一个java文件列表文件 思路 1、对指定目录进行递归 2、获取递归过程中所得的java文件路...

C语言基础学习——第10天(文件操作)

C语言基础学习——第10天(文件操作)

【C#基础知识】——File(文件操作)Path类

Path静态类Path是静态类。只适用于操作路径的类。 Path常用的方法:1 . Path.GetFileName(string path) 获得指定的路径文件的名字和扩展名。 string st...
  • Joinl
  • Joinl
  • 2017年05月11日 20:17
  • 153

PHP基础学习1——文件操作

1简介 fopen是打开文件资源。 使用方法: $file=fopen("welcome.txt","r"); 具体意思:第一个参数是文件的路径。后面的参数是要求用何种方式...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux基础篇十 ——文件操作
举报原因:
原因补充:

(最多只允许输入30个字)