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

缓冲区

 

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”变量来获取具体的错误信息。


 

 

 

 

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值