Linux——基础IO

这篇具有很好参考价值的文章主要介绍了Linux——基础IO。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

C语言文件操作        

fprintf​编辑

Linux下的文件操作(文件的系统调用接口) 

open

open的第三个参数

open的第二个参数

write

 read

文件描述符fd

进程与被打开文件的关系(理解的关键)

见见猪跑

fd文件描述符的分配规则

结论

重定向

输入重定向原理

 输出重定向原理

 dup2

dup2函数使用 

将重定向功能添加到myshell中

缓冲区的理解

举例引出缓冲区概念

生活相关

计算机相关 

 现象解释

缓冲区的刷新策略

模拟实现C语言中的fopen、fwrite、fclose、fflush

Makefile

myStdio.c

myStdio.h

main.c


C语言文件操作        


#include <stdio.h>
#include <string.h>


#define FILE_NAME  "log.txt"


// C语言操作
  int main()
  {
  FILE *fp = fopen(FILE_NAME, "w"); // r,w r+(读写,不存在出错),w+(读写,不存在创建)
  // FILE *fp=fopen(FILE_NAME,"r");//r,w r+(读写,不存在出错),w+(读写,不存在创建)
  // FILE *fp=fopen(FILE_NAME,"a");//r,w r+(读写,不存在出错),w+(读写,不存在创建)
  //  a+ 追加
  if (NULL == fp)
  {
    perror("fopen"); //
    return 1;
  }

  // // char buffer[64];

  // // //fgets是会给我们的字符串自动添加一个\0的 因此我们少传一个以至于让fegts有位置放\0
  // // while (fgets(buffer, sizeof(buffer) - 1, fp) != NULL)
  // // {
  // //   buffer[strlen(buffer)-1] = 0;//去掉\n
  // //   puts(buffer);
  // // }

  // //fprintf:将指定(信息)字符串输出到指定文件中
  // int cnt=5;
  // while(cnt)
  // {
  //   fprintf(fp,"%s:%d\n","hello mwb",cnt--);
  // }

  // 文件关闭
  fclose(fp);

  return 0;
}

fprintf

Linux下的文件操作(文件的系统调用接口) 

open

Linux——基础IO

 当我们打开一个不存在的文件时,如果没有对其设置具体权限,所产生的文件权限将会混乱。

open的第三个参数

Linux——基础IO

 当我们手动设置好权限后,就不会出现上图出现的情况了。

Linux——基础IO

Linux——基础IO

还可以手动消除系统中默认的文件掩码

umask(0);

open的第二个参数

使用位的或运算,对应需要以什么方式打开文件。

Linux——基础IO

 根据所需进行或运算。

write

Linux——基础IO


#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

#define FILE_NAME  "log.txt"


int main()
{

  
  int fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_APPEND, 0666);// 追加
  // int fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0666);//清空原文件内容
  // int fd = open(FILE_NAME, O_RDONLY);
  if (fd < 0)
  {
    perror("open");
    return 1;
  }

  

  int cnt = 5;
  char outBuffer[64];
  while (cnt)
  {
    sprintf(outBuffer, "%s:%d\n", "hellomwb", cnt--);

    write(fd, outBuffer, strlen(outBuffer));//向文件写入string的时候,要不要+1
  }

  
  close(fd);
}

 Linux——基础IO

 read

Linux——基础IO

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

#define FILE_NAME  "log.txt"



int main()
{

  int fd = open(FILE_NAME, O_RDONLY);
  if (fd < 0)
  {
    perror("open");
    return 1;
  }

  char buffer[1024];
  ssize_t num = read(fd, buffer, sizeof(buffer) - 1);

  if (num > 0)
  {
    buffer[num] = 0;//0,'\0',NULL 都是0
  }
  printf("%s", buffer);

  
  close(fd);
}

Linux——基础IO

文件描述符fd

进程与被打开文件的关系(理解的关键)

Linux——基础IO

一个进程可以打开很多文件,操作系统中一定有很多被打开的文件操作系统为了管理对应的打开文件必定要为文件创建对应的内核数据结构标识文件struct file{}。里面包含了文件的大部分属性。

