Linux——标准IO

news2024/9/26 3:29:32

文件的基础

  • 概念:一组相关数据的有序集合

  • 文件的类型:
    常规文件-r
    目录文件-d
    字符设备文件-c:键盘
    块设备文件-b:U盘 磁盘
    管道文件-p
    套接字文件-s
    符号链接文件-I:快捷方式

标准I/O 流

  • file
    标准IO用一个结构体类型来保存打开的文件的相关信息
    标准的IO操作都是围绕file来进行的

  • 流(stream)
    file有被称为流(stream)
    文本流/二进制流
    在这里插入图片描述

文本流/二进制流

  • window :
    二进制流:换行符 ‘/n’
    文本流:换行符:‘/r’ ‘/n’

  • linux:
    换行符:‘/n’

流的缓冲的类型

  • 全缓冲:缓冲区写满再将数据写入磁盘
  • 行缓冲:当行结束时,将数据写入磁盘
  • 无缓冲:直接读写磁盘

  • 标准的输入流
  • 标准的输出流
  • 标准的错误流

文件的打开和关闭

  • 打开:占用资源

  • 关闭:释放资源

  • 打开函数:FILE *fopen (const char *path, const char *mode);

    • Path:普通文件当前路径不需要加目录,其他要使用完整的路径
    • Mode:
      在这里插入图片描述
    • 返回值:出现错误返回NULL,使用必须判断是否为空

文件的关闭

函数:int fclose(FILE *stream)

  • fclose()调用成功返回0,失败返回EOF(-1),并设置errno
  • fclose()函数的入参stream必须保证为非空,否则出现断错误。

打开关闭练习

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

int main() {
  FILE *fp;
  int ret;
  fp = fopen("test.txt", "r");
  if (fp = NULL) {
    perror("fopen");
    printf("fopen:%s\n", strerror(errno));
  } else {
    printf("Open file success\n");
  }
  ret = fclose(fp);
  if (ret == 0) {
    printf("file close sucess\n");
  } else {
    perror("fclose");
    printf("fclose:%s\n", strerror(errno));
  }
  return 0;
}

字符的输入

读单个字符

  • int fgetc(FILE *stream);
  • int getc(FILE *stream); //宏
  • int getchar(void);

成功时返回读取的字符;若到文件末尾或出错时返回EOF(-1),
getchar()等同于fgetc(stdin)
getc和fgetc区别是一个是宏一个是函数

读取整个行

  • char *gets(char *s); 读取标准输入到缓冲区s
  • char *fgets(char *s, int size, FILE *stream);
    成功时返回s,到文件末尾或出错时返回NULL
    遇到’\n’或已输入size-1个字符时返回,总是包含’\0’

字符的输出

写单个字符

  • int fputc(int c, FILE *stream);
  • int putc(int c, FILE *stream);
  • int putchar(int c);
    成功时返回写入的字符;出错时返回EOF
    putchar©等同于fputc(c, stdout)

读取整个行

  • int puts(const char *s);
  • int fputs(const char *s, FILE *stream);

成功时返回非负整数;出错时返回EOF
puts将缓冲区s中的字符串输出到stdout,并追加’\n’
fputs将缓冲区s中的字符串输出到stream,不追加 ‘\n’

二进制读写

文本文件和二进制的区别:
存储的格式不同:文本文件只能存储文本。

二进制读写函数格式:

  • size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
    void *ptr 读取内容放的位置指针
    size_t size 读取的块大小
    size_t n 读取的个数
    FILE *fp 读取的文件指针

  • size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
    void *ptr 写文件的内容的位置指针
    size_t size 写的块大小
    size_t n 写的个数
    FILE *fp 要写的文件指针

流的刷新

int fflush(FILE *fp);

成功时返回0;出错时返回EOF
将流缓冲区中的数据写入实际的文件
Linux下只能刷新输出缓冲区,输入缓冲区丢弃

如果输出到屏幕使用fflush(stdout)

流的定位:

long ftell(FILE *stream);
long fseek(FILE *stream, long offset, int whence);
void rewind(FILE *stream);
fseek 参数whence参数:SEEK_SET/SEEK_CUR/SEEK_END
SEEK_SET 从距文件开头 offset 位移量为新的读写位置
SEEK_CUR:以目前的读写位置往后增加 offset 个位移量
SEEK_END:将读写位置指向文件尾后再增加 offset 个位移量
offset参数:偏移量,可正可负
注意事项:
1.文件的打开使用a模式 fseek无效
2.rewind(fp) 相当于 fseek(fp,0,SEEK_SET);
3.这三个函数只适用2G以下的文件

