Linux---文件操作

C语言中的文件读&写

在这里插入图片描述

#include <stdio.h>

int main()
{
  FILE* fp = fopen("log.txt","r");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  int ct = 5;
  char buf[64];
  while(ct){
  
    fgets(buf,sizeof(buf),fp);
    printf(buf);
    ct--;
  }
  /*
  int ct = 5;
  while(ct)
  {
    fputs("hello world \n",fp);
    ct--;
  }
  */
  fclose(fp);
  return 0;
}

stdin

在这里插入图片描述

标准输入

FILE* fp = fopen("log.txt","r");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  int ct = 5;
  char buf[64];
  while(ct){
  
    fgets(buf,sizeof(buf),stdin);
    printf(buf);
    ct--;
  }

在这里插入图片描述

stdout

标准输出

int ct = 5;
  while(ct)
  {
    fputs("hello world \n",stdout);
    ct--;
  }

在这里插入图片描述

stderr

标准错误

int ct = 5;
  while(ct)
  {
    fputs("hello world \n",stderr);
    ct--;
  }

在这里插入图片描述

a–追加写入

#include <stdio.h>

int main()
{
  FILE* fp = fopen("log.txt","a");//append
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  int ct = 5;
  while(ct)
  {
    fputs("hello L \n",fp);
    ct--;
  }
  
  fclose(fp);
  return 0;
}

在这里插入图片描述

write-- 覆盖写入

#include <stdio.h>

int main()
{
  FILE* fp = fopen("log.txt","w");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  int ct = 5;
  while(ct)
  {
    fputs("welcome!\n",fp);
    ct--;
  }
  
  fclose(fp);
  return 0;
}

在这里插入图片描述

系统中的I/O

接口

  • O_RDONLY 只读打开
  • O_WRONLY只写打开
  • O_RDWR读写打开
  • O_CREAT若文件不存在,则创建
  • O_APPEND追加写
  • 打开成功返回值 大于0
  • 打开失败返回1

文件描述符

在这里插入图片描述

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

int main()
{
  int fd = open("log.txt",O_WRONLY,0666);
  printf("fd: %d\n",fd);

  return 0;
}

在这里插入图片描述

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

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",fd);

  return 0;
}

在这里插入图片描述
在这里插入图片描述

找标志位

在这里插入图片描述
在这里插入图片描述

open

在这里插入图片描述

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

int main()
{
  int f1 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f1);
  int f2 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f2);
  int f3 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f3);
  int f4 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f4);
  int f5 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f5);

  return 0;
}

在这里插入图片描述

write&close

const char* msg = "welcome L\n";
  write(1,msg,strlen(msg));

在这里插入图片描述

char buff[32];
  read(0,buff,32);
  printf("%s\n",buff);

在这里插入图片描述

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
  int f1 = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(f1 < 0){
    
    printf("open error!\n");
  }
  printf("fd: %d\n",f1);
  
  int ct = 5;
  const char* msg = "hello world!\n";
  while(ct)
  {
    write(f1,msg,strlen(msg));//strlen不需要+1
    ct--;
  }

  close(f1);
  return 0;
}

在这里插入图片描述

read

#include <string.h>
int main()
{
  int f1 = open("log.txt",O_RDONLY);
  if(f1 < 0){
    
    printf("open error!\n");
  }
  printf("fd: %d\n",f1);
  
  char c;
  while(1)
  {
    ssize_t s = read(f1,&c,1);
    if(s <= 0)
    {
      break;
    }
    write(1,&c,1);//fwrite(,,,stdout);
  }
  close(f1);

  return 0;
}

在这里插入图片描述

文件标识符分配规则

从最小但是没有被使用的开始分配
在这里插入图片描述
在这里插入图片描述
关闭显示器(1)

 close(1);
  int f2 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f2);
  int f3 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f3);
  int f4 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f4);
  int f5 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f5);

  return 0;

在这里插入图片描述
关0

 close(0);
  int f2 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f2);
  int f3 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f3);
  int f4 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f4);
  int f5 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f5);

  return 0;

