命令行中的重定向符号
介绍和使用
在Linux的命令行中,重定向符号用于将命令的输入或输出重定向到文件或设备。
常见的重定向符号:
1.“
>
“符号:将命令的标准输出重定向到指定文件中,并覆盖原有的内容。
2.”>>
“符号:将命令的标准输出重定向的指定文件中,并将输出结果追加到文件末尾。
3.”<
“符号:将指定文件的内容作为命令的标准输入。
4."<<
"符号:将命令的标准输入设置为指定的文本块。
在使用重定向符号时,应该确保文件或设备的权限设置正确,否则可能会出现无法访问或写入的错误。
模拟实现
下面通过自定义shell来进行模拟实现重定向,加深印象。
自定义Shell的链接入口
](https://img-blog.csdnimg.cn/direct/46130d2de9434b69956ccedd77bc39ce.png)
文件缓冲问题
描述
文件缓冲是指将数据暂时存储在内存中,而不是立即写入到文件中。这样可以提高文件操作的效率,因为将多次的写操作合并为一次,可以减少IO操作的效率。
文件缓冲主要为两种类型:
- 全缓冲:当填满缓冲区或遇到换行符时,才会执行写操作。例如,使用
fwrite()
函数写入数据时,默认是全缓冲。 - 行缓冲:当遇到换行符时,才会执行写操作。例如,使用
printf()
函数输出数据时,默认是行缓冲。
可以使用
setbuf()
、
setvbuf()
等函数来设置文件的缓冲方式。此外,使用
fflush()
函数可以强制刷新缓冲区,将缓冲区中的数据立即写入到文件中。
需要注意的是,文件缓冲只适用于标准I/O库函数(如
stdio.h
中的函数),对于直接使用系统调用进行文件操作的函数(如
read()
和
write()
),没有文件缓冲的概念,数据会立即写入文件。
例子
模拟实现
头文件:
mystdio.h
#pragmaonce#include<stdio.h>#defineSIZE4096#defineNONE_FLUSH(1<<1)#defineLINE_FLUSH(1<<2)#defineFULL_FLUSH(1<<3)typedefstruct_myFILE{//char inbuffer[];char outbuffer[SIZE];int pos;int cap;int fileno;int flush_mode;}myFILE;
myFILE *my_fopen(constchar*pathname,constchar*mode);intmy_fwrite(myFILE *fp,constchar*s,int size);//int my_fread();voidmy_fflush(myFILE *fp);voidmy_fclose(myFILE *fp);voidDebugPrint(myFILE *fp);
源文件:
mystdio.c
#include"mystdio.h"#include<string.h>#include<sys/stat.h>#include<sys/types.h>#include<fcntl.h>#include<stdlib.h>#include<unistd.h>constchar*toString(int flag){if(flag & NONE_FLUSH)return"None";elseif(flag & LINE_FLUSH)return"Line";elseif(flag & FULL_FLUSH)return"FULL";return"Unknow";}voidDebugPrint(myFILE *fp){printf("outbufer: %s\n", fp->outbuffer);printf("fd: %d\n", fp->fileno);printf("pos: %d\n", fp->pos);printf("cap: %d\n", fp->cap);printf("flush_mode: %s\n",toString(fp->flush_mode));}
myFILE *my_fopen(constchar*pathname,constchar*mode){int flag =0;if(strcmp(mode,"r")==0){
flag |= O_RDONLY;}elseif(strcmp(mode,"w")==0){
flag |=(O_CREAT|O_WRONLY|O_TRUNC);}elseif(strcmp(mode,"a")==0){
flag |=(O_CREAT|O_WRONLY|O_APPEND);}else{returnNULL;}int fd =0;if(flag & O_WRONLY){umask(0);
fd =open(pathname, flag,0666);}else{
fd =open(pathname, flag);}if(fd <0)returnNULL;
myFILE *fp =(myFILE*)malloc(sizeof(myFILE));if(fp ==NULL)returnNULL;
fp->fileno = fd;
fp->cap = SIZE;
fp->pos =0;
fp->flush_mode = LINE_FLUSH;return fp;}voidmy_fflush(myFILE *fp){if(fp->pos ==0)return;write(fp->fileno, fp->outbuffer, fp->pos);
fp->pos =0;}intmy_fwrite(myFILE *fp,constchar*s,int size){// 1. 写入memcpy(fp->outbuffer+fp->pos, s, size);
fp->pos += size;// 2. 判断,是否要刷新if((fp->flush_mode & LINE_FLUSH)&& fp->outbuffer[fp->pos-1]=='\n'){my_fflush(fp);}elseif((fp->flush_mode & FULL_FLUSH)&& fp->pos == fp->cap){my_fflush(fp);}return size;}voidmy_fclose(myFILE *fp){my_fflush(fp);close(fp->fileno);free(fp);}
测试:
版权归原作者 诡异森林。 所有, 如有侵权,请联系我们删除。