task_struct当中有一个指针,该指针指向一个名为files_struct的结构体,在该结构体当中就有一个名为fd_array的指针数组,该数组的下标就是我们所谓的文件描述符。

当进程打开log.txt文件时,我们需要先将该文件从磁盘当中加载到内存,形成对应的struct file,将该struct file连入文件双链表,并将该结构体的首地址填入到fd_array数组当中下标为3的位置,使得fd_array数组中下标为3的指针指向该struct file,最后返回该文件的文件描述符给调用进程即可。

见见猪跑

分别打开5个不同的文件,并且打印他们的文件描述符。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>


#define FILE_NAME(number) "log.txt" #number



int main()
{


  int fd0 = open(FILE_NAME(1), O_WRONLY | O_CREAT | O_APPEND, 0666);
  int fd1 = open(FILE_NAME(2), O_WRONLY | O_CREAT | O_APPEND, 0666);
  int fd2 = open(FILE_NAME(3), O_WRONLY | O_CREAT | O_APPEND, 0666);
  int fd3 = open(FILE_NAME(4), O_WRONLY | O_CREAT | O_APPEND, 0666);
  int fd4 = open(FILE_NAME(5), O_WRONLY | O_CREAT | O_APPEND, 0666);
  
  printf("fd: %d\n", fd0);
  printf("fd: %d\n", fd1);
  printf("fd: %d\n", fd2);
  printf("fd: %d\n", fd3);
  printf("fd: %d\n", fd4);

  close(fd0);
  close(fd1);
  close(fd2);
  close(fd3);
  close(fd4);
  
}

Linux——基础IO

 我们能发现他们是连续的小整数:3 4 5 6 7。

1、为什么他们不是从0开始的?

因为0,1,2已经被占用了。

打印标准输入,标准输出,标准错误对应的文件描述符:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

int main()
{

  printf("stdin->fd: %d\n",stdin->_fileno);
  printf("stdout->fd: %d\n",stdout->_fileno);
  printf("stderr->fd: %d\n",stderr->_fileno);
}

Linux——基础IO

 2、为什么他们是连续的小整数?

他们其实是一个指针数组 struct file* fd_array[]的数组下标,这个结构体被存在task_struct里面一个指针指向。

3、C语言文件操作函数与Linux下的文件操作函数的关系是什么?

不仅C语言,C++、java、Python等等编程语言,只要在Linux下使用。他们其实都是封装了Linux下的系统调用接口。

Linux——基础IO

 跟操作系统层面的这张图是对应的,其他编程语言中的文件操作函数就在用户操作接口这一层。Linux——基础IO

fd文件描述符的分配规则

当我们把标准输入(fd=0),标准错误(fd=2)关闭的话会出现什么样的结果呢?(先不关闭1,因为1为标准输出,当我们把1关闭的时候观察不到输出的结果了)

Linux——基础IO

如图所示,当我们关闭0的时候,当我们再试图用open打开一个文件并且打印它的文件描述符的时候,它居然变成了0。

然后我们再尝试着关闭2试一下。 

Linux——基础IO

 同理,我们打开新文件的描述符变成了2。

当然,如果我们关闭1的话是观察不到结果的。

结论

我们文件描述符分配的规则是使用未被占用的最小的那个fd。

重定向

重定向本质就是让本应该输出到一个文件的数据重定向输出到另一个文件中。

输入重定向原理

比如我们需要实现一个让本该输出到显示器的文件数据输出到我们指定的文件当中,那我们就可以在打开一个文件之前把标准输出(fd=1)给关闭,那么我们该文件分配到的就是1的文件描述符。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  
  close(1);

  umask(0);
  int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
  if (fd < 0)
  {
    perror("open");
    return 1;
  }

  const char *msg = "hello mwb\n";
  write(1, msg, strlen(msg));
  fflush(stdout);
  close(fd);

  return 0;
}

Linux——基础IO  

原理:

Linux——基础IO

 输出重定向原理

