首页 > 系统相关 >重头开始嵌入式第十九天(Linux系统编程 文件IO)

重头开始嵌入式第十九天(Linux系统编程 文件IO)

时间:2024-08-13 18:24:17浏览次数:10  
标签:fp 文件 函数 int 缓冲 嵌入式 fd IO Linux

缓冲区

 

1.行缓冲

行缓冲,1k, terminal,主要用于人机交互stdout
缓存区满或者遇到\n刷新 1024
行缓存多是关于终端的一些操作
1.遇到\n刷新
2.缓存区满刷新
3.程序结束刷新
4.fflush刷新  fflush(stdout);

2.全缓冲


全缓冲,4k,主要用于文件的读写
缓存区满刷新缓存区 4096
对普通文件进行标准IO操作,建立
的缓存一般为全缓存
刷新条件:
1.缓存区满刷新
2.程序结束刷新
3.fflush来刷新  fflush(fp);

3.无缓冲


无缓冲,0k  主要用于出错处理信息的输出 stderr 
不对数据缓存直接刷新
printf();==>>stdout 
fprintf(strerr,"fopen error %s",filename);
界面交互 出错处理
使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。
缓冲区的大小是可以设置

在 C 语言中,可以通过以下方式手动控制缓冲:

 

1. 使用  fflush  函数: fflush  函数用于强制刷新输出缓冲区,将缓冲区中的内容立即输出。例如: fflush(stdout);  这将刷新标准输出缓冲区。

2. 设置缓冲模式:可以使用  setvbuf  函数来设置缓冲区的类型和大小。函数原型为: int setvbuf(FILE *stream, char *buffer, int mode, size_t size);  其中:

 

-  stream  是要设置缓冲的文件流指针。

-  buffer  是用户提供的缓冲区(如果为  NULL ,则由系统分配)。

-  mode  可以是  _IONBF (无缓冲)、 _IOLBF (行缓冲)、 _IOFBF (全缓冲)。

-  size  是缓冲区的大小(仅在全缓冲和行缓冲时有效)。

 

例如,要将  stdout  设置为无缓冲,可以这样写:

setvbuf(stdout, NULL, _IONBF, 0);

 

fseek

 

“fseek”是 C 语言标准库中的一个文件操作函数,用于在文件中移动文件指针的位置。
 
其函数原型为: int fseek(FILE *stream, long offset, int whence); 
 
参数解释:
 
-  stream :指向文件流的指针。
-  offset :要移动的字节数,可以是正数(向前移动)、负数(向后移动)或 0(保持当前位置)。
-  whence :指定起始位置,有以下几种取值:
-  SEEK_SET :文件开头。
-  SEEK_CUR :当前位置。
-  SEEK_END :文件末尾。
 
函数返回值:成功返回 0 ,失败返回非零值。
 
例如,如果要将文件指针移动到文件开头向前 10 个字节的位置,可以这样写:

FILE *fp;
if ((fp = fopen("example.txt", "r"))!= NULL) {
    if (fseek(fp, -10, SEEK_SET) == 0) {
        // 移动成功后的操作
    } else {
        // 移动失败的处理
    }
    fclose(fp);
}


 


 rewind

 

“rewind”也是 C 语言标准库中用于文件操作的函数。
 
其作用是将文件指针重新定位到文件的开头。
 
函数原型为: void rewind(FILE *stream); 
 
使用“rewind”函数会清除文件流的错误和 EOF 标记,并将文件指针重置到文件的起始位置。
 
例如:

FILE *fp;
if ((fp = fopen("example.txt", "r"))!= NULL) {
    // 进行一些文件操作
    rewind(fp);  // 将文件指针重置到开头
    // 后续基于开头位置的操作
    fclose(fp);
}


它相比于“fseek(fp, 0, SEEK_SET)”这种方式更加简洁直观,但功能是相同的,都是将文件指针移到文件开头。
 

 

ftell

 

“ftell”是 C 语言标准库中的一个函数,用于获取文件指针在文件中的当前位置。
 
函数原型为: long ftell(FILE *stream); 
 
它返回一个长整型值,表示文件指针相对于文件开头的偏移量(以字节为单位)。如果返回值为 -1L,表示获取位置信息时出现错误。
 
例如:

FILE *fp;
if ((fp = fopen("example.txt", "r"))!= NULL) {
    long position = ftell(fp);  // 获取当前位置
    // 进行一些操作
    fclose(fp);
}


 
文件io


操作系统为了方便用户使用系统功能而对外提供的一组系统函数。称之为 系统调用  其中有个  文件IO,一般都是对设备文件操作,当然也可以对普通文件进行操作。
是一个基于Linux内核的没有缓存的IO机制

特性:


