linux应用:errno、perror、open、fopen
errno
errno 是一个全局变量,定义在 头文件中。当系统调用(如 open、read、write 等)或库函数执行失败时,会将一个错误码赋值给 errno。不同的错误码代表不同的错误类型,通过检查 errno 的值,可以判断具体发生了什么错误。
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>int main() {// 尝试打开一个不存在的文件int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {// 检查 errno 的值if (errno == ENOENT) {std::cerr << "The file does not exist. errno value: " << errno << std::endl;} else {std::cerr << "An unknown error occurred. errno value: " << errno << std::endl;}}return 0;
}
代码中使用 open 函数尝试打开一个不存在的文件。由于文件不存在,open 函数会执行失败并返回 -1。
当 open 函数返回 -1 时,通过检查 errno 的值来判断具体的错误类型。ENOENT 是一个预定义的错误码,表示文件或目录不存在。如果 errno 等于 ENOENT,则输出相应的错误信息。
perror
perror 是一个函数,定义在 头文件中。它会根据 errno 的当前值,输出一条对应的错误信息。perror 函数接受一个字符串作为参数,该字符串会被作为错误信息的前缀输出。
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio>int main() {// 尝试打开一个不存在的文件int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {// 使用 perror 输出错误信息perror("Failed to open the file");}return 0;
}
同样,代码中使用 open 函数尝试打开一个不存在的文件,由于文件不存在,open 函数执行失败并返回 -1。
当 open 函数返回 -1 时,调用 perror 函数并传入一个字符串 “Failed to open the file” 作为前缀。perror 函数会根据 errno 的当前值,输出一条包含前缀和具体错误信息的错误消息,例如:Failed to open the file: No such file or directory。
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>int main() {// 尝试打开一个不存在的文件int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {// 先使用 perror 输出错误信息perror("Open file error");// 再根据 errno 进行具体处理switch (errno) {case ENOENT:std::cerr << "The file does not exist." << std::endl;break;case EACCES:std::cerr << "Permission denied." << std::endl;break;default:std::cerr << "An unknown error occurred." << std::endl;break;}}return 0;
}
errno 和 perror 的使用。当 open 函数执行失败时,首先调用 perror 函数输出一条包含前缀和通用错误信息的错误消息。
然后,通过 switch 语句根据 errno 的具体值进行更细致的错误处理,输出不同的错误提示信息,方便开发者进行调试和问题定位。
文件IO和标准IO的区别
文件 I/O(File I/O)和标准 I/O(Standard I/O)是在编程中进行输入输出操作的两种不同方式,它们在多个方面存在区别,下面为你详细介绍:
1. 接口层面
文件 I/O
系统调用接口:文件 I/O 使用的是操作系统提供的系统调用函数,这些函数直接与操作系统内核进行交互。在 Linux 系统中,常见的文件 I/O 函数有 open、read、write、lseek 和 close 等。这些函数是操作系统内核的一部分,不同的操作系统可能会有不同的实现细节。
低级别操作:由于直接与内核交互,文件 I/O 提供了更底层的操作方式,允许程序员对文件的读写位置、读写权限等进行更精确的控制。
标准 I/O
库函数接口:标准 I/O 是 C 标准库提供的一组函数,如 fopen、fread、fwrite、fseek 和 fclose 等。这些函数是在文件 I/O 的基础上进行了封装,提供了更高级、更方便的接口。
跨平台性:标准 I/O 函数是 C 标准库的一部分,具有很好的跨平台性,在不同的操作系统上都能保持一致的使用方式。
2. 缓冲机制
文件 I/O
无缓冲或自定义缓冲:文件 I/O 默认情况下是无缓冲的,即每次调用 read 或 write 函数都会直接进行系统调用,与磁盘进行数据交互。不过,程序员可以自己实现缓冲机制来提高效率,例如使用 read 函数一次性读取较大的数据块到缓冲区,然后再进行处理。
适合实时性要求高的场景:由于无缓冲,文件 I/O 能够立即将数据写入磁盘或从磁盘读取数据,适合对实时性要求较高的场景,如日志记录、设备驱动等。
标准 I/O
自动缓冲:标准 I/O 提供了自动缓冲机制,分为全缓冲、行缓冲和无缓冲三种类型。全缓冲是指当缓冲区满时才进行实际的 I/O 操作;行缓冲是指当遇到换行符时才进行 I/O 操作;无缓冲则是每次操作都立即进行 I/O。
提高效率:自动缓冲机制减少了系统调用的次数,提高了 I/O 操作的效率。例如,在向文件写入大量数据时,标准 I/O 会先将数据写入缓冲区,当缓冲区满时再一次性将数据写入磁盘,减少了磁盘 I/O 的次数。
3. 文件定位
文件 I/O
使用 lseek 函数:文件 I/O 通过 lseek 函数来定位文件的读写位置。lseek 函数可以将文件指针移动到指定的偏移量处,支持相对当前位置、文件开头和文件末尾三种偏移方式。
灵活性高:lseek 函数提供了较高的灵活性,程序员可以根据需要精确地控制文件指针的位置,实现随机读写操作。
标准 I/O
使用 fseek 函数:标准 I/O 使用 fseek 函数来定位文件的读写位置。fseek 函数的功能与 lseek 类似,但它是基于标准 I/O 流的,使用起来更加方便。
与缓冲机制结合:由于标准 I/O 有缓冲机制,fseek 函数在移动文件指针时会处理缓冲区的内容,确保数据的一致性。
4. 错误处理
文件 I/O
使用 errno:文件 I/O 函数在执行失败时会设置全局变量 errno,通过检查 errno 的值可以判断具体的错误类型。同时,还可以使用 perror 函数输出更详细的错误信息。
底层错误信息:errno 提供的错误信息比较底层,与操作系统的具体实现相关,对于一些复杂的错误,需要对操作系统有一定的了解才能准确判断。
标准 I/O
返回值和 ferror 函数:标准 I/O 函数通过返回值来表示操作是否成功,例如 fread 和 fwrite 函数返回实际读写的元素个数,如果返回值与预期不符,则表示操作失败。此外,还可以使用 ferror 函数检查流是否发生错误。
高级错误处理:标准 I/O 提供的错误处理方式相对更高级,更易于理解和使用,适合初学者。
5. 适用场景
文件 I/O
系统编程:在进行系统编程、设备驱动开发等需要直接与操作系统内核交互的场景中,文件 I/O 是首选。例如,开发一个磁盘文件系统的工具,需要精确控制文件的读写和定位,使用文件 I/O 可以更好地满足需求。
实时性要求高的场景:对于实时性要求较高的应用,如日志记录、网络编程等,文件 I/O 的无缓冲特性可以确保数据及时写入磁盘或发送到网络。
标准 I/O
通用文件处理:在一般的文件处理场景中,如文本文件的读写、数据的存储和读取等,标准 I/O 的自动缓冲机制和高级接口可以提高开发效率,减少代码复杂度。
跨平台开发:由于标准 I/O 具有良好的跨平台性,在需要编写跨操作系统的程序时,使用标准 I/O 可以确保代码的可移植性。
示例代码对比
文件 I/O 示例
#include <iostream>
#include <fcntl.h>
#include <unistd.h>int main() {const char* filename = "test.txt";const char* data = "Hello, File I/O!";// 打开文件int fd = open(filename, O_CREAT | O_WRONLY, 0666);if (fd == -1) {std::cerr << "Failed to open the file." << std::endl;return 1;}// 写入数据ssize_t bytesWritten = write(fd, data, sizeof(data));if (bytesWritten == -1) {std::cerr << "Failed to write to the file." << std::endl;close(fd);return 1;}// 关闭文件close(fd);return 0;
}
标准 I/O 示例
#include <iostream>
#include <cstdio>int main() {const char* filename = "test.txt";const char* data = "Hello, Standard I/O!";// 打开文件FILE* file = fopen(filename, "w");if (file == nullptr) {std::cerr << "Failed to open the file." << std::endl;return 1;}// 写入数据size_t bytesWritten = fwrite(data, sizeof(char), sizeof(data), file);if (bytesWritten != sizeof(data)) {std::cerr << "Failed to write to the file." << std::endl;fclose(file);return 1;}// 关闭文件fclose(file);return 0;
}
相关文章:
linux应用:errno、perror、open、fopen
errno errno 是一个全局变量,定义在 头文件中。当系统调用(如 open、read、write 等)或库函数执行失败时,会将一个错误码赋值给 errno。不同的错误码代表不同的错误类型,通过检查 errno 的值,可以判断具体…...
物联网中的气象监测设备具备顶级功能
物联网中的气象监测设备具备顶级功能时,通常集成GPS、数据上报和预警系统,以确保精准监测和及时响应。以下是这些功能的详细说明: 1. GPS定位 精准定位:GPS模块提供设备的精确地理位置,确保数据与具体位置关联&#…...
15-YOLOV8OBB损失函数详解
一、YOLO OBB支持的OBB 在Ultralytics YOLO 模型中,OBB 由YOLO OBB 格式中的四个角点表示。这样可以更准确地检测到物体,因为边界框可以旋转以更好地适应物体。其坐标在 0 和 1 之间归一化: class_index x1 y1 x2 y2 x3 y3 x4 y4 YOLO 在内部处理损失和输出是xywhr 格式,x…...
WHAT - 前端异步事件流处理场景梳理
目录 一、典型场景二、解决方案与技术选型1. 基础异步控制2. 状态管理方案3. 复杂任务调度4. 任务取消机制5. 微任务队列优化 三、最佳实践建议四、工具链推荐 前端异步任务流处理是现代Web开发中常见的需求,尤其在复杂业务逻辑、高交互性应用中不可或缺。以下是常见…...
计算机网络软考
1.物理层 1.两个主机之间发送数据的过程 自上而下的封装数据,自下而上的解封装数据,实现数据的传输 2.数据、信号、码元 码元就是数字通信里用来表示信息的基本信号单元。比如在二进制中,用高电平代表 “1”、低电平代表 “0”,…...
安防监控/视频集中存储EasyCVR视频汇聚平台如何配置AI智能分析平台的接入?
EasyCVR安防视频监控平台不仅支持AI边缘计算智能硬件设备的接入,还能快速集成AI智能分析平台,接收来自智能分析平台或设备的AI告警信息,如烟火检测、周界入侵检测、危险区域闯入检测、安全帽/反光衣佩戴检测等。 本文将详细介绍如何在EasyCVR…...
做小程序开发的安全防护全方案
小程序开发安全防护方案 为了确保小程序在开发过程中的安全性,以下是一个全面的防护方案: 1. 需求分析与规划 功能模块分析:明确小程序的功能模块,识别高风险区域如用户登录和支付功能。数据分类分级:将数据分为敏感…...
在Spring Boot项目中导出复杂对象到Excel文件
在Spring Boot项目中导出复杂对象到Excel文件,可以利用Hutool或EasyExcel等库来简化操作。这里我们将详细介绍如何使用Hutool和EasyExcel两种方式来实现这一功能。 使用Hutool导出复杂对象到Excel 首先确保你的pom.xml中添加了Hutool的依赖: <depe…...
从JDBC到数据库连接池:构建高性能Java应用的基石(中篇)
推荐关联阅读:JDBC核心技术解析:从基础连接到ORM演进之路(上) 一、JDBC的困境与连接池的救赎 1.1 传统JDBC的致命缺陷 在Java应用与数据库交互的原始模式中,开发者通过DriverManager.getConnection()获取数据库连接…...
JavaWeb后端基础(6)
主键返回 例子: /** * 新增员工数据 */ Options(useGeneratedKeys true, keyProperty "id") Insert("insert into emp(username, name, gender, phone, job, salary, image, entry_date, dept_id, create_time, update_time) " "value…...
nio多线程版本
多线程多路复用 多线程NIO,,就是多个线程,每个线程上都有一个Selector,,,比如说一个系统中一个线程用来接收请求,,剩余的线程用来读写数据,,每个线程独立干自…...
Electron、Tauri及其它跨平台方案终极对比
Electron、Tauri及跨平台方案终极对比(2025版) 一、核心框架深度解析 1.1 Electron:Web技术的桌面霸主 技术架构 基于Chromium(浏览器内核) Node.js(后端运行时)的双进程架构,支持…...
蓝桥杯试题:二分查找
一、问题描述 给定 n 个数形成的一个序列 a,现定义如果一个连续子序列包含序列 a 中所有不同元素,则该连续子序列便为蓝桥序列,现在问你,该蓝桥序列长度最短为多少? 例如 1 2 2 2 3 2 2 1,包含 3 个不同的…...
MongoDB Chunks核心概念与机制
1. 基础定义 Chunk(块):MongoDB分片集群中数据的逻辑存储单元,由一组连续的片键(Shard Key)范围数据组成,默认大小为64MB(可调整范围为1-1024MB)。数据分…...
决策树(Decision Tree):机器学习中的经典算法
1. 什么是决策树? 决策树(Decision Tree)是一种基于树形结构的机器学习算法,适用于分类和回归任务。其核心思想是通过一系列的规则判断,将数据集不断划分,最终形成一棵树状结构,从而实现预测目…...
高频 SQL 50 题(基础版)_1084. 销售分析 III
高频 SQL 50 题(基础版)_1084. 销售分析 III 思路 思路 select t1.product_id,product_name from Product as t1 join(select product_id,min(sale_date) as min_date,max(sale_date) as max_datefrom Salesgroup by (product_id)having 2019-01-01<…...
Python-selenium启动edge打开百度
文章目录 专栏导读1、背景2、代码总结 专栏导读 🔥🔥本文已收录于《Python基础篇爬虫》 🉑🉑本专栏专门针对于有爬虫基础准备的一套基础教学,轻松掌握Python爬虫,欢迎各位同学订阅,专栏订阅地址…...
网络安全需要掌握哪些技能?
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 在这个高度依赖于网络的时代,网络安全已经成为我们工作和生活中不可或缺的一部分,更是0基础转行IT的首选,可谓是前景好、需求大…...
自动扶梯人员摔倒掉落识别检测数据集VOC+YOLO格式5375张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):5375 标注数量(xml文件个数):5375 标注数量(txt文件个数):5375 …...
中国棒球国家队征战世界棒球经典赛·棒球1号位
中国棒球国家队在世界棒球经典赛预选赛中的表现备受瞩目。以下是对中国棒球国家队参与此次预选赛的详细介绍: 一、预选赛背景与分组 • 赛事背景:世界棒球经典赛(World Baseball Classic,简称WBC)是由世界棒垒联授权&…...
Linux内核同步机制:从原子操作到RCU的实战指南
1. 项目概述:为什么我们需要同步机制?想象一下,你正在一个繁忙的十字路口指挥交通。如果没有红绿灯和交通规则,车辆和行人随意穿行,结果必然是混乱、拥堵,甚至发生事故。在操作系统的核心——Linux内核中&a…...
告别轮询!用STM32CubeMX和DMA实现ADC多通道‘无感’采集与串口打印(附完整工程)
告别轮询!STM32CubeMX与DMA实现ADC多通道无感采集实战指南 在嵌入式开发中,数据采集系统的效率往往决定了整个应用的性能上限。传统轮询方式不仅消耗大量CPU资源,还会引入不可预测的延迟。想象一下,当你需要同时监测多个环境传感器…...
MH2103(兆讯恒达)兼容替代 GD32F103(兆易创新)
MH2103(兆讯恒达)VS GD32F103(兆易创新)参数对比 & Pin‑to‑Pin 兼容性结论先给核心结论:同封装下,MH2103 与 GD32F103 引脚完全兼容、寄存器高度兼容,可直接 Pin‑to‑Pin 替换࿱…...
从Wi-Fi 6到5G:深入浅出聊聊MIMO中的CSI反馈那些事儿(PMI/RI/CQI详解)
从Wi-Fi 6到5G:深入浅出聊聊MIMO中的CSI反馈那些事儿(PMI/RI/CQI详解) 现代无线通信系统正经历着从Wi-Fi 6到5G的跨越式发展,而多天线技术(MIMO)作为提升频谱效率的核心手段,其性能很大程度上依赖于准确的信道状态信息…...
Obsidian 完整使用手册 — 目录与索引
Obsidian 完整使用手册 — 目录与索引 一份从入门到精通的 Obsidian 全面指南,涵盖基础操作、核心功能、插件生态、同步备份与进阶技巧。 手册列表 编号手册名称内容概要01基础入门篇软件安装、界面布局、库管理、核心设置02Markdown 语法篇格式化语法、扩展语法、…...
别再被CAPL路径搞懵了!getAbsFilePath、setFilePath这几个函数到底怎么用?
CAPL文件路径操作全解析:从函数原理到实战避坑指南 在CANoe自动化测试开发中,文件路径操作堪称最基础却又最容易出错的环节之一。许多工程师都经历过这样的场景:精心编写的CAPL脚本在本地测试一切正常,换到同事电脑上却频频报错&a…...
别再只用Telnet了!手把手教你给思科路由器配置SSH远程登录(附Packet Tracer验证)
从Telnet到SSH:思科路由器安全远程管理实战指南 每次看到运维同事用Telnet登录路由器时,我都忍不住想提醒——这就像在咖啡馆用明信片写密码。作为从业十年的网络工程师,我见过太多因Telnet导致的安全事故。本文将用Packet Tracer带您完成从T…...
Arm Cortex-A715向量计算优化指南:ASIMD/SVE指令深度解析
1. Cortex-A715向量计算引擎深度解析在移动计算和嵌入式领域,Arm Cortex-A715作为最新一代高性能CPU核心,其向量计算能力直接决定了AI推理、图像处理等关键场景的性能表现。本文将深入剖析A715的ASIMD/SVE指令集架构设计,从底层硬件机制到实际…...
ChatGPT对技术从业者的影响:机遇与挑战
在人工智能技术飞速发展的当下,ChatGPT这类大语言模型的横空出世,无疑在科技领域投下了一颗重磅炸弹。对于软件测试从业者而言,这既是一场前所未有的机遇,也是一次严峻的挑战。它不仅重塑了测试工作的模式与效率,更对从…...
终极指南:如何解锁光猫全部性能?RTL960x开源方案深度解析
终极指南:如何解锁光猫全部性能?RTL960x开源方案深度解析 【免费下载链接】RTL960x Hacking & Reverse Engineering RTL960x-based xPON ONTs to suit your OLT 项目地址: https://gitcode.com/gh_mirrors/rt/RTL960x RTL960x开源光猫固件是基…...