同理,我们想要把从键盘输入的数据从文件中读取,就可以关闭标准输入(fd=0),然后再打开一个文件,在文件里面对标准输入进行写入。(其实写入的就是文件里面的内容)。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  close(0);
  

  umask(0);
  int fd = open("log.txt", O_RDONLY);
  if (fd < 0)
  {
    perror("open");
    return 1;
  }

  


  char line[64];
  while (1)
  {
    printf("> ");
    if(fgets(line, sizeof(line), stdin)==NULL) break;//stdin里面读取
    printf("%s",line);
  }

  
  close(fd);

  return 0;
}

Linux——基础IO

 dup2

要完成重定向我们只需进行fd_array数组当中元素的拷贝即可。

Linux——基础IO

dup2函数使用 

Linux——基础IO

也就是说dup2后看似我们使用的是newfd,其实使用的是oldfd,也就是说保留了oldfd。

这里其实很不好理解,我的简单理解就是,让我们使用oldfd的时候其实使用的是newfd的功能。

举例说明:将本该输出到显示屏上的数据显示到文件里面。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  

  umask(0);
  int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
 
  if (fd < 0)
  {
    perror("open");
    return 1;
  }



  dup2(fd, 1);
  printf("fd: %d\n", fd);
  fprintf(stdout, "fd: %d\n", fd);

  
  close(fd);

  return 0;
}

Linux——基础IO

从输出结果上我们发现,其实dup2和我们之前使用先关闭标准输出(fd=1)是有所不同的,当前文件的fd还是3,但是其实fd对应数组中的内容已经拷贝到1所在位置了,并且完成了重定向的操作。

将重定向功能添加到myshell中

配有详细注释,有意者可看。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

#define NUM 1024
#define OPT_NUM 64

//用宏定义出来各个文件操作

//没有特性
#define NONE_REDIR 0

//输入重定向
#define INPUT_REDIR 1

// 输出重定向
#define OUTPUT_REDIR 2

// 追加重定向
#define APPEND_REDIR 3


// 先在此处定义,然后while循环中将每次都对这两个变量重新赋初值
// 重定向的方式
int redirType = NONE_REDIR;
// 需要重定向的文件
char *redirFile = NULL;

//start就是重定向符号后面的字符串
#define trimSpace(start)    \
  do                        \
  {                         \
    while (isspace(*start)) \
      start++;              \
  } while (0)

char lineCommand[NUM];
char *myargv[OPT_NUM];
int lastCode = 0;
int lastSig = 0;


//检查我们输入的命令中是否包含'>' '<' '>>' 其实也就是是否需要进行重定向操作
void commandCheck(char *commands)
{
  //字符串为空直接终止进程报错
  assert(commands);


  // 从左到右扫描
  // 设置两个指针进行遍历操作(其实本质还是找是否有'>' '<' '>>')
  char *start = commands;
  char *end = commands + strlen(commands);

  //便利完成即可退出
  while (start < end)
  {
    // 根据我们遍历到的重定向符号进行相应的操作
    if (*start == '>')
    {
      *start = '\0';
      start++;
      //若一下if成立则说明是追加重定向'>>'
      if (*start == '>')
      {
        // 修改对应的宏来标记对应的重定向操作
        redirType = APPEND_REDIR;
        //继续遍历操作
        start++;
      }
      else
      {
                // 修改对应的宏来标记对应的重定向操作
        redirType = OUTPUT_REDIR;
      }
      trimSpace(start);
      //确定需要操作的文件
      redirFile = start;
      break;
    }
    else if (*start == '<')
    {
      //"cat<file.txt"
      *start = '\0';
      start++;
      trimSpace(start);
      
// 修改对应的宏来标记对应的重定向操作
      redirType = INPUT_REDIR;
      //确定需要操作的文件
      redirFile = start;
      break;
    }
    else
    {
      start++;
    }
  }
}

