Linux--文件(2)-重定向和文件缓冲

简介: Linux--文件(2)-重定向和文件缓冲

命令行中的重定向符号

介绍和使用

在Linux的命令行中,重定向符号用于将命令的输入或输出重定向到文件或设备

常见的重定向符号

1.“>“符号:将命令的标准输出重定向到指定文件中,并覆盖原有的内容。

2.”>>“符号:将命令的标准输出重定向的指定文件中,并将输出结果追加到文件末尾。

3.”<“符号:将指定文件的内容作为命令的标准输入。

4."<<"符号:将命令的标准输入设置为指定的文本块。

在使用重定向符号时,应该确保文件或设备的权限设置正确,否则可能会出现无法访问或写入的错误

模拟实现

下面通过自定义shell来进行模拟实现重定向,加深印象。

自定义Shell的链接入口

文件缓冲问题

描述

文件缓冲是指将数据暂时存储在内存中,而不是立即写入到文件中这样可以提高文件操作的效率,因为将多次的写操作合并为一次,可以减少IO操作的效率

文件缓冲主要为两种类型:

  • 全缓冲:当填满缓冲区或遇到换行符时,才会执行写操作。例如,使用fwrite()函数写入数据时,默认是全缓冲。
  • 行缓冲:当遇到换行符时,才会执行写操作。例如,使用printf()函数输出数据时,默认是行缓冲。

可以使用setbuf()setvbuf()等函数来设置文件的缓冲方式。此外,使用fflush()函数可以强制刷新缓冲区,将缓冲区中的数据立即写入到文件中。

需要注意的是,文件缓冲只适用于标准I/O库函数(如stdio.h中的函数),对于直接使用系统调用进行文件操作的函数(如read()write()),没有文件缓冲的概念,数据会立即写入文件

例子

模拟实现

头文件:mystdio.h

#pragma once
#include <stdio.h>
#define SIZE 4096
#define NONE_FLUSH (1<<1) 
#define LINE_FLUSH (1<<2) 
#define FULL_FLUSH (1<<3) 
typedef struct _myFILE
{
    //char inbuffer[];
    char outbuffer[SIZE];
    int pos;
    int cap;
    int fileno;
    int flush_mode;
}myFILE;
myFILE *my_fopen(const char *pathname, const char *mode);
int my_fwrite(myFILE *fp, const char *s, int size);
//int my_fread();
void my_fflush(myFILE *fp);
void my_fclose(myFILE *fp);
void DebugPrint(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>
const char *toString(int flag)
{
    if(flag & NONE_FLUSH) return "None";
    else if(flag & LINE_FLUSH) return "Line";
    else if(flag & FULL_FLUSH) return "FULL";
    return "Unknow";
}
void DebugPrint(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(const char *pathname, const char *mode)
{
    int flag = 0;
    if(strcmp(mode, "r") == 0)
    {
        flag |= O_RDONLY;
    }
    else if(strcmp(mode, "w") == 0)
    {
        flag |= (O_CREAT|O_WRONLY|O_TRUNC);
    }
    else if(strcmp(mode, "a") == 0)
    {
        flag |= (O_CREAT|O_WRONLY|O_APPEND);
    }
    else
    {
        return NULL;
    }
    int fd = 0;
    if(flag & O_WRONLY)
    {
        umask(0);
        fd = open(pathname, flag, 0666);
    }
    else
    {
        fd = open(pathname, flag);
    }
    if(fd < 0) return NULL;
    myFILE *fp = (myFILE*)malloc(sizeof(myFILE));
    if(fp == NULL) return NULL;
    fp->fileno = fd;
    fp->cap = SIZE;
    fp->pos = 0;
    fp->flush_mode = LINE_FLUSH;
    return fp;
}
void my_fflush(myFILE *fp)
{
    if(fp->pos == 0) return;
    write(fp->fileno, fp->outbuffer, fp->pos);
    fp->pos = 0;
}
int my_fwrite(myFILE *fp, const char *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);
    }
    else if((fp->flush_mode & FULL_FLUSH) && fp->pos  == fp->cap)
    {
        my_fflush(fp);
    }
    return size;
}
void my_fclose(myFILE *fp)
{
    my_fflush(fp);
    close(fp->fileno);
    free(fp);
}

测试:

相关文章
|
3天前
|
存储 Linux Shell
Linux|Transfer.sh 轻松实现文件共享
Linux|Transfer.sh 轻松实现文件共享
17 2
Linux|Transfer.sh 轻松实现文件共享
|
18天前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
66 34
|
12天前
|
Linux
Linux文件与目录的日常
目录的切换 一般使用(”pwd“)显示当前所在的目录 比如:当前目录是在home下面的,与用户名相同的文件夹,可以使用(”cd“)命令来切换目录; 进入下载目录(”cd home/a/下载“)这种从给目录开头的一长串路经”叫做绝对路径“; 进入图片目录(”cd .. /图片/“)".."代表当前路径的上级路径,相对于当前的目录而言的”叫做相对路径“,(”.“)代表当前路径; 如果,想快速切换,上一个所在目录可以(”cd - / cd..“); 如果,想快速切换,追原始的目录可以(”cd --“); 查看目录及文件
35 14
|
8天前
|
Linux Shell
Linux 将所有文件和目录名重命名为小写
Linux 将所有文件和目录名重命名为小写
20 3
|
3月前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
99 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
3月前
|
Ubuntu Linux Go
golang编译成Linux可运行文件
本文介绍了如何在 Linux 上编译和运行 Golang 程序,涵盖了本地编译和交叉编译的步骤。通过这些步骤,您可以轻松地将 Golang 程序编译成适合 Linux 平台的可执行文件,并在目标服务器上运行。掌握这些技巧,可以提高开发和部署 Golang 应用的效率。
336 14
|
3月前
|
存储 NoSQL Linux
linux积累-core文件是干啥的
核心文件是Linux系统在程序崩溃时生成的重要调试文件,通过分析核心文件,开发者可以找到程序崩溃的原因并进行调试和修复。本文详细介绍了核心文件的生成、配置、查看和分析方法
184 6
|
3月前
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
539 6
|
4月前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
62 5
|
4月前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
77 6