格式化输出(重要)

int fprintf(FILE *stream, const char *fmt, …);
int sprintf(char *s, const char *fmt, …);

成功时返回输出的字符个数;出错时返回EOF

格式化输入

int fscanf(FILE *stream, const char *format, …);
int sscanf(const char *str, const char *format, …);

文件IO的API

文件描述符概念:
英文:缩写fd(file descriptor)
是0-1023的数字,表示文件。
0, 1, 2 的含义 标准输入,标准输出,错误

  • 文件IO 打开 open
    int open(const char *pathname, int flags); 不创建文件
    int open(const char *pathname, int flags, mode_t mode); 创建文件,不能创建设备文件
    成功时返回文件描述符;出错时返回EOF

文件IO和标准的模式对应关系:
r—— O_RDONLY
r+—— O_RDWR
w —— O_WRONLY | O_CREAT | O_TRUNC, 0664
w+ —— O_RDWR | O_CREAT | O_TRUNC, 0664
a —— O_WRONLY | O_CREAT | O_APPEND, 0664
a+ —— O_RDWR | O_CREAT | O_APPEND, 0664

  • umask概念:
    umask 用来设定文件或目录的初始权限
  • 文件的关闭
    int close(int fd)
    关闭后文件描述符不能代表文件

对目录的操作

打开目录

#include <dirent.h>
DIR *opendir(const char *name);
DIR *fdopendir(int fd); 使用文件描述符,要配合open函数使用
DIR是用来描述一个打开的目录文件的结构体类型
成功时返回目录流指针;出错时返回NULL

读取目录

#include <dirent.h>
struct dirent *readdir(DIR *dirp);

struct dirent是用来描述目录流中一个目录项的结构体类型
包含成员char d_name[256] 参考帮助文档
成功时返回目录流dirp中下一个目录项;
出错或到末尾时时返回NULL

关闭目录

closedir函数用来关闭一个目录文件:
#include <dirent.h>
int closedir(DIR *dirp);

成功时返回0;出错时返回EOF

修改文件权限

chmod/fchmod函数用来修改文件的访问权限:
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

成功时返回0;出错时返回EOF

获取文件属性

#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);

成功时返回0;出错时返回EOF
如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性

练习:使用文件IO实现“每隔1秒向文件1.txt写入当前系统时间,行号递增”

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

int main() {
  int fd;
  int ret;
  time_t ctime;
  struct tm *ctimestr;
  int linecount = 0;
  char rbuf[32];
  char wbuf[32];

  fd = open("1.txt", O_RDWR | O_CREAT | O_APPEND, 0666);
  if (fd < 0) {
    perror("open");
    return 0;
  }

  while (1) {
    memset(rbuf, 0, sizeof(rbuf));
    ret = read(fd, rbuf, sizeof(rbuf)); //写入字符串长度 "\0结束"

    if (ret < 0) {
      perror("write");
      ret = close(fd);
      return 0;
    }
    if (ret == 0) {
      break;
    }
    if (strcmp(rbuf, "\n")) {
      linecount++;
    }
  }

  while (1) {
    ctime = time(NULL);           //获取当前时间
    ctimestr = localtime(&ctime); //转换为结构体格式
    sprintf(wbuf, "%d, %04d-%02d-%02d %02d:%02d:%02d\n", linecount,
            ctimestr->tm_year + 1900, ctimestr->tm_mon + 1, ctimestr->tm_mday,
            ctimestr->tm_hour, ctimestr->tm_min, ctimestr->tm_sec);
    printf("wbuf:%s", wbuf);
    ret = write(fd, wbuf, sizeof(wbuf)); 
    if (ret < 0) {
      perror("write");
      ret = close(fd);
      return 0;
    }
    linecount++;
    sleep(1);
  }

  ret = close(fd);
  if (ret < 0) {
    perror("close");
    return 0;
  }

  return 0;
}

练习:遍历一个文件夹下所有文件,并打印文件权限、大小和日期

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