int main()
{
  while (1)
  {

    // 对重定向的方式和重定向的文件进行初始化
    //  重定向的方式
    redirType = NONE_REDIR;
    // 需要重定向的文件
    redirFile = NULL;

    errno = 0;
    // 输出提示符
    printf("用户名@主机名 当前路径# ");
    // 刷新缓冲区,将printf中打印的值给立即输出出来
    fflush(stdout);

     接受用户输入的字符串
    char *s = fgets(lineCommand, sizeof(lineCommand) - 1, stdin);
    assert(s != NULL);

    (void)s; // 为使shell不报错,进行强转去掉也无妨

     将我们输入的字符串进行分割

    // 目的是将我们输入指令后敲的那个回车给去掉
    lineCommand[strlen(lineCommand) - 1] = 0;
    // printf("test: %s\n",lineCommand);

    //"ls -a -l -i" -> "ls" "-a" "-l" "-i" -> l -> n

    // 字符串分割之前 要做检查
    // 在我们所输入字符串里面去检查是否有 '>' '>>' '<'
    commandCheck(lineCommand);

    // 字符串切割
    myargv[0] = strtok(lineCommand, " ");

    int i = 1;
     判断是否为ls命令,如果为ls命令 加上颜 色
    if (myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)
    {
      myargv[i++] = (char *)"--color=auto";
    }

    // 如果没有子串了,strtok->NULL,myargv[end]=NULL
    // 将切割后的子串一个个赋值给myargv 当切割结束刚好返回NULL
    // while判断条件中先赋值再判断
    while (myargv[i++] = strtok(NULL, " "))
      ;

     如果是cd命令,不需要创建子进程,让shell自己执行对应的命令
    // 本质就是执行系统接口
    // 像这种不需要让我们子进程来执行,而是让shell自己执行的命令 --- 内建/内置命令
    if (myargv[0] != NULL && strcmp(myargv[0], "cd") == 0)
    {
      if (myargv[1] != NULL)
        chdir(myargv[1]); // chdir可以直接改变当前进程目录
      continue;           // 直接退出此次while循环,已经不需要再使用子进程了
    }

    if (myargv[0] != NULL && myargv[1] != NULL && strcmp(myargv[0], "echo") == 0)
    {
      if (strcmp(myargv[1], "$?") == 0)
      {
        printf("%d, %d\n", lastCode, lastSig);
      }
      else
      {
        printf("%s\n", myargv[1]);
      }
      continue;
    }

     测试是否成功,条件编译(只是对我们前期简写代码的一个测试)
#ifdef DEBUG
    for (int i = 0; myargv[i]; i++)
    {
      printf("myargv[%d]: %s\n", i, myargv[i]);
    }
#endif

    // 执行命令
    // 使用fork创建子进程来完成我们需要完成的进程程序替换
    pid_t id = fork();
    // 如果id==-1 直接终止程序
    assert(id != -1);

    // 如果id==0则说明是子进程 接下来进行子进程内的进程程序替换
    if (id == 0)
    {
      // 因为命令是子进程执行的,真正重定向的工作一定是子进程来完成的
      // 如何重定向,是父进程要给子进程提供信息的
      // 这里重定向会影响父进程吗?
      // 不会,因为进程具有独立性,这里对文件的操作父进程中fd不会改变。

      switch (redirType)
      {
        // 如果没有重定向,什么都不做就行了
      case NONE_REDIR:
        break;

      case INPUT_REDIR:
      {

        int fd = open(redirFile, O_RDONLY);
        if (fd < 0)
        {
          perror("open");
          exit(errno);
        }
        // 重定向的文件已经打开了
        dup2(fd, 0);
      }
      break;

      case APPEND_REDIR:
      case OUTPUT_REDIR:
      {
        umask(0);
        int flags = O_WRONLY | O_CREAT;
        if (redirType == APPEND_REDIR)
          flags |= O_APPEND;
        else
          flags |= O_TRUNC;
        // 由于这里是输出重定向,如果文件不存在会自己创建,因此我们务必设置文件的权限
        int fd = open(redirFile, flags, 0666);
        if (fd < 0)
        {
          perror("open");
          exit(errno);
        }

        dup2(fd, 1);
      }

      break;

      default:
        printf("bug?\n");
        break;
      }

      // 执行程序替换的时候,会不会影响曾经进程打开的重定向文件
      // 不会 程序替换是在磁盘与物理地址之间进行的操作
      // 进程打开的重定向文件是在进程PCB中的操作,互不干涉
      execvp(myargv[0], myargv);
      // 替换后退出,让父进程能接受到退出码
      exit(1);
    }

    // 父进程在此等待子进程的退出,回收子进程的退出信息
    // 以防没有回收子进程造成僵尸进程
    int status = 0;
    pid_t ret = waitpid(id, &status, 0);
    assert(ret > 0);
    (void)ret;
    // 我们把退出码和退出信号保存在这两个变量中以便于一会儿我们打印
    lastCode = ((status >> 8) & 0xFF);
    lastSig = (status & 0x7F);
  }
}

 父子进程共有一块文件区域,由于文件区域不属于进程,因此不需要给子进程拷贝一份儿,至于他们指向文件区域如何后续操作,这里需要我们理解写时拷贝!