.1 没有缓存区
.2 操作对象不在是流,而是文件描述符  FILE*    int 0-1023
.3文件描述符
很小的非负的整数 int   0-1023
内核每打开一个文件就会获得一个文件 描述符

  每个程序在启动的时候操作系统默认为其打开
  三个描述符与流对象匹配:
  0 ==>STDIN_FILENO === stdin
  1 ==>STDOUT_FILENO == stdout
  2 ==>STDERR_FILENO == stderr

在 Linux 中,标准 I/O 和文件 I/O 主要有以下区别:


 
1. 缓冲机制:标准 I/O 提供了缓冲机制,例如全缓冲、行缓冲和无缓冲。这意味着数据在满足一定条件(如缓冲区填满、遇到换行符等)时才会实际进行读写操作。而文件 I/O 通常是无缓冲或由用户自行控制缓冲。
2. 可移植性:标准 I/O 具有更好的可移植性,因为它的接口在不同的操作系统上通常是相似的。而文件 I/O 的某些细节在不同的系统中可能会有所不同。
3. 函数接口:标准 I/O 使用如  fprintf 、 fscanf  等函数,而文件 I/O 使用如  open 、 read 、 write 、 close  等函数。
4. 处理对象:标准 I/O 主要处理与标准输入、输出和标准错误相关的流。文件 I/O 可以处理各种文件,包括普通文件、设备文件等。
5. 效率:在某些情况下,文件 I/O 可能比标准 I/O 更高效,特别是在需要频繁进行小量数据读写时,因为标准 I/O 的缓冲机制可能会引入一些额外的开销。
 
 

相关函数

 

open

 

在 Linux 中, open  函数用于打开或创建文件。
 
 open  函数的原型通常如下:

#include <fcntl.h>

int open(const char *pathname, int flags, mode_t mode);

-  pathname :要打开文件的路径名。
-  flags :指定打开文件的方式,常用的标志包括:
-  O_RDONLY :以只读方式打开。
-  O_WRONLY :以只写方式打开。
-  O_RDWR :以读写方式打开。
-  O_CREAT :如果文件不存在则创建它。
-  O_TRUNC :如果文件存在且以可写方式打开,则清空文件内容。
- 这些标志可以通过逻辑或( | )组合使用。
-  mode :仅在创建新文件时使用,指定文件的权限。
 
 open  函数成功时返回一个文件描述符(一个非负整数),失败时返回  -1  ,并设置  errno  来指示错误原因。
 
例如,以读写方式打开一个已存在的文件:

int fd = open("example.txt", O_RDWR);
if (fd == -1) {
    perror("Error opening file");
    return -1;
}

又如,创建一个新文件并设置权限为所有者可读可写可执行,组和其他用户可读可执行:

int fd = open("new_file.txt", O_CREAT | O_WRONLY, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (fd == -1) {
    perror("Error creating file");
    return -1;
}

又比如:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
    int fd = open("1.txt",O_WRONLY| O_CREAT|O_TRUNC,0666);    
    if(-1 == fd)
    {
        fprintf(stderr,"open error\n");
        return 1;
    }
    printf("fd is %d\n",fd);
    return 0;
}

close

 

在 Linux 中, close  函数用于关闭一个已打开的文件描述符。

 close  函数的原型如下:

#include <unistd.h>

int close(int fd);

其中, fd  是要关闭的文件描述符。

当成功关闭文件时, close  函数返回 0;如果关闭失败,则返回 -1,并设置  errno  来指示错误原因。

及时关闭不再使用的文件描述符是良好的编程习惯,它可以释放相关的系统资源,并确保数据的正确写入和同步。

write

 

在 Linux 中, write  函数用于向一个已打开的文件描述符写入数据。
  write  函数的原型如下:

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);


参数说明:
 
-  fd :文件描述符,指定要写入数据的文件。
-  buf :指向要写入数据的缓冲区。
-  count :要写入的字节数。
 
 write  函数返回实际写入的字节数,如果发生错误则返回 -1,并设置  errno  来指示错误原因。
 
例如:

char data[] = "Hello, World!";
ssize_t bytesWritten = write(fd, data, sizeof(data));
if (bytesWritten == -1) {
    perror("Error writing to file");
    return -1;
}
 

又比如:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
    int fd = open("1.txt",O_WRONLY| O_CREAT|O_TRUNC,0666);    
    if(-1 == fd)
    {
        fprintf(stderr,"open error\n");
        return 1;
    }
    printf("fd is %d\n",fd);
    char buf[512]="hello";
    int ret = write(fd,buf,strlen(buf));
    if(-1 == ret)
    {
        fprintf(stderr,"write error\n");
        return 1;
    }

    close(fd);
    return 0;
}


lssek

 

“lseek”是在 Unix/Linux 系统编程中用于移动文件指针位置的函数。
 
它的函数原型通常为: off_t lseek(int fd, off_t offset, int whence) 
 
参数含义如下:
 