在这里插入图片描述

 close(0);
 close(2);
  int f2 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f2);
  int f3 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f3);
  int f4 = open("log.txt",O_WRONLY|O_CREAT,0666);
   printf("fd: %d\n",f4);
  int f5 = open("log.txt",O_WRONLY|O_CREAT,0666);
  printf("fd: %d\n",f5);

  return 0;

在这里插入图片描述

int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0){
    return 1;
  }
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);

  close(fd);

在这里插入图片描述

close(1);
int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0){
    return 1;
  }
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);
  write(fd,"hello\n",6);

  close(fd);

在这里插入图片描述

重定向

输出重定向

close(1);
int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0){
    return 1;
  }
  write(1,"hello\n",6);
  write(1,"hello\n",6);
  write(1,"hello\n",6);
  write(1,"hello\n",6);
  write(1,"hello\n",6);

  close(fd);

在这里插入图片描述

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

   printf("hello you:%d\n",123);
   printf("hello you:%c\n",'v');
   printf("hello you:%f\n",3.335);
   fflush(stdout);

在这里插入图片描述

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

   printf("hello",stdout);
   printf("hello",stdout);
   printf("hello",stdout);

在这里插入图片描述


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

   printf("hello",stdout);
   printf("hello",stdout);
   printf("hello",stdout);

在这里插入图片描述
重定向本质是修改文件描述符下标对应的struct file 指向的内容*
struct FILE 是一个结构体,里面必定包含一个成员叫fd

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
  umask(0);
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0)
  {
    perror("open");
    return 1;
  }
  //都属于C,FILE*
  printf("hello printf!\n");//stdout printf内部封装了stdout
  fprintf(stdout,"hello fprintf!\n");
  fputs("hello fputs %d %c %c\n",stdout);
  close(fd);
  return 0;

}

在这里插入图片描述

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
  close(1);//fd = 1
  umask(0);
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0)
  {
    perror("open");
    return 1;
  }
  //都属于C,FILE*,只认stdout(FILE*)的接口
  printf("hello printf!\n");//stdout printf内部封装了stdout
  fprintf(stdout,"hello fprintf!\n");
  fputs("hello fputs %d %c %c\n",stdout);
  close(fd);
  return 0;

}

在这里插入图片描述

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
  close(1);//fd = 1
  umask(0);
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0)
  {
    perror("open");
    return 1;
  }
  //都属于C,FILE*,只认stdout(FILE*)的接口
  printf("hello printf!\n");//stdout printf内部封装了stdout
  fprintf(stdout,"hello fprintf!\n");
  fflush(stdout);//让文件里把信息显示出来
  fputs("hello fputs %d %c %c\n",stdout);
  close(fd);
  return 0;

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标准输入

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
  umask(0);
  int fd = open("log.txt",O_RDONLY,0666);
  if(fd < 0)
  {
    perror("open");
    return 1;
  }
  //都属于C,FILE*,只认stdout(FILE*)的接口
  printf("hello printf!\n");//stdout printf内部封装了stdout
  fprintf(stdout,"hello fprintf!\n");
  fputs("hello fputs %d %c %c\n",stdout);
 fflush(stdout);//让文件里把信息显示出来

 char buff[50];
 fgets(buff,50,stdin);
 printf("%s\n",buff);
 close(fd);
  return 0;

}

在这里插入图片描述

输出重定向

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
 close(0);//stdin
  umask(0);
  int fd = open("log.txt",O_RDONLY,0666);
  if(fd < 0)
  {
    perror("open");
    return 1;
  }
  //都属于C,FILE*,只认stdout(FILE*)的接口
  printf("hello printf!\n");//stdout printf内部封装了stdout
  fprintf(stdout,"hello fprintf!\n");
  fputs("hello fputs %d %c %c\n",stdout);
 fflush(stdout);//让文件里把信息显示出来

 char buff[50];
 fgets(buff,50,stdin);
 printf("%s\n",buff);
 close(fd);
  return 0;

}

在这里插入图片描述

在这里插入图片描述