缓冲区的理解

举例引出缓冲区概念

生活相关

缓冲区类似与我们的外卖寄存柜,当外卖小哥给我们送外卖的时候,我们刚好在忙,外卖小哥不用当时就给我们交互。他可以把我们的外卖存放到寄存柜里面,然后等我们有空了就可以去拿,这样既不影响我们的正常工作,也给外卖员节省了很多时间。

Linux——基础IO

计算机相关 

我们之前讲过,CPU的计算速度(纳秒级别)是极快的,然而磁盘的读取速度(毫秒级别)相对于CPU来说非常慢,如果CPU什么都不干把时间都浪费到去等磁盘将数据读取到内存中,那岂不是效率极低,因此就引入了缓冲区的概念,在内核空间里面有一块内核缓冲区,可供我们的磁盘将数据加载到内存的时候先存放到内核缓冲区中,等CPU来使用。

Linux——基础IO 

 

 现象解释

Linux——基础IO

 以上代码如果直接执行,我们发现是四条打印内容,可是当我们重定向到log.txt中的时候,log.txt中的内容却与之前不同。我们能很好的观察到C语言的打印接口重复打印了两次,然而系统调用接口只打印了一次。

原因就是C语言缓冲区的存在,当我们fork之后会创建子进程,然而此时我们使用>将所打印的内容重定向到文件log.txt中的时候。会使用全缓冲来进行缓冲区的刷新,全缓冲:等缓冲区满或者关闭fd的时候会刷新缓冲区,然而父子进程会先后退出,然后就把我们文件的内容多拷贝了一份,先后退出进行缓冲区的刷新,造成了打印两份的操作。然而write是系统调用接口,不存在使用C语言层面的缓冲区的概念因此只打印一份。

缓冲区的刷新策略

1、无缓冲(没有缓冲区,对需要写入或者读取数据直接操作)

2、行缓冲(遇到'\n'进行刷新,一行刷新一次)

3、全缓冲(缓冲区满了才会进行刷新)文章来源地址https://www.toymoban.com/news/detail-456569.html

模拟实现C语言中的fopen、fwrite、fclose、fflush

Makefile

main:main.c myStdio.c
	gcc -o $@ $^ -std=c99
.PHONY:clean
clean:
	rm -f main

myStdio.c

#include "myStdio.h"

