lv4 嵌入式开发-7 文件IO(概念、打开、关闭、读、写)

news2024/11/28 19:03:25

目录

1 文件I/O 介绍

2 文件I/O – 文件描述符fd(File Descriptor)

3 文件I/O – open

4 文件I/O – close

5 文件I/O – read

 6 文件I/O – write

7 文件IO – lseek

8 标准I/O – 思考和练习


掌握文件描述符的含义

1 文件I/O 介绍

什么是文件I/O?

posix(可移植操作系统接口)定义的一组函数

不提供缓冲机制,每次读写操作都引起系统调用

核心概念是文件描述符

访问各种类型文件

Linux下, 标准IO基于文件IO实现,文件IO与操作系统有关,每个操作系统不一样

建议操作字符串还是使用标准IO,两者不能混用

2 文件I/O – 文件描述符fd(File Descriptor)

  • 每个打开的文件都对应一个文件描述符。
  • 文件描述符是一个非负整数。Linux为程序中每个打开的文件分配一个文件描述符。
  • 文件描述符从0开始分配,依次递增。
  • 文件IO操作通过文件描述符来完成。
  • 0, 1, 2 的含义?

应用程序运行时自动打开,0标准输入流 1标准输入流 2标准错误流

文件I/O – open

 open函数用来创建或打开一个文件:

 #include <fcntl.h>
 int open(const char *pathname, int flags);  //文件存在,传入2个参数
 int open(const char *pathname, int flags, mode_t mode);  //文件存在,需要3个参数创建
  • 成功时返回文件描述符;出错时返回EOF
  • 打开文件时使用两个参数
  • 创建文件时第三个参数指定新文件的权限,(只有在建立新文件时有效)此外真正建文件时的权限会受到umask 值影响,实际权限是mode-umaks
  • 可以打开设备文件但是不能创建设备文件(创建设备mknode 驱动部分会讲)

man 2 open 查看文档 

O_NOCTTY 在串口用的时候比较多,在某些情况下,我们希望打开终端设备时不将其作为进程的控制终端。这时可以使用 O_NOCTTY 标记来避免这种情况发生。

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权限

普通用户                                                666 - 0002 =664

root用户                                                 666 - 0022 =644

对于标准IO是没有权限参数的,只有文件IO有。

示例

以只写方式打开文件1.txt。如果文件不存在则创建,如果文件存在则清空:

int  fd;