#define FILENAME "./day5_1"
int main() {
  DIR *dp;
  struct dirent *dt;
  struct stat buf;
  int ret;
  struct tm *t;

  dp = opendir(FILENAME);
  if (dp < 0) {
    perror("opendir");
    return 0;
  }

  while ((dt = readdir(dp)) != NULL) {

    if (strcmp(dt->d_name, ".") == 0 || strcmp(dt->d_name, "..") == 0) {
      continue;
    }
    // printf("%s\n", dt->d_name);

    char name[64] = {0};
    memset(name, 0, sizeof(name));
    memcpy(name, FILENAME, sizeof(FILENAME));
    strcat(name, "/");
    strcat(name, dt->d_name);
    // printf("%s\n", name);
    ret = stat(name, &buf);
    if (ret < 0) {
      perror("stat");
      return 0;
    }

    if (S_ISREG(buf.st_mode)) {
      printf("-");
    }
    if (S_ISDIR(buf.st_mode)) {
      printf("d");
    }
    if (S_ISCHR(buf.st_mode)) {
      printf("c");
    }
    if (S_ISBLK(buf.st_mode)) {
      printf("b");
    }
    if (S_ISFIFO(buf.st_mode)) {
      printf("p");
    }
    if (S_ISSOCK(buf.st_mode)) {
      printf("s");
    }

    for (size_t i = 0; i < 8; i++) {
      if (buf.st_mode & (1 << i)) {
        switch (i % 3) {
        case 2:
          printf("r");
          break;
        case 1:
          printf("w");
          break;
        case 0:
          printf("x");
          break;
        }
      } else {
        printf("-");
      }
    }

    printf(" %d", (int)buf.st_size);

    t = localtime(&buf.st_ctime);

    printf(" %d-%d-%d %d:%d:%d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
           t->tm_hour+8, t->tm_min, t->tm_sec);//小时+8北京时间
    printf(" %s\n", dt->d_name);
  }

  closedir(dp);

  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/127243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据质量管理—理论大纲与实践(B站)

0、背景 故事的开头&#xff0c;是一位业务部门的同事找到我们&#xff0c;咨询了一个经典问题&#xff1a; 「需求方经常说我们做的报表看起来数据不准&#xff0c;有什么办法吗&#xff1f;」 为了解释这个问题&#xff0c;我以我们团队在数据质量管理中积累下来的方法&am…

决策树和随机森林的python实现

文章目录决策树实现方法测试更好地展示结果调参调整max_depthscoring利用GridSearchCV确定最佳max_depthmin_samples_splitmin_impurity_decreasemax_features多参数同时选优采用最优参数特征重要性排序随机森林测试调参n_estimators调整max_depth调整max_features调整min_samp…

黑马Hive+Spark离线数仓工业项目--数仓事实层DWB层构建(2)

工单事实指标构建 目标&#xff1a;实现DWB层工单事实指标表的构建 实施 建表 抽取 安装事实指标需求分析 目标&#xff1a;掌握DWB层安装事实指标表的需求分析 路径 - step1&#xff1a;目标需求 - step2&#xff1a;数据来源 实施 目标需求&#xff1a;基于设备安装信…

Python【继承】复写使用父类成员

继承&#xff1a;继承就是一个类&#xff0c;继承另外一个类的成员变量&#xff08;属性&#xff09;和成员方法 继承的作用&#xff1a;子类通过继承父类的属性和方法&#xff0c;在调用的时候&#xff0c;除了可以使用子类自身的成员方法和属性外&#xff0c;还可以使用父类…

模型不达标调整

一 、模型不达标调整 模型构建就是——科学的研究问题的数学表达&#xff1b;比如线性回归模型中的模型公式。 在进行建模时&#xff0c;很多同学会遇到模型不达标的问题&#xff0c;这种情况很常见&#xff0c;通常需要进行模型不达标的调整。 模型不好如何处理 模型拟合不…

使用扩散模型训练文本贴图

🍿*★,*:.☆欢迎您/$:*.★* 🍿 整个代码除了数据处理 其他是借鉴而来 那么说说 数据处理 采取的是使用pil 将某种字体中文写入到图片上去 而后生成图,最后进行加噪生成数据集 简单的利用生成器进行 batch 训练了100epoch 可以简单的生成一些带有文字的图 import numpy a…

数据可视化①:dashboard展示大学生就业现状

大学生就业是和我们息息相关的话题&#xff0c;每一位大学生都关注着&#xff0c;我们常常在网络上看到有关大学生就业的话题&#xff0c;比如毕业季的一些讨论。在大一的创新创业课中&#xff0c;我们也了解到自己所学的专业和以后如何就业&#xff0c;往哪方面就业。但我们了…

linux下安装java环境(小D课堂)

VirtualBox下载安装&#xff1a; 官网去下载就好了。 然后安装就可以了。 然后我们去安装我们的centos7. 然后我们可以从这里选择&#xff0c;然后进行下载。 这里我就用它默认的大小&#xff0c;后面还可以去改。 然后这个虚拟机我们就创建完成了。 我们去双击打开它&#xff…

2023年MCM/ICM美国大学生数学建模竞赛报名通知

一、竞赛背景 美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff09;由美国数学及其应用联合会主办&#xff0c; 是唯一的国际性数学建模竞赛&#xff0c;自1985年以来&#xff0c;美国大学生数学建模竞赛已经成功举办38届&#xff0c;也是世界范围内最具影响力的数学建模竞…

微信小程序集成three.js--2.创建不同材质的物体

1.实例演示 小程序集成Three.js,创建不同材质的物体2.源码 &#xff08;1&#xff09;引入three.js库文件 import * as THREE from ../../libs/three.weapp.js import {OrbitControls } from ../../jsm/controls/OrbitControls const app getApp() 库文件下载及配置看这里ht…

【STM32F4系列】【HAL库】【自制库】模拟IIC主机

介绍 本项目是利用GPIO模拟I2C的主机 网上常见的是模拟I2C主机 本项目是作为一个两个单片机之间低速通信的用法 协议介绍请看,传送门 模拟从机请看这里 主机 功能描述 I2C按字节(Byte)读写I2C读写寄存器I2C连续读写 编程思路解析 主机是时钟信号的发起方,起始和中止信号…

【Python百日进阶-数据分析】Day141 - plotly桑基图:plotly.graph_objects.Sankey()

文章目录一、语法二、参数三、返回值四、实例4.1 基本桑基图4.2 桑基图的hovertemplate和customdata4.3 定义节点位置4.4 带有彩色链接的更复杂的桑基图4.5 Dash中的桑基图4.6 风格桑基图一、语法 用于网络流量数据分析的桑基图。节点在 中指定&#xff0c;nodes源和目标之间的…

Flutter GetX系列教程---BottomSheet

安装 将 GetX 添加到你的 pubspec.yaml 文件中 dependencies:get: ^4.6.5在需要用到的文件中导入&#xff0c;它将被使用。 import package:get/get.dart;BottomSheet介绍 BottomSheet 是底部弹出的一个组件&#xff0c;常用于单选、验证码二次校验弹窗等&#xff0c;GetX的…

Go语言设计与实现 -- singleflight

这个东西很重要&#xff0c;可以经常用在项目当中&#xff0c;所以我们单独拿出来进行讲解。 在使用它之前我们需要导包&#xff1a; go get golang.org/x/sync/singleflightgolang/sync/singleflight.Group 是 Go 语言扩展包中提供了另一种同步原语&#xff0c;它能够在一个服…

【NCC】之二:积分图加速均值计算

文章目录<center> 积分图 integral image1. 原理&#xff1a;2. 示例3. 计算区域均值4. 计算区域方差5. 积分图示例6. 计算积分图的源码7. 用积分图加速NCC参考积分图 integral image1. 原理&#xff1a; Summed Area Table是一种数据结构和算法&#xff0c;用于快速有效…

【math】大规模对称正定稀疏线性方程组的求解与代数多重网格

大规模对称正定稀疏线性方程组的求解与代数多重网格代数多重网格问题定义迭代法的优畧几何多重网格代数多重网格代数多重网格 你好&#xff01;代数多重网格一个很有意思的话题。 问题定义 很多问题都可以抽象为求解下列优化的问题&#xff1a; 对于图像问题&#xff0c;一…

安全、稳定的工业蜂窝路由器具有怎样的特性?

一、前言 传统路由器通过电缆或光纤线路访问Internet&#xff0c;在很多场景或区域下存在着很大的局限性&#xff0c;例如在行驶的火车上&#xff0c;在固定电话稀缺或没有其他接入方式的地区都是十分受限的。随着科技的发展&#xff0c;很多行业应用都需要具有更强大功能的路…

3 高级面向对象编程实例

高级OOP 1 继承 是一种基于已有类创建新类的机制 class 子类名 extends 父类{类体; }public class Extends_v1 {public static void main(String[] args) {Extendsclass01 ex new Extendsclass01();} } class Baseclass01{public int num;public void setNum(int n){num n…

java之线程死锁和ThreadLocal的使用

线程死锁&#xff1a; 线程死锁是指两个或者两个以上的线程在执行过程中&#xff0c;由于竞争资源或者彼此通信而造成的一种阻塞的现象,若无外力的作用,它们都将无法继续执行下去。 此时应用系统就处于了死锁状态&#xff0c;这些永远在互相等待的线程称为死锁线程。 如下图…

文本中按规则分组区段随机抽样

【问题】 This is a bit complex, and I greatly appreciate any help! I am trying to randomly sample rows from a .csv file. Essentially, I want a resulting file of unique locations (Locations are specified by Easting and Northing columns of the data file, be…