FILE_ *fopen_(const char *path_name, const char *mode)
{
    int flags = 0;
    int defaultMode = 0666;

    if (strcmp(mode, "r") == 0)
    {
        flags |= O_RDONLY;
    }
    else if (strcmp(mode, "w") == 0)
    {
        flags |= (O_WRONLY | O_CREAT | O_TRUNC);
    }
    else if (strcmp(mode, "a") == 0)
    {
        flags |= (O_WRONLY | O_CREAT | O_APPEND);
    }
    else
    {
        // TODO
    }
    int fd = 0;

    if (flags & O_RDONLY)
        fd = open(path_name, flags);

    else
        fd = open(path_name, flags, defaultMode);

    if (fd < 0)
    {
        const char *err = strerror(errno);
        write(2, err, strlen(err));
        return NULL; // 为什么打开文件失败会返回NULL
    }
    FILE_ *fp = (FILE_ *)malloc(sizeof(FILE_)); // 申请堆空间
    assert(fp);

    fp->flags = SYNC_LINE; // 默认设置成行刷新
    fp->fileno = fd;
    fp->cap = SIZE;
    fp->size = 0;
    memset(fp->buffer, 0, SIZE);

    return fp; // 为什么你们打开一个文件,就会返回一个 FILE* 指针
}
void fwrite_(const void *ptr, int num, FILE_ *fp)
{
    // 1、写入到缓冲区中
    memcpy(fp->buffer + fp->size, ptr, num); 
    //fp->buffer指向缓冲区的开头+fp->size指向size后,已经使用了size
    //所以接下里的文件应该放在size后面
    //memcpy的意思是将从ptr开始num个数据复制到从fp-buffer+fp->size的位置之后
    // 这里我们不考虑缓冲区溢出的问题
    fp->size += num;
    // 2、判断是否刷新
    if (fp->flags & SYNC_NOW)
    {
        write(fp->fileno, fp->buffer, fp->size);
        fp->size = 0; // 清空缓冲区
    }
    else if (fp->flags & SYNC_FULL)
    {
        if (fp->size == fp->cap)
            write(fp->fileno, fp->buffer, fp->size);
        fp->size = 0;
    }
    else if (fp->flags & SYNC_LINE)
    {
        // abcd\nef不考虑
        if (fp->buffer[fp->size - 1] == '\n')
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0;
        }
    }
    else
    {

    }
}
void fflush_(FILE_ *fp)
{
    if (fp->size > 0)
        write(fp->fileno, fp->buffer, fp->size);
        fsync(fp->fileno); //将数据,强制要求OS进行外设刷新!
        fp->size=0;
}
void fclose_(FILE_ *fp)
{
    fflush_(fp);
    close(fp->fileno);
}

myStdio.h

#pragma once


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include<stdlib.h>
#include<assert.h>

#define SIZE 1024
#define SYNC_NOW 1
#define SYNC_LINE 2
#define SYNC_FULL 4

typedef struct _FILE
{
    int flags;// 刷新方式
    int fileno;
    int cap; //buffer的总容量
    int size;//buffer当前的使用量
    char buffer[SIZE];
} FILE_;

FILE_ *fopen_(const char *pathname, const char *mode);
void fwrite_(const void *ptr, int num, FILE_ *fp);
void fclose_(FILE_ *fp);
void fflush_(FILE_ *fp);

main.c

#include "myStdio.h"
#include <stdio.h>

int main()
{
    FILE_ *fp = fopen_("./log.txt", "w");

    if (fp == NULL)
    {
        return 1;
    }
    int cnt = 10;
    const char *msg = "hello mwb ";
    while (1)
    {
        fwrite_(msg, strlen(msg), fp);
        fflush_(fp);
        sleep(1);
        printf("count: %d\n", cnt);
        // if (cnt == 5)
        //     fflush_(fp);
        cnt--;
        if (cnt == 0)
            break;
    }

    fclose_(fp);
    return 0;
}