if ((fd  = open(“1.txt”, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
    perror(“open”);
    return  -1;
}
……

以读写方式打开文件1.txt。如果文件不存在则创建,如果文件存在则报错:

int  fd;

if ((fd  = open(“1.txt”, O_RDWR|O_CREAT|O_EXCL, 0666)) < 0) {
    if (errno == EEXIST) { 
       perror(“exist error”);
    } else {
       perror(“other error”);
    }
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char *argv[]){
    int fd;
    int ret;
     
    fd = open("test.txt",O_WRONLY|O_CREAT|O_TRUNC, 0666);
    if(fd<0){
       printf("open file err\n");
       return 0;

    }
    printf("sucess,fd=%d\n",fd);

    ret=  close(fd);
    if(ret<0){
        printf("close failed\n");
    }

    ret=close(fd);
    printf("ret=%d\n",ret);
}

4 文件I/O – close

close函数用来关闭一个打开的文件:

#include  <unistd.h>
int  close(int fd);
  • 成功时返回0;
  • 出错时返回EOF 程序结束时自动关闭所有打开的文件
  • 文件关闭后,文件描述符不再代表文件

5 文件I/O – read

read函数用来从文件中读取数据:

#include  <unistd.h>
ssize_t  read(int fd, void *buf, size_t count);
  • 成功时返回实际读取的字节数;出错时返回EOF
  • 读到文件末尾时返回0
  • buf是接收数据的缓冲区
  • count不应超过buf大小

示例

从指定的文件(文本文件)中读取内容并统计大小

int  main(int argc, char *argv[]) {
{
    int  fd, n, total = 0;
    char  buf[64];
    if (argc < 2) {
       printf(“Usage : %s <file>\n”, argv[0]);  return -1;
    }
    if ((fd  = open(argv[1], O_RDONLY)) < 0) {
           perror(“open”);  return -1;
    }
    while ((n = read(fd, buf, 64)) > 0) {
        total += n;
    }
    ……

 6 文件I/O – write

write函数用来向文件写入数据:

 #include  <unistd.h>
 ssize_t  write(int fd, void *buf, size_t count);
  • 成功时返回实际写入的字节数;出错时返回EOF
  • buf是发送数据的缓冲区
  • count不应超过buf大小 

示例

将键盘输入的内容写入文件,直到输入quit

    int  fd;
    char  buf[20];

    if ((fd  = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
           perror(“open”);  return -1;
    }
    while (fgets(buf, 20, stdin) != NULL) {
        if (strcmp(buf, “quit\n”) == 0) break;
        write(fd, buf, strlen(buf));
    }
    ……

7 文件IO – lseek

lseek函数用来定位文件:

 #include  <unistd.h>
 off_t  lseek(int fd, off_t offset, intt whence);

param whence:SEEK_SET头偏移 SEEK_CUR当前位置偏移  SEEK_END尾部偏移
  • 成功时返回当前的文件读写位置;出错时返回EOF
  • 参数offset和参数whence同fseek完全一样(可正、可负)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[]){

    int fd;
    int ret;
    char buf[32] = "hello world";
    char buf2[32]={0};
    fd = open("test.txt",O_RDWR | O_CREAT|O_APPEND, 0666);
    if(fd<0){
       printf("open file err\n");
       return 0;

    }
    printf("sucess,fd=%d\n",fd);

    ret=write(fd,buf,strlen(buf));  //注意写字符串不能用sizeof,用strlen
    if(ret<0){
       perror("write");
       goto END;
    }
    printf("write count=%d\n",ret);
    
    lseek(fd,0,SEEK_SET);
     
    ret = read(fd,buf2,32);
    if(ret<0){
        perror("read");
        goto END;
    }
    buf2[31]=0;  // '/0'可以避免超过32位有乱码出现的情况
    printf("read buf2=%s\n",buf2);

END:


   close(fd);


}

 注意:

写字符串不能用sizeof ,用strlen,不能使用标准函数的定位。如果没有定位,关闭再打开读取,会从首字符读取。

8 标准I/O – 思考和练习

利用文件IO实现文件的复制

文件名通过命令行参数指定

打开文件的方式?

如何判断读到源文件的末尾?

练习

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

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


int main(int argc,char *argv[])
{    
	int fd;
	time_t ticks;
	struct tm * curtime;
	int linecount = 0;
	char buf[256];
	int ret;

	fd = open("text.txt",O_RDWR | O_CREAT | O_APPEND, 0666);
	if(fd < 0)
	{
		printf("open file err\n");
		close(fd);
		return 1;
	}



	while(1)
	{

		ticks = time(&ticks);
		curtime = localtime(&ticks);
		//printf("cur=%d\n",(int)ticks);
		printf("%d,%4d-%2d-%2d %2d:%2d:%2d\n",linecount\
										 ,curtime->tm_year+1900\
										 ,curtime->tm_mon+1\
										 ,curtime->tm_mday\
										 ,curtime->tm_hour\
										 ,curtime->tm_min\
										 ,curtime->tm_sec);
		sprintf(buf,"%d,%4d-%2d-%2d %2d:%2d:%2d\n",linecount\
								         ,curtime->tm_year+1900\
										 ,curtime->tm_mon+1\
										 ,curtime->tm_mday\
										 ,curtime->tm_hour\
										 ,curtime->tm_min\
										 ,curtime->tm_sec);
		ret = write(fd, buf, strlen(buf));
		buf[255] = 0;
		if(ret < 0)
		{
			perror("write");
			goto END;
		}

		linecount++;
		sleep(1);
	}

END:	
	close(fd);
	return 0;
}

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

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

相关文章

php 实现stripe支付流程

1.申请账号获取密钥key 2.申请创建商品&#xff0c;创建价格&#xff0c;创建支付&#xff0c; //创建商品 public function create_product(){ $_key self::STRIPE_KEY;$stripe new \Stripe\StripeClient($_key);$arr $stripe->products->create([name > $good…

Arcgis多值提取至点所有波段数值一样

Arcgis多值提取至点所有波段数值一样 问题描述 进行多值提取多波段后的结果&#xff0c;所有波段数值都是一样的。 原因 操作流程问题&#xff0c;输入栅格只选择了一个栅格文件 解决方案 实际上&#xff0c;每个波段都会对应一个栅格文件&#xff0c;要把这些添加进去 这…

【网络编程】深入理解TCP协议二(连接管理机制、WAIT_TIME、滑动窗口、流量控制、拥塞控制)

TCP协议 1.连接管理机制2.再谈WAIT_TIME状态2.1理解WAIT_TIME状态2.2解决TIME_WAIT状态引起的bind失败的方法2.3监听套接字listen第二个参数介绍 3.滑动窗口3.1介绍3.2丢包情况分析 4.流量控制5.拥塞控制5.1介绍5.2慢启动 1.连接管理机制 正常情况下&#xff0c;TCP需要经过三…

淘宝/天猫获取商品销量详情 API 返回值说明

item_get_sales-获取商品销量详情 API测试工具 taobao.item_get_sales 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_…

SEO优化排名的技巧与注意点(百度SEO排名的五大注意点)

关键词排名是指在搜索引擎中&#xff0c;用户搜索相关关键词时&#xff0c;网站出现的顺序。SEO优化是提高网站排名的一种方法。优化关键词排名的目的是提高网站流量和知名度。但是要注意遵循百度SEO排名的规则。 下面介绍一下百度SEO排名的五大注意点和优化关键词的六种方式。…

Arcgis提取每个像元的多波段反射率值

Arcgis提取每个像元的多波段反射率值 数据预处理 数据预处理阶段需要对遥感图像进行编辑传感器参数、辐射定标、大气校正、正射校正&#xff0c;具体流程见该文章 裁剪研究区 对于ENVI处理得到的tiff影像&#xff0c;虽然是经过裁剪了&#xff0c;但是还存在黑色的背景值&a…

JDK、eclipse软件的安装

一、打开JDK安装包 二、复制路径 三、点击我的电脑&#xff0c;找到环境变量 四、新建环境 变量名&#xff1a;JAVA_HOME 变量值就是刚刚复制的路径 五、在path中建立新变量 双击path 打印以下文字 最后一直双击确定&#xff0c;安装环境完成。 六、双击eclipse 选择好安装…

Sentinel控制台配置 持久化到nacos

sentinel控制台&#xff0c;使用方便&#xff0c;功能强大。使用官方的jar包&#xff0c;配置不会持久化&#xff0c;sentinel重启后会导致&#xff0c;之前的规则全部丢失&#xff0c;下面一起改造源码实现规则数据的持久化 sentinel源码地址 &#xff08;github访问太慢&am…

React TypeScript 定义组件的各种方式

目录 举例说明1. 使用 class 定义2. 使用函数定义2.1 使用普通函数2.2 使用函数组件 举例说明 比如我们要定义一个计数器 Counter&#xff0c;它包含一个 label 和一个 button&#xff0c;计数器的初始值由外部传入&#xff0c;点击 button 计数加 1: 这虽然是个简单组件&…

第25章_瑞萨MCU零基础入门系列教程之看门狗定时器-WDT

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

iOS17正式版9月18日正式发布!怎么更新即将发布的iOS17正式版?

苹果在今天举办的“好奇心上头”发布会结束后&#xff0c;推送了iOS 17和iPadOS 17发布候选版本&#xff08;Release Candidate Version&#xff09;&#xff0c;同时宣布将于9月18日面向iPhone和iPad 用户&#xff0c;推送iOS17/iPadOS 17正式版更新。苹果表示iOS 17的设计理念…

C# Onnx Yolov8 Detect 物体检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System…

自动化办公更简单了:新版python-office,有哪些更新?

#职场经验谈# 大家好&#xff0c;这里是程序员晚枫&#xff0c;小破站/小红薯都叫这个名。 去年4月开源了一个Python自动化办公项目&#xff1a;python-office&#xff0c;GitHub和Gitee都能看到。1行代码实现复杂的自动化办公任务&#xff0c;帮助不懂代码的小白&#xff0c;…

处理SQLSyntaxErrorException异常:数据库表 ‘books‘ 不存在;

目录 背景介绍 我的问题中的解决方法 通用方法 背景介绍 今天遇见了这个问题&#xff0c;解决后发出来分享一下 Java应用程序中的SQLSyntaxErrorException&#xff1a;表 bookmanagement.books 不存在问题解决 解决MySQL错误&#xff1a;无法找到表 bookmanagement.books…

Java native 关键字

如你在看 JDK 的源代码的时候&#xff0c;大概率会看到很多方法使用了 native 关键字。 下面是 String 对象 JDK 中的源代码&#xff0c;就带有了一个 native 关键字。 native 是干什么用的 简单来说就是 Java 的 native 方法的实现不是用 Java 实现的&#xff0c;可能在其他…

2023最新AI创作商用ChatGPT源码分享+支持AI绘画

一、SparkAI智能创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文…

OPENCV--实现meanshift图像分割

Meanshift原理 效果图 API # -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/9/13 """ import cv2 import numpy as npimg = cv2.imread("F:\\learnOpenCV\\openCVLearning\\pictures\\Lena.jpg

计算机视觉的应用14-目标检测经典算法之YOLOv1-YOLOv5的模型架构与改进过程详解,便于记忆

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用14-目标检测经典算法之YOLOv1-YOLOv5的模型架构与改进过程详解&#xff0c;便于记忆。YOLO&#xff08;You Only Look Once&#xff09;是一种目标检测深度学习模型。想象一下&#xff0c;传统的目…

做机器视觉工程师,其实挺没意思的

3.康耐视VisionPro高级脚本系列教程-3.脚本编辑错误和运行错误调试方法&#xff0c;break和Contitinuee的差别_哔哩哔哩_bilibili 其实人生就是“有时有意思&#xff0c;有时没意思”。 心里有太多的不甘心&#xff0c;太多的苦水&#xff0c;是没法再吃学习的苦&#xff0c…

Linux系统编程多线程(C++)

目录 【1】引入如何看待地址空间和列表 【2】什么是线程 【3】线程的优点 【4】线程的缺点 【5】线程异常 【6】线程用途 【7】线程VS进程 【8】Linux线程控制 【8.1】查看轻量级线程指令 【8.2】线程创建 【8.2.1】POSIX线程库 【8.2.2】创建线程 【8.2.3】一次性…