追加重定向

在这里插入图片描述

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
  close(1);//fd = 1

  umask(0);
  int fd = open("log.txt",O_WRONLY|O_APPEND);//a
  if(fd < 0)
  {
    perror("open");
    return 1;
  }
  //都属于C,FILE*,只认stdout(FILE*)的接口
  printf("hello printf!\n");//stdout printf内部封装了stdout
  fprintf(stdout,"hello fprintf!\n");
  fputs("hello fputs %d %c %c\n",stdout);
 fflush(stdout);//让文件里把信息显示出来

 return 0;

}

在这里插入图片描述
凡是显示到显示器上面的内容/从键盘读取的内容,都是字符,所以,键盘和显示器一般称之为“字符设备”

scanf/printf格式化输入输出需要把数字依据ASCII表转化为字符

查看fd 1&2的区别

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
  
  printf("hello printf!\n");//stdout
  perror("perror");//stderr
  fprintf(stdout,"stdout : hello fprintf\n");
  fprintf(stderr,"stderr : hello fprintf\n");
  return 0;
}

在这里插入图片描述
在这里插入图片描述
重定向1所以不往显示器上打印,但是不影响2所以fd=2的内容在显示器上显示

批量替换

NOMAL模式

  • 1、按ESC
  • :%s/替换/被替换/g

使用dup2系统调用

在这里插入图片描述

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
 
  umask(0);
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
  if(fd < 0){
    perror("open");
    return 1;
  }
  close(1);//打开之后再重定向
  dup2(fd,1);
  printf("hello printf\n");
  fprintf(stdout,"hello fprintf\n");
  fputs("hello fputs:%d %c %f\n",stdout);
  fflush(stdout);
  close(fd);
  return 0;
}

在这里插入图片描述

在myshell添加重定向动能

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#define len 1024
#define num 32
int main()
{
  int type = 0;//0 > 1 >> 2 <
  char cmd[len];
  char* myarg[num];
  while(1)
  {
    printf("[L@my_centos_mc dir]$");
    fgets(cmd,len,stdin);
    cmd[strlen(cmd)-1] = '\0';
    //printf("%s",cmd);
    //解析字符串
    //char* start  = cmd + strlen(cmd) - 1;
    char* start = cmd;
    while(*start != '\0')
    {
      if(*start == '>')
      {
        type = 0;
        *start = '\0';
        start ++;
        if(*start == '>')
        {
          type = 1;
          start++;
        }
        break;
      }
      if(*start == '<')
      {
        type = 2;
        *start = '\0';
        start++;
        break;
      }
      //start --;
      start++;
    }
    if(*start != '\0')
    {
      while(isspace(*start)){
        start++;
      }
      //printf("%s\n",start);
    }
    else{
      start = NULL;
    }
    myarg[0] = strtok(cmd," ");
    int i = 1;
    while(myarg[i] = strtok(NULL," "))
    {
      i++;
    }
    pid_t id = fork();
    if(id == 0)
    {
      //child
     if(start != NULL)
     {
       if(type == 0){
       
         int fd = open(start,O_CREAT|O_WRONLY,0644);
       
         if(fd < 0)
        {
          perror("open");
         exit(2);
        }
        dup2(fd,1);
       }
     }
     else if(type == 1)
     {
         int fd = open(start,O_APPEND,0644);
         if(fd < 0){
        
           perror("open");
           exit(2);
          }
         dup2(fd,1);
     }
     else if(type == 2)
     {
       int fd = open(start,O_RDONLY,0644);
       dup2(fd,0);
     }
     else{

     }
      execvp(myarg[0],myarg);
      exit(10);
    }
    int status = 0;
    pid_t ret = waitpid(id,&status,0);
    if(ret > 0)
    {
      printf("exit code: %d\n",WEXITSTATUS(status));
    }
  }
  /*
  char name[32];
  while(1)
  {
    gethostname(name,sizeof(name)-1);
    printf("%s\n",name);
  }*/
  return 0;
}

FILE

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

解释Linux下一切皆文件

在这里插入图片描述