到了这里,关于Linux——基础IO的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux:概述 、安装 、文件与目录结构 、vim编辑器 、网络配置 、远程登录 、系统管理 、基础命令 、软件包管理 、克隆虚拟机 、shell编程

    2.1.1、Linux是什么? Linux是一个操作系统(OS) 所谓的操作系统就是直接用来操作计算机底层硬件的软件。 2.1.2、Linux的出现 官网: https://www.centos.org/ 进入官网进行下载 有很多的镜像,以阿里云的为例: 3.3.1、下载 官网: https://www.vmware.com/ 这是下载的企业版,30天试用期,可

    2024年02月05日
    浏览(65)
  • Linux基础命令 - 文件及目录操作, 打印输出, 查找命令, 用户及权限管理, vi的使用等

    vi - 纯文本编辑器 vi命令 是UNIX操作系统和类UNIX操作系统中最通用的 全屏幕 纯文本编辑器。Linux中的vi编辑器叫 vim ,它是vi的 增强版 (vi Improved),与vi编辑器 完全兼容 ,而且实现了很多 增强功能 。 vi编辑器支持 编辑模式 和 命令模式 ,编辑模式下可以完成文本的编辑功

    2024年02月06日
    浏览(83)
  • 文件操作以及相关的函数,fputc,fgetc,fputs,fgtes,fprintf,fscanf,sprintf,sscanf

    🐶博主主页: @ᰔᩚ. 一怀明月ꦿ  ❤️‍🔥 专栏系列: 线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++ 🔥 座右铭: “不要等到什么都没有了,才下定决心去做” 🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🐰文

    2024年02月04日
    浏览(35)
  • Linux 命令操作(一)——文件和目录操作

    目录信息 参考链接 Linux常用操作命令大全 1.1、创建文件夹 1.1.1、创建目录 1.1.2、创建文件 touch命令操作 1.2、删除文件夹/文件 1.2.1、删除目录操作 1.2.2、删除文件 1.3、重命名目录或者文件名称 1.4、目录切换 1.5、目录以及文件列表查看 1.6、复制目录或者文件 -r 递归处理,将

    2024年02月03日
    浏览(46)
  • Linux 目录和文件常见操作

    就常见的命令: pwd pwd 显示当前的目录 我以如下的目录大致结构做一个简单的例子 cd 迁移到指定的路径,可以指定相对路径和绝对路径,默认相对 .指向当前路径,…/ 指向上一级的目录。 ls 列出文件及其目录 命令选项: -F 区分文件和目录,目录后面会加上/ -a 显示隐藏文

    2024年02月13日
    浏览(39)
  • 文件目录操作——Linux命令核心

    目录 相对路径和绝对路径  查看和切换工作目录 pwd 显示当前工作目录的绝对路径 cd 切换目录 列出目录内容 ls 列出目录的内容 创建和删除目录文件夹 mkdir创建一个新目录 rmdir 删除一个空的目录 touch 创建空文件 cp复制文件或者目录 rm 删除文件或目录  mv移动文件与目录或重

    2024年02月01日
    浏览(42)
  • Windows基础命令:目录和文件操作&文本处理&网络相关操作

    方法一:打开\\\"运行\\\"对话框(Win+R),输入cmd 也可以通过cmd /c 命令和cmd /k 命令的方式来直接运行命令(/c表示执行完命令后关闭cmd窗口;/k表示执行完命令后保留cmd窗口) 方法二:在任务栏直接搜索“cmd” 显示当前目录或改变当前目录 语法规则 (1)显示目录 显示当前驱动

    2024年02月05日
    浏览(43)
  • Linux文件目录操作命令-mv命令

            mv 命令是 move 的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录。  mv 命令中第二个参数类型的不同(是目标文件还是目标目录), mv 命令将文件重命名或将其移至一个新的目录中。当第二个参数类型

    2024年02月02日
    浏览(44)
  • 【文件IO】Linux 文件操作(一) —— 遍历指定目录下的所有文件

    目录 一、访问目录相关函数 1、打开/访问目录 (opendir / fdopendir) 2、读取目录内容 (readdir) 3、关闭目录 (closedir) 二、遍历指定目录下的所有文件 opendir / fdopendir 函数的作用是访问指定路径的目录,函数声明如下: (1) opendir opendir 函数是通过用户提供的目录路径来访问目录, 参

    2024年02月04日
    浏览(57)
  • 快速上手Linux核心命令(三):文件和目录操作命令

    目录 前言 cd 切换目录 pwd 显示当前路径 ls 显示目录下内容及相关属性信息 mkdir 创建目录 tree 以树形结构显示目录下的内容 touch 创建空白文件或改变文件的时间戳属性 cp 复制文件或目录 mv 移动或重命名文件 rm 删除文件或目录 chown 改变文件或目录的用户用户组 chmod 改变文件

    2023年04月23日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包