-  fd :文件描述符,标识要操作的文件。
-  offset :偏移量,表示要移动的字节数。
-  whence :指定移动的基准位置,常见的值有:
-  SEEK_SET :从文件开头开始偏移。
-  SEEK_CUR :从当前位置开始偏移。
-  SEEK_END :从文件末尾开始偏移。
 
通过“lseek”函数,可以灵活地在文件中定位读取或写入的位置,从而实现对文件的随机访问。

“lseek”函数的返回值为新的文件偏移量,如果返回值为 -1 则表示发生错误。可以通过“errno”变量来获取具体的错误信息。


 

 

 

 

标签:fp,文件,函数,int,缓冲,嵌入式,fd,IO,Linux
From: https://blog.csdn.net/qq_64792908/article/details/141156909

相关文章

  • 【WPF】【XAML】Exception: 无法找到名为“xx”的资源。资源名称区分大小写。
    <Grid.Resources>一定要放在使用之前,比如<ListBoxName="peopleListBox"Grid.Column="1"Grid.Row="2"ItemsSource="{BindingSource={StaticResourceExpenseDataSource},XPath=Person}"ItemTemplate="{StaticResour......
  • Linux:文件管理,目录管理,文件类型,链接类型
    1,文件管理用户(标识号:UID):一定资源的使用者,可以创建和管理文件以及访问其他用户文件。可以从属于多个群组。用户组(标识号:GID):由一定数量的对某些文件具有相同操作权限的用户组成的小组。可以拥有多个用户。root用户:超级管理员,可以为所欲为。为何要区分用户和用户组?答:一种功......
  • Linuxu-引导过程与服务控制
    系列文章目录`提示:仅用于个人学习,进行查漏补缺使用。1.Linux介绍、目录结构、文件基本属性、Shell2.Linux常用命令3.Linux文件管理4.Linux命令安装(rpm、install)5.Linux账号管理6.Linux文件/目录权限管理7.Linux磁盘管理/文件系统8.Linux逻辑卷管理LVM9.Li......
  • Paper Reading: AutoLearn - Automated Feature Generation and Selection
    目录研究动机文章贡献本文方法问题定义AutoLearn的设计原理预处理挖掘相关特征特征生成特征选择样例展示实验结果数据集和实验设置对比实验可扩展性分析优点和创新点PaperReading是从个人角度进行的一些总结分享,受到个人关注点的侧重和实力所限,可能有理解不到位的地方。具体的......
  • IOS UI自动化脚本
    1.安装rethinkdbhttps://rethinkdb.com/docs/install/osx/2.安装bunch包错修复setup.py里面的数据,去掉U3.imp包变成了importlib需要替换  importImp#moduleFile,pathName,desc=imp.find_module(moduleName,[os.path.dirname(modulePath)])#module=imp.load_m......
  • 使用Github Action来拉取docker镜像
    前提只需一个github账号即可注意:免费版Action每天能使用1小时,每个月33小时(基本上够用)国内网络访问github网速并不稳定,但是用来应急还是可以的拉取逻辑GitHubAction来拉取和打包镜像从github上下载压缩包上传到自己的服务器上解压加载镜像到自己的服务器上这种......
  • Cookie、localStorage 和 sessionStorage 的区别及应用实例
    在前端开发中,持久化数据存储是一个非常常见的需求。为了实现这一点,浏览器提供了多种方式,包括Cookie、localStorage和sessionStorage。这三者各有优劣,适用于不同的场景1.CookieCookie是浏览器存储少量数据的一种机制,通常由服务器生成并发送到客户端。每次客户端向同一域名发......
  • 搭建基于Grafana+JMeter+InfluxDB的性能监控与分析平台(Linux版)
    搭建基于Grafana+JMeter+InfluxDB的性能监控与分析平台(Linux版)在软件开发和运维领域,性能监控与分析是确保应用稳定性和用户体验的关键环节。随着应用规模的不断扩大和复杂度的增加,传统的性能测试工具和方法已难以满足需求。本文将详细介绍如何搭建一个基于Grafana、JMeter和Influ......
  • [JOISC2017] Cultivation
    link。不是,怎么四方跑得飞快啊?成最优解了?有人会卡吗?鉴定为剪枝太多导致的。一个出发点不太一样的思路。假设上下左右各被操作了\(U,D,L,R\)次。我们考虑一个点\((x,y)\)不被感染的条件是初始时\([x-D,x+U]\times[y-R,y+L]\)这个矩形内没有任何感染点。考虑扣出所有中间......
  • Linux高级编程(一)标准io:stdio.h
    标准io的概念1975DennisrIO库,C语言的标准,ANSIc IO即input outputI:键盘是标准输入设备====》默认输入就是指键盘 /dev/inputO:显示器是标准输出设备==》默认输出就是指显示器Linux操作系统当中IO都是对文件的操作C一部分,任何支持标准C的系统都可使用标准IO实......