缓冲

#include <stdio.h>
#include <unistd.h>
int main()
{
  /*
  printf("hello world!\n");//先执行hello world\n
  sleep(3);
  */
  printf("hello world!");//先被保存到缓冲区3秒再被刷新出来
  sleep(3);
  //fflush(stdout);//会被立即刷新出来
  return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
 
  //C语言函数
  printf("hello printf\n");
  fprintf(stdout,"hello fprintf\n");
  //system
  const char* msg = "hello write\n";
  write(1,msg,strlen(msg));
  return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
  //C语言函数
  printf("hello printf\n");
  fprintf(stdout,"hello fprintf\n");
  //system
  const char* msg = "hello write\n";
  write(1,msg,strlen(msg));
  
  fork();
  return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件系统

在这里插入图片描述

  • 模式
  • 磁盘链接数
  • 文件所有者
  • 大小
  • 最后修改日期
  • 文件名

磁盘

查看磁盘

在这里插入图片描述
在这里插入图片描述

inode

查看inode编号:ls -l -i
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

软硬链接

#include <stdio.h>

int main()
{
  printf("hello new !\n");
  return 0;
}

建立软链接

ln -s file  file-s

在这里插入图片描述

在这里插入图片描述

建立硬链接

ln  file  file-h

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • Access:最近被访问的时间
  • Modify:最近被修改的时间
  • Change:文件属性的变化

动态库和静态库

Linux
.so:动态库
.a:静态库
Windows
.dll:动态库
.lib:静态库
在这里插入图片描述
把动态库变为静态库

gcc -o file file.c -static

在这里插入图片描述

  • 静态库(.a):程序在编译链接时把库的代码链接到可执行文件中。程序运行时将不再需要静态库
  • 动态库(.so):程序在运行时才去链接动态库的代码,多个程序共享使用库的代码
  • 一个动态库链接的可执行文件仅仅 包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
  • 在可执行文件开始运行前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称之为动态链接
  • 动态库可以在多个程序中共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间

静态库
缺点:占空间(内存+磁盘),多个静态库程序加载时,一定会有在内存中存在大量重复代码
优点:与库无关,不需要库
动态库:
优点:节省空间(内存空间),库文件是通过地址空间共享的
缺点:必须依赖库,没有库,无法运行

生成静态库

在这里插入图片描述

  • 生成静态库:ar -rc libmymath.a file.o test.oar是gnu归档工具,rc(replace and create)
cat Makefile 
mylib=libcal.a
CC=gcc
$(mylib):add.o sub.o
		ar -rc $(mylib) $^

%.o:%.c
		$(CC) -c $<
.PHONY:clean
clean:
		rm -f $(mylib) *.o
.PHONY:output
output:
		mkdir -p mathlib/lib 
		mkdir -p mathlib/include 
		cp *.h mathlib/include
		cp *.a mathlib/lib 


  • 查看静态库中的目录列表:ar -tv libmymath.a test.o file.o t:列出静态库的文件 v:verbose 详细信息
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

cat test.c
#include <stdio.h>
#include <add.h>
int main()
{
  int x = 10;
  int y = 20;
  int z = my_add(x,y);
  printf("%d\n",z);
  return 0;
}

在这里插入图片描述

在这里插入图片描述

  • -I :头文件在哪里
  • -L:库文件在哪里
  • -l:链接哪个库

安装库的过程

把库拷贝到系统路径下

sudo cp mathlib/include/* /usr/include/

生成动态库

  • shared:表示生成共享库格式
  • FPIC:产生位置无关码
  • 库名规则:libxxx.so

使用动态库

  • l:链接动态库,只要库名即可(去掉lib及版本号)
  • L:链接库所在的路径

运行动态库

  • 拷贝.so文件到系统共享库路径下,一般指/usr/lib
  • 更改LD_LIBRARY_PATH
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • ldconfig 配置 /etc/ld.so.conf.d/,ldconfig更新
    在这里插入图片描述

使用外部库

  • -lm 表示要链接libm.so或libm.a库文件
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值