当前位置: 首页 > news >正文

C/C++ 与 Java IO 机制对比解析和流与缓冲的概念介绍

系统级 IO

系统级 IO 是操作系统提供的输入输出接口 , 直接与硬件内核交互 .

不同操作系统的 系统级 IO 不同 .

数据传输的抽象管道 , 定义数据如何输入输出 , 有流才能传输数据 . 本质是 封装 系统级 IO 的高级抽象 , 拥有自己的统一接口 ( iostream , InputStream 等) .

为什么要将系统级 IO 抽象成流 ?
  1. 设备无关性 : 对于文件 , 网络数据 , 内存等数据 , 流能够提供统一的操作接口 .

  2. 跨平台兼容 : 流将不同操作系统的系统级 IO 封装起来 , 使操作兼容不同平台 .

  3. 优化 : 流拥有缓冲区 , 类型检查 , 错误处理等优化机制 .

缓冲区

缓冲区内存中的临时数据存储区域 , 用于优化流的性能 , 减少系统调用次数 , 匹配网络和硬件读取访问的不同速度 .

B题 我才是奶龙 : 给你一组R、G、B的字符,判断其中是否恰好只有R、G。

缓冲区认识最深刻的时候是上学期新生赛的 B 题 , 学校机房设备的 Dev-C++ 编译器没有调整缓冲模式 , 导致我在这题的输入输出浪费了很多时间 .

缓冲模式
缓冲模式触发刷新条件应用
全缓冲缓冲区满文件 IO
行缓冲遇到换行符或缓冲区满控制台 IO
无缓冲立即输出我才是奶龙

纵向介绍

C scanf & printf

基于 stdio 库函数封装操作系统的系统级 IO , 速度极快 . 默认使用 stdio 缓冲 : 终端行缓冲 ; 文件全缓冲 . 可通过 setvbuf 修改缓冲模式和自定义缓冲区大小 .

#include<stdio.h> // #include<cstdio>
int main(){
    int n;
    scanf("%d", &n);
    printf("%d", n);
    
    int a[n];
    for(int i = 0; i < n; ++i){
        scanf("%d", &arr[i]);
    }
    for(int i = 0; i < n; ++i){
        printf("%d", arr[i]);
    }
    
    return 0;
}
C++ cin & cout

基于流对象 iostram , 通过操作符重载实现类型安全 . 默认与 C 风格 stdio 同步共享缓冲区 , 解除同步避免额外计算可以提升输入输出操作效率 .

操作符重载 : 在自定义类或结构体中重新定义语言内置操作符的行为 .

#include<bits/stdc++.h> // #include<iostream>
int main(){
    int n;
    cin >> n;
    cout << n;
    
    int arr[n];
    for(int i = 0; i < n; ++i){
        cin >> n;
    }
    for(int temp : arr){
        cout << temp;
    }
    
    return 0;
}
Java Scanner

基于 InputStream , 通过正则表达式分隔解析输入 . 多次小规模读取的效率较低 . 无法直接修改缓冲区大小 .

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.print(n);
        
        int[] arr = new int[n]; // int arr[n];无效
        for(int i = 0; i < n; ++i){
            arr[i] = scanner.nextInt();
        }
        for(int temp : arr){
            System.out.print(temp);
        }
        
        scanner.close();
    }
}
Java 格式化输出

基于 Formatter 的装饰器流 , 语法和 C 语言的 printf 类似 , 拥有类型安全 . 提供格式说明符对齐输出结构 .

装饰器模式 : 允许动态地向对象添加新的功能而无需修改原有类的代码 , 以组合代替继承的方式扩展对象行为 .

import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.printf("%d", n);
        
        String temp = String.format("%d", n); // 支持代码复用
        
        scanner.close();
    }
}
Java BufferedReader 类输入

基于 Reader , 使用缓冲优化减少系统调用次数 , 无类型安全 , 需要手动解析数据类型 . 可以直接在析构函数中直接指定缓冲区大小 .

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(bufferedReader.readLine());
        
        String[] input = br.readLine().split(" ");
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(input[i]);
        }
        
        bufferedReader.close();
    }
}

横向对比

\printf/scanfcin/coutScannerJava格式化输出BufferedReader
性能极高 直接调用一般 需要关闭同步极低 正则匹配成本高较低 解析格式符成本高较高 批量读取 缓冲优化
类型安全 易出现未定义行为编译时推导类型运行时检查格式化字符串与参数强匹 手动解析字符串的具体类型
缓冲管理setvbuf 修改缓冲区大小和缓冲模式可自定义缓冲区 默认共享无 依赖底层流缓冲Scanner不可更改缓冲模式 默认 8196 Kb 缓冲 可调整大小

补充

底层流 是直接与数据源交互的原始数据通道 .

ScannerJava 格式化输出 依赖底层流缓冲 , 没有独立的缓冲管理能力 .

// 底层流是System.in 标准输入流 无缓冲
Scanner scanner1 = new Scanner(System.in);

// 底层流是FileInputStream 字节流 无缓冲
FileInputStream fis = new FileInputStream("data.txt");
Scanner scanner2 = new Scanner(fis);

// 底层流是BufferedReader 字符流 已缓冲
BufferedReader br = new BufferedReader(new FileReader("data.txt"));
Scanner scanner3 = new Scanner(br);

相关文章:

  • [GESP202312 五级] 平均分配
  • C语言今天开始了学习
  • 【python读取并显示遥感影像】
  • win日志
  • 仿真每日一练 | ABAQUS子程序DLOAD
  • 复杂物快速定性定量:液相色谱质谱联用仪
  • 7.第二阶段x64游戏实战-string类
  • 【MySQL基础】左右连接实战:掌握数据关联的完整视图
  • LabVIEW 中 JSON 数据与簇的转换
  • Java实战报错 tcp
  • 深入理解深度学习模型的训练与评估模式:从基础组件到实战应用
  • 【WRF理论第十七期】单向/双向嵌套机制(含namelist.input详细介绍)
  • The 2024 CCPC National Invitational Contest (Changchun),第17届吉林省赛 C
  • STM32 HAL库之EXTI示例代码
  • 线程池(一):线程基础知识全面解析
  • 独立部署及使用Ceph RBD块存储
  • 学习OpenCV C++版
  • 卡尔曼滤波器的工作原理
  • 嵌入式系统中如何构建事件响应架构
  • Droris(强制)删除某一个分区数据
  • 济南电商网站开发/广州seo培训
  • 网站建设是否包含等保/google关键词分析工具
  • 泰州网站建设制作工作室/福州短视频seo获客
  • 网站的做用/网上推广产品怎么做
  • 网站建设相关知识/目前最好的引流推广方法
  • 大连网站推广/兰州搜索引擎优化