linux篇【8】:基础IO—<前序>

目录

一.文件相关知识储备

二.c语言文件操作复习

1.基本写入

2.当前路径

chdir(“路径”):更改当前进程的工作路径

3.文件操作

(1)a: 追加写入,不断的往文件中新增内容->追加重定向!

(3)读取

4.回归理论

三.系统接口

1.open

 (1)宏标记位示例:

(2)打开曾经不存在的文件用int open(const char *pathname, int flags, mode_t mode); 

错误示例:

示例2:初始权限给666,结果却是-rw-rw-r--:因为有权限掩码

示例3:用umask() 系统接口设置权限掩码

2.close 关闭文件

3.write 写入文件

 write使用示例:

(1)O_TRUNC——将原文件内容置空的宏

(2)O_APPEND——追加内容

4.read

四.文件描述符

1.为什么文件描述符fd从3开始,0, 1, 2是什么?

系统接口和c语言接口对应关系:​编辑

(1)证明:0对应标准输入,1对应标准输出,2对应标准错误

(2)验证012和stdin,stdout,stderr的对应关系

结论:

2.文件描述符究竟是什么?——就是指针数组的数组下标

3.虚拟文件系统(VFS)

五.文件描述符应用特征

1.文件描述符的分配规则

2.重定向

(1)重定向原理 >

(2)dup2 重定向

(3)追加重定向:>>

 (4)输入重定向 <

六.缓冲区

1.缓冲区的本质:就是一段内存

2.缓冲区的意义

3.缓冲区在哪里

例1:

例2:如果在刷新之前,关闭了fd会有什么问题?

4.刷新策略的问题

缓冲区和fork引发的小问题:

5.fflush()函数:更新缓存区。

6.sync,syncfs和fsync函数

(1)sync

(2)syncfs 刷盘

(3)fsync

7.模拟实现一下自己封装C标准库——打开文件的模拟实现

第二个main测试:


一.文件相关知识储备

1.文件=文件内容+文件属性
文件属性也是数据->即便你创建一个空文件,也要占据磁盘空间

2.文件操作=文件内容的操作+文件属性的操作
有可能在操作文件的过程中,既改变内容,又改变属性

3. 所谓的“打开”文件,究竟在干什么?
答:将文件的属性或内容加载到内存中! ——冯诺依曼体系决定:CPU只能从内存中对数据做读写!

4.是不是所有的文件,都会处于被打开的状态?
——答:绝对不是!
没有被打开的文件,在哪里?——答:只在磁盘上静静的存储着!

5.对文件的宏观分类:
打开的文件(内存文件) 和 (未打开文件)磁盘文件

6.通常我们打开文件,访问文件,关闭文件,是谁在进行相关操作?——是进程在操作!
c语言接口fopen,fclose, fread, fwrite... -> 写出代码 -> 形成程序 -> 当我们的文件程序,运行起来的时候,才会执行对应的代码,然后才是真正的对文件进行相关的操作
                                        是进程在操作!!!

7.学习文件操作:就是学习——进程和打开文件的关系!        内存级

r+和w+都是既读又写,只是w+多了一个文件不存在就创建文件

二.c语言文件操作复习

1.基本写入

fprintf(fp, "%s: %d\n", msg, cnt++); 向fp中写入msg, cnt两个值、

#include<stdio.h>
#include<unistd.h>
int main()
{
  FILE *fp=fopen("log.txt","w");
  if(fp==NULL)
  {
    perror("fopen");
    return 1;
  }
  const char *msg="hello linux";
  int cnt=1;
  while(cnt<=5)
  {
    fprintf(fp,"%s:%d",msg,cnt++);
  }

  return 0;
}

36c287210d4449c8a947718f8ab232d4.png

2.当前路径

(当前路径)cwd——correct work director42c65a7151f64edeb40827dfad29f639.png

当前路径定义:当前进程所处的工作路径!

默认的进程工作路径是在它所处的路径下,不过这个路径是可以改的

chdir(“路径”):更改当前进程的工作路径

ls /proc/(pid) 查看文件进程;ls /proc/(pid) -al 查看文件进程详细信息;

#include <stdio.h>
#include <unistd.h>

//myfile filename
int main(int argc, char* argv[])
{
	//chdir("/home/whb"); // 更改当前进程的工作路径
	//1. 默认这个文件会在哪里形成呢?当前路径
	//2. r, w, r+, w+, a(?), a+
	//3. 关注一下文件清空的问题
	FILE *fp = fopen("log.txt", "w"/*?*/); //写入
	if (fp == NULL)
	{
		perror("fopen"); //?
		return 1;
	}

	printf("mypid: %d\n", getpid());

	while (1)
	{
		sleep(1);
	}

	const char* msg = "hello 104 ";
	int cnt = 1;
	while (cnt <= 5)
	{
		fprintf(fp, "%s: %d\n", msg, cnt++);
	}

	fclose(fp);
}

3.文件操作

7c332e295eb941c48df24c159207e8b6.png

(1)a: 追加写入,不断的往文件中新增内容->追加重定向!


(2)当我们以w方式打开文件,准备写入的时候,其实文件已经先被清空!w:有文件就清空再从头写;没文件,就创建从头写

80d4017b9b29411b9ab0ce54fbd44108.png

(3)读取

利用格式./myfile log.txt ,读取log.txt文件的内容:

fgets(buffer, sizeof(buffer), fp)        按行读取

把读取的内容放到buffer,fp流中一行读多少字节,从fp流读出数据;读取失败返回NULL,成功返回buffer

#include <stdio.h>
#include <unistd.h>

//myfile filename
int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("Usage: %s filename\n", argv[0]);
        return 1;
    }

    FILE *fp = fopen(argv[1], "r");
    if(fp == NULL)
    {
        perror("fopen"); //?
        return 1;
    }

    char buffer[64];
    while(fgets(buffer, sizeof(buffer), fp) != NULL)
    {
        printf("echo:%s", buffer);
    }
}

4ff7176feef746f789cb47b879cba363.png

4.回归理论

1.当我们向文件写入的时候,最终是不是向磁盘写入?——答:是

2.磁盘是硬件吗?——是硬件

3.只有谁有资格向硬件写入呢?——操作系统!

4.能绕开操作系统对文件直接写入吗?——不能,所有的上层访问文件的操作,都必须贯穿操作系统

5.操作系统是如何被上层使用的?——必须使用操作系统提供的相关系统调用!
封装了系统接口
1.如何理解printf
2.我们怎么从来没有见过?——因为所有的语言都对系统接口做了封装

为什么要封装?
1.直接使用原生系统接口,使用成本比较高!
2.语言不具备跨平台性!
封装是如何解决跨平台问题的呢?——穷举所有的底层接口+条件编译!
 

三.系统接口

接口介绍

1.open

int open(const char *pathname, int flags); 只能打开已有文件

int open(const char *pathname, int flags, mode_t mode);   打开曾经不存在的文件,可以初始化权限
——① pathname 文件名;

② flags 打开文件传递的选项:O_RDONLY 只读(read only), O_WRONLY 只写(write only),O_RDWR 读写(read write),O_APPEND 追加(append), O_CREAT 如果文件不存在就创建(creat)(这些都是宏,系统传递标记位,是用位图结构来进行传递的! 每一个宏标记,一般只需要有一个比特位是1,并且和其他宏对应的值,不能重叠)O_TRUNC 将原文件内容置空(truncate)

③ mode 初始权限

返回值:创建成功返回新的文件描述符fd,或者打开已有文件就返回已有文件的文件描述符;错误返回-1

[zsh@ecs-78471 ~]$ man 2 open

b1df5cbf3d00480f8410b27a54b40263.png

 (1)宏标记位示例:

跟上面的O_RDONLY等等一样,下面的这些也是宏,系统传递标记位,是用位图结构来进行传递的! 每一个宏标记,一般只需要有一个比特位是1,并且和其他宏对应的值,不能重叠

#include <stdio.h>

#define PRINT_A 0x1 //0000 0001
#define PRINT_B 0x2 //0000 0010
#define PRINT_C 0x4 //0000 0100
#define PRINT_D 0x8 //0000 1000
#define PRINT_DFL 0x0


//open
void Show(int flags)
{
    if(flags & PRINT_A) printf("hello A\n"); //如果flags是PRINT_A,就打印hello A
    if(flags & PRINT_B) printf("hello B\n"); //如果flags是PRINT_B,就打印hello B
    if(flags & PRINT_C) printf("hello C\n"); //如果flags是PRINT_C,就打印hello C
    if(flags & PRINT_D) printf("hello D\n"); //如果flags是PRINT_D,就打印hello D

    if(flags == PRINT_DFL) printf("hello Default\n");
             //如果flags是PRINT_DFL,就打印hello Default
}


int main()
{
    printf("PRINT_DFL:\n");
    Show(PRINT_DFL);

    printf("PRINT_A\n");
    Show(PRINT_A);

    printf("PRINT_B\n");
    Show(PRINT_B);

    printf("PRINT_A 和 PRINT_B\n");
    Show(PRINT_A | PRINT_B);

    printf("PRINT_C 和 PRINT_D\n");
    Show(PRINT_C | PRINT_D);

    printf("PRINT all:\n");
    Show(PRINT_A | PRINT_B | PRINT_C | PRINT_D);

    return 0;
}

a824abc0f48d4554b8022e5146e16263.png

可以得出结论:Show(PRINT_A | PRINT_B); 我们传入宏PRINT_A | PRINT_B时,则A和B都满足,下面同理,如果我们既需要只读,又需要文件不存在就创建,就传入O_RDONLY | O_CREAT

(2)打开曾经不存在的文件用int open(const char *pathname, int flags, mode_t mode); 

mode给初始权限, 不能用   int open(const char *pathname, int flags); 否则权限是乱码。  int open(const char *pathname, int flags); 只能打开已有文件

错误示例:

此时没有log.txt文件

0d79c4664d214f638ca825a940a8a431.png

示例2:初始权限给666,结果却是-rw-rw-r--:因为有权限掩码

umask=0002,就是希望把other的写权限屏蔽掉,本来是-rw-rw-rw-,屏蔽other的w后就是    :        -rw-rw-r--

18ab51ff12f443b5a85802bf78a4134b.png

示例3:用umask() 系统接口设置权限掩码

 umask(0)把权限掩码设成0

176bdf810e8a4375a0587eb3a8cfab01.png

2.close 关闭文件

[zsh@ecs-78471 ~]$ man 2 close

d794b2c9d5834a9fa824ee6b452c0b31.png

传入整形fd关闭文件

3.write 写入文件

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

fd:特定的文件描述符。buf:(缓冲区)字符串的起始地址。 count:(缓冲区)字符串的大小

返回值:写入成功返回实际写入的字节数,什么都没写返回0,写入失败返回-1 错误码被设置。

 man 2 write

703da19aa78041d69899f6efd41e9145.png

 write使用示例:

注意:此处size_t count传strlen(str),不传\0,\0在vim中没有对应的实际字符串,打印出来就是乱码

cc8c42fbb901493b9575fe7cc9c5d406.png

f6cddfd0df6244c68135d59a08f72e2b.png

(1)O_TRUNC——将原文件内容置空的宏

细节1:c在w方式打开文件的时候,会清空的!这里却是覆盖:(上次写入5次hello 104 后,重新写入1行“aaaaaa”时发现会覆盖)

 71eb4cea9382420ca35d87cec2c0cabb.png

解决方法:O_TRUNC:将原文件内容置空

1faa005bcfb4488abecae0cd1c5ffb09.png

fbdf6a401ea24a8aa63a2373dea35ad7.png

log.txt中显示 "aaaaaa"

(2)O_APPEND——追加内容

1604a3aae7dd4705b8bbc28414ea232a.png

4.read

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

—— ssize_t是有符号整数类型。——int fd:文件描述符。——void *buf:(缓冲区)字符串的起始地址。—— count:(缓冲区)字符串的大小

返回值:成功后,返回读取的字节数;0表示文件结束;信号出现错误返回-1。

管道中返回值=0的情况:读端一直在读,写端不写了,并且关闭了写端,读端会使 read的返回值 == 0,代表写端关闭

s == 0: 代表对方关闭,client 写端退出

390909c3e97b4b639538f8078ab0b6fa.png

例子:把log.txt文件的内容读到数组buffer中

 e26f20353d4546dc8f2de912923738ac.png

四.文件描述符

每个文件描述符都是一个内核中文件描述信息数组的下标

文件描述符fd:

fd<0:failed
fd>=0:success

当我们打开一堆文件时,发现他们的fd从3开始往后排:

359be474b2e24ed6a161b55b650cced1.png

引入以下问题:

1.为什么文件描述符fd从3开始,0, 1, 2是什么?

系统接口和c语言接口对应关系:
a91a3822b7bf49ac9093b0319cb08550.png

FILE* ->文件指针-> FILE是什么呢?
FILE:C库提供的结构体,它封装了多个成员,并且FILE内部,必定封装了fd!

(1)证明:0对应标准输入,1对应标准输出,2对应标准错误

① 0对应标准输入

404f9787dd0346ed9704b4c1cd16d3ae.png

② 1对应标准输出,2对应标准错误,

 350225e9ffd940eda5ac89807256ddf2.png

(2)验证012和stdin,stdout,stderr的对应关系

_fileno 就是结构体FILE内部封装的文件描述符

7eff04c6b83d4319b7e281c905307ccc.png

结论:

上层的c语言函数接口 fopen/ fclose/ fread/ fwrite... 底层封装的是系统接口open/close/ read/write;上层的c语言类型对应的结构体FILE底层封装的是系统文件描述符fd;c库函数调用的系统接口

c196e80ec90f4d39aa8ebed2c1514221.png

2.文件描述符究竟是什么?——就是指针数组的数组下标

每个文件描述符都是一个内核中文件描述信息数组的下标

进程:内存和文件的关系 ——> 被打开的文件是在内存里面的! !

一个进程可不可以打开多个文件?——:当然可以,所以在内核中,进程:打开的文件 = 1:n ——>    所以系统在运行中,有可能会存在大量的被打开的文件! ——>    OS要对这些被打开的文件进行管理——>操作系统如何管理这些被打开的文件呢? ?——:先描述,在组织

一个文件被打开,在内核中,要创建该被打开的文件的内核数据结构 就是:先描述
c70ab91bede14a50951b8993d506f25d.png

解释下图:

进程中存在一个结构体指针 struct files_struct* files,指向结构体 struct files_struct,结构体 struct files_struct内部存着一个指针数组(文件描述符表) struct file* fd_ array[ ],他的各个位置存着被打开的文件的地址,[0]指向的打开文件就是上面说的标准输入;[1]指向的打开文件就是标准输出;[2]指向的打开文件就是上面说的标准错误;文件描述符就是这里的指针数组的数组下标。

4a6649bcba1042cbab704ecb83f183e2.png

3.虚拟文件系统(VFS)

 接着解释上面的struct file如何实现调用硬件的,同时证明 Linux下一切皆文件!

 如何使用C语言,实现面向对象(类):

92327e0c822e449ca72b283e3dbf6ef7.png

 虚拟文件系统通过函数指针的方式将上层的操作系统层和底层的硬件驱动层进行逻辑解耦:

53efd64c3866431488ceba6a100c5407.png

五.文件描述符应用特征

1.文件描述符的分配规则

从头遍历数组fd_array[], 找到一个最小的,没有被使用的下标,分配给新的文件!

如果close(0),即关闭标准输入,发现分配给log.txt的文件描述符就是0;

a236c3b646ec4a80a7064624edf9d15b.png

如果close(2),即关闭标准错误,发现分配给log.txt的文件描述符就是2;

69544c07f62c46a9b22a83755750ce8d.png

但是如果close(1),即关闭标准输出,发现什么也不打印;因为printf->stdout->1->不再指向对应的显示器了,而是已经指向了log.txt的底层struct file对::

1016d286ceed4a96884f29db2ce36cf2.png

2.重定向

重定向概念:

每个文件描述符都是一个内核中文件描述信息数组的下标,每个文件描述符对应有一个文件的描述信息用于操作文件,而重定向就是在不改变所操作的文件描述符的情况下,通过改变描述符对应的文件描述信息进而实现改变所操作的文件

(1)重定向原理 >

0ee14cd3f38b4ac2ad7294d6dd71c921.png

重定向原理:stdout中有一个结构体FILE,他的fd天然就是1,结合上下图,当close(1)时相当于把指针数组的[1]置为空,int fd = open("log.txt",O_ WRONLY | O_ CREAT | O_TRUNC, 0666); 时遍历指针数组,因为[1]有空余,就把[1]指向myfile(log.txt)。当 fprintf (stdout, "打开文件成功,fd: %d\n", fd) ; 时,就把内容输入stdout存的文件描述符中,就是输入到[1]中,可是此时[1]指向myfile(log.txt),所以,内容就输入到myfile(log.txt)中了。

86fb8788f3124dbf873cd7965a3ea85d.png

如果我们要进行重定向,上层只认0, 1, 2, 3, 4, 5这样的fd,我们可以在OS内部,通过一定的方式调整数组的特定下标的内容(指向),我们就可以完成重定向操作!

(2)dup2 重定向

不用dup,只看dup2

17168b2575c742c1848b14fc7170e166.png

介绍:dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the following:
介绍的解释: int dup2(int oldfd, int newfd); newfd是oldfd内容的拷贝,意思是把 oldfd 内容拷贝进 newfd,都是oldfd了。即:原本数据向newfd文件中输入,现在数据向oldfd中输入了。

5439cd90fddd4a31a5b11eeeea092829.png

如果想把stdout重定向成myfile(log.txt),拷贝是:fd—>1,int dup2(int oldfd, int newfd); oldfd—>[3], newfd—>[1],需要这样传参:dup2(fd, 1); fd这里就是3

c3f247737e8a47f9b47ec4830134638f.png

(3)追加重定向:>>

打开文件 log.txt ,dup2(fd,1)后,再向stdout中打印数据,会发现数据传到了文件log.txt中了

9e2e54988c424952bd5401bf95a3e669.png

 (4)输入重定向 <

先在给文件 log.txt 输入一堆“打开文件成功,fd: 3”

cd429d0e5a8942028a95c1f503c2ae78.png

六.缓冲区

1.缓冲区的本质:就是一段内存

2.缓冲区的意义

a. 解放使用缓冲区的进程的时间
b.缓冲区的存在可以集中处理数据刷新,减少IO的次数,从而达到提高整机的效率的目的

送书的例子:你在云南,需要把书送到北京的朋友那里:你(进程)把书(数据)交给顺丰快递(缓冲区),此时进程返回并继续执行自己后续的代码,缓冲区积累够一堆数据以后才开始

65d820e3df794fba9ee38823f9eb46b5.png

3.缓冲区在哪里

例1:

下面例子write和printf都不加\n时,write有无\n都会直接刷新,printf无\n在sleep期间不刷新,而printf内部是封装了write,说明sleep期间printf内部是把数据存在缓冲区中,此时并没有调用write系统接口:那么这个缓冲区一定不在write内部!我们曾经谈论的缓冲区,不是内核/系统级别的。那么这个缓冲区在哪里???——只能是C语言提供的,语言级别的缓冲区

printf,fprintf,fpus这类函数的参数中都有stdout这个FILE*类型的参数(printf也有只是没显示出来),结构体struct FILE中封装很多的属性,除了封装了fd,还封装了该FILE对应的语言级别的缓冲区。即:缓冲区在结构体FILE的内部。

你的代码中调用了printf() ,fprintf(),fputs() 等时,是先把要打印的内容存在结构体FILE的缓冲区cache中,缓冲区内数据积累到一定大小会定期通过fd调用write()把数据刷新到内存中去。就引出了下面的刷新策略的问题~ 

缓冲区刷新草图:

560174722e274f5aab120345c05411c5.png

既然缓冲区在FILE内部,在C语言中,而我们每一次打开一个文件,都要有一个FILE*会返回!
意味着,每一个文件都有一个fd和属于它自己的语言级别缓冲区
 

例2:如果在刷新之前,关闭了fd会有什么问题?

在进程结束时printf() ,fprintf(),fputs() 会把数据刷新到stdout,把数据刷新到stdout之前关闭stdout的文件描述符fd就会导致缓冲区内数据无法通过fd调用write()把数据刷新到内存中。

 

 如果sleep之前加上fflush(stdout),就会立即刷新。

4.刷新策略的问题

缓冲区内数据积累到一定大小会定期通过fd调用write()把数据刷新到内存中去,如何定期刷新?(什么时候刷新?)
常规:
a.无缓冲(立即刷新)——系统接口write就是无缓冲
b.行缓冲(逐行刷新)——文件是显示器就是行刷新
c.全缓冲(缓冲区满,刷新)——写入到块设备对应的文件,即:写入到磁盘文件

特殊: ①进程退出 ②用户强制刷新fflush

缓冲区和fork引发的小问题:

解释:./myfile 的刷新策略就是正常的行缓冲,立即刷新了四条字符串;

主要解释——./myfile > log.txt :

先要知道:

1.刷新的本质,把缓冲区的数据write到OS内部,清空缓区! 
2.缓冲区,是自己的FILE内部维护的,属于父进程内部的数据区域,子进程会发生写时拷贝

解释./myfile > log.txt :        当./myfile输出的内容重定向写入 log.txt时,因为log.txt是磁盘文件,所以刷新策略由 无缓冲(立即刷新) 转为 全缓冲(缓冲区满,刷新) ,所以C库函数的printf() ,fprintf(),fputs()打印的3条字符串存在各自的FILE的缓冲区中,系统接口write则不受缓冲区影响,直接刷新出来;当fork()时创建子进程,随后main函数即将结束,此时进程退出是会刷新缓冲区的。因为 缓冲区是自己的FILE内部维护的,属于父进程内部的数据区域,所以子进程要发生写时拷贝,所以父子进程就会各自刷新一份(hello fputs  ,hello printf,hello fprintf)到OS内部

5.fflush()函数:更新缓存区。

头文件:#include<stdio.h>
函数定义:int fflush(FILE *stream);
函数说明:调用fflush()会将缓冲区中的内容写到stream所指的文件中去.若stream为NULL,则会将所有打开的文件进行数据更新。

fflush 是 C 标准库提供的函数,对输入输出流起作用,起作用的是C标准库管理的用户空间文件缓存。对输出流来说,会使用系统提供的写文件系统调用(write)把标准库缓存的数据写入文件,fflush并不能保证数据真正的写入文件系统。对输入流来说,会把从可寻址的文件读入标准库缓存的数据给清洗掉。

fflush(stdin):刷新缓冲区,将缓冲区内的数据清空并丢弃。fflush(stdin)不太常用,在有些编译器中是错误的用法,可以用以下方法替代:while(getchar()!='/n');
fflush(stdout):刷新缓冲区,将缓冲区内的数据输出到设备。

6.sync,syncfs和fsync函数

总结:sync是把所有文件刷盘;syncfs针对的是把 fd所在的文件系统的所有内核缓存 刷盘(文件系统不止一个,fd所在的某一个文件系统),fsync针对的是把 fd对应的单一文件 刷盘 

(1)sync

#include <unistd.h>
void sync(void);
int syncfs(int fd);

 sync 和 syncfs 起作用的是文件系统缓存,这些缓存是在内核空间管理的。sync 会把对文件系统的元数据、缓存的文件数据写入所有底层的文件,对所有文件系统有用syncfs 需要一个文件描述符,只写入文件描述符指向的文件所在的文件系统上的数据。有时候突然拔掉优盘,里面的文件会损坏,就是因为优盘上文件的更改没有从内核文件缓存写入优盘所导致的。

在linux系统上,sync 和 syncfs 都是阻塞的,会确保数据写入底层的文件系统。但是在POSIX标准里,sync可能在数据写入之前返回。

(2)syncfs 刷盘

 int syncfs(int fd);        系统接口write仅仅是写入内核中,syncfs才是写入到磁盘上

 sync 和 syncfs 起作用的是文件系统缓存,这些缓存是在内核空间管理的。sync 会把对文件系统的元数据、缓存的文件数据写入所有底层的文件,对所有文件系统有用syncfs 需要一个文件描述符,只写入文件描述符指向的文件所在的文件系统上的数据。有时候突然拔掉优盘,里面的文件会损坏,就是因为优盘上文件的更改没有从内核文件缓存写入优盘所导致的。

在linux系统上,sync 和 syncfs 都是阻塞的,会确保数据写入底层的文件系统。但是在POSIX标准里,sync可能在数据写入之前返回。

(3)fsync

#include <unistd.h>
int fsync(int fd);
int fdatasync(int fd);

fsync 把文件描述符fd指向的文件缓存在内核中的所有已修改的数据写入文件系统,包含数据与文件元数据(文件大小,文件修改时间等)。但是fsync不会写入对指向文件的目录项的修改,也就是说如果新创建了一个文件,要是确保下次能正确读出的话,就需要把所在目录也fsync一下。

fdatasync 把和fsync作用差不多,但是不会写入对下次正确读取文件作用不大的一些元数据(比如上次访问时间,上次修改时间等),但是大小如果改变了,是会写进去的。

这两个系统调用被调用后会阻塞,直到设备报告所有数据都已写入(设备可能本身也有缓存)。

7.模拟实现一下自己封装C标准库——打开文件的模拟实现

int syncfs(int fd);  sync, syncfs - commit buffer cache to disk (把缓冲区的数据直接提交到磁盘这个硬件上)

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.h>

#define NUM 1024

#define NONE_FLUSH 0x0
#define LINE_FLUSH 0x1
#define FULL_FLUSH 0x2

typedef struct _MyFILE{
    int _fileno;
    char _buffer[NUM];
    int _end;
    int _flags; //fflush method
}MyFILE;

MyFILE *my_fopen(const char *filename, const char *method)
{
    assert(filename);
    assert(method);

    int flags = O_RDONLY;

    if(strcmp(method, "r") == 0)
    {}
    else if(strcmp(method, "r+") == 0)
    {}
    else if(strcmp(method, "w") == 0)
    {
        flags = O_WRONLY | O_CREAT | O_TRUNC;
    }
    else if(strcmp(method, "w+") == 0)
    {}
    else if(strcmp(method, "a") == 0)
    {
        flags = O_WRONLY | O_CREAT | O_APPEND;
    }
    else if(strcmp(method, "a+") == 0)
    {}

    int fileno = open(filename, flags, 0666);
    if(fileno < 0)
    {
        return NULL;
    }

    MyFILE *fp = (MyFILE *)malloc(sizeof(MyFILE));
    if(fp == NULL) return fp;
    memset(fp, 0, sizeof(MyFILE));
    fp->_fileno = fileno;
    fp->_flags |= LINE_FLUSH;
    fp->_end = 0;
    return fp;
}

void my_fflush(MyFILE *fp)
{
    assert(fp);

    if(fp->_end > 0)
    {
        write(fp->_fileno, fp->_buffer, fp->_end);
        fp->_end = 0;
        syncfs(fp->_fileno);
    }

}


void my_fwrite(MyFILE *fp, const char *start, int len)
{
    assert(fp);
    assert(start);
    assert(len > 0);

    // abcde123
    // 写入到缓冲区里面
    strncpy(fp->_buffer+fp->_end, start, len); //将数据写入到缓冲区了
    fp->_end += len;

    if(fp->_flags & NONE_FLUSH)
    {}
    else if(fp->_flags & LINE_FLUSH)
    {
        if(fp->_end > 0 && fp->_buffer[fp->_end-1] == '\n')
        {
            //仅仅是写入到内核中
            write(fp->_fileno, fp->_buffer, fp->_end);
            fp->_end = 0;
            syncfs(fp->_fileno);
        }
    }
    else if(fp->_flags & FULL_FLUSH)
    {

    }
}

void my_fclose(MyFILE *fp)
{
    my_fflush(fp);
    close(fp->_fileno);
    free(fp);
}

int main()    //第一个测试例子
{
    MyFILE *fp = my_fopen("log.txt", "w");
    if(fp == NULL)
    {
        printf("my_fopen error\n");
        return 1;
    }

	const char* s = "hello my 111\n";
	my_fwrite(fp, s, strlen(s));

	printf("消息立即刷新");
	sleep(3);

	const char* ss = "hello my 222";
	my_fwrite(fp, ss, strlen(ss));
	printf("写入了一个不满足刷新条件的字符串\n");
	sleep(3);

	const char* sss = "hello my 333";
	my_fwrite(fp, sss, strlen(sss));
	printf("写入了一个不满足刷新条件的字符串\n");
	sleep(3);


	const char* ssss = "end\n";
	my_fwrite(fp, ssss, strlen(ssss));
	printf("写入了一个满足刷新条件的字符串\n");
	sleep(3);

    const char *sssss =" aaaaaaa";
    my fwrite(fp, sssss, strlen(ssss));
    printf("写入了一个不满足刷新条件的字符串\n");
    sleep(1);
    my_ fflush(fp);
    sleep(3);
    my_ fclose(fp);

}

int main()    //第二个测试例子
{    
    const char *s = "-aaaaaaa";
    my_fwrite(fp, s, strlen(s));
    printf("写入了一个不满足刷新条件的字符串\n");
    fork();

    //模拟进程退出
    my_fclose(fp);
}

第二个main测试:

(1)有\n时, 只有一串"aaaaaaa",原因:普通的行刷新策略,在fork之前就立即刷新了,所以只有一行。

(2)无\n时, 有二串"aaaaaaa",原因:普通的行刷新策略,没有"\n",则一直不刷新,在fork之后有父子两个进程,因为代码共享,在进程退出时,父子进程各自刷新了一行"aaaaaaa",所以有二行。

zy@zy-Lenovo-Legion-R7000P2020H:~/autoware$ colcon build --symlink-install \ --cmake-args \ -DCMAKE_BUILD_TYPE=Release \ -DCUDAToolkit_ROOT=/usr/local/cuda-12.4 \ -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.4/bin/nvcc \ --continue-on-error \ --allow-overriding can_msgs Starting >>> autoware_lint_common Starting >>> autoware_planning_msgs Starting >>> autoware_simple_object_merger --- stderr: autoware_probabilistic_occupancy_grid_map In this package, headers install destination is set to `include` by ament_auto_package. It is recommended to install `include/autoware_probabilistic_occupancy_grid_map` instead and will be the default behavior of ament_auto_package from ROS 2 Kilted Kaiju. On distributions before Kilted, ament_auto_package behaves the same way when you use USE_SCOPED_HEADER_INSTALL_DIR option. CMake Warning: Manually-specified variables were not used by the project: CMAKE_CUDA_COMPILER CUDAToolkit_ROOT /usr/bin/ccache: invalid option -- 'E' nvcc fatal : Failed to preprocess host compiler properties. CMake Error at autoware_probabilistic_occupancy_grid_map_cuda_generated_utils_kernel.cu.o.Release.cmake:220 (message): Error generating /home/zy/autoware/build/autoware_probabilistic_occupancy_grid_map/CMakeFiles/autoware_probabilistic_occupancy_grid_map_cuda.dir/lib/utils/./autoware_probabilistic_occupancy_grid_map_cuda_generated_utils_kernel.cu.o gmake[2]: *** [CMakeFiles/autoware_probabilistic_occupancy_grid_map_cuda.dir/build.make:105:CMakeFiles/autoware_probabilistic_occupancy_grid_map_cuda.dir/lib/utils/autoware_probabilistic_occupancy_grid_map_cuda_generated_utils_kernel.cu.o] 错误 1 gmake[1]: *** [CMakeFiles/Makefile2:150:CMakeFiles/autoware_probabilistic_occupancy_grid_map_cuda.dir/all] 错误 2 gmake: *** [Makefile:146:all] 错误 2 --- Failed <<< autoware_probabilistic_occupancy_grid_map [29.1s, exited with code 2] Starting >>> autoware_pid_longitudinal_controller --- stderr: autoware_lidar_transfusion In this package, headers install destination is set to `include` by ament_auto_package. It is recommended to install `include/autoware_lidar_transfusion` instead and will be the default behavior of ament_auto_package from ROS 2 Kilted Kaiju. On distributions before Kilted, ament_auto_package behaves the same way when you use USE_SCOPED_HEADER_INSTALL_DIR option. sh: 1: cicc: not found CMake Error at autoware_lidar_transfusion_cuda_lib_generated_preprocess_kernel.cu.o.Release.cmake:280 (message): Error generating file /home/zy/autoware/build/autoware_lidar_transfusion/CMakeFiles/autoware_lidar_transfusion_cuda_lib.dir/lib/preprocess/./autoware_lidar_transfusion_cuda_lib_generated_preprocess_kernel.cu.o gmake[2]: *** [CMakeFiles/autoware_lidar_transfusion_cuda_lib.dir/build.make:411:CMakeFiles/autoware_lidar_transfusion_cuda_lib.dir/lib/preprocess/autoware_lidar_transfusion_cuda_lib_generated_preprocess_kernel.cu.o] 错误 1 gmake[1]: *** [CMakeFiles/Makefile2:192:CMakeFiles/autoware_lidar_transfusion_cuda_lib.dir/all] 错误 2 gmake: *** [Makefile:146:all] 错误 2 --- Failed <<< autoware_lidar_transfusion [34.7s, exited with code 2] Starting >>> autoware_pure_pursuit --- stderr: autoware_planning_validator In this package, headers install destination is set to `include` by ament_auto_package. It is recommended to install `include/autoware_planning_validator` instead and will be the default behavior of ament_auto_package from ROS 2 Kilted Kaiju. On distributions before Kilted, ament_auto_package behaves the same way when you use USE_SCOPED_HEADER_INSTALL_DIR option. CMake Warning: Manually-specified variables were not used by the project: CMAKE_CUDA_COMPILER CUDAToolkit_ROOT /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_functions.cpp.o: in function `PlanningValidatorTestSuite_checkValidFiniteValueFunction_Test::TestBody()': test_planning_validator_functions.cpp:(.text+0xa4): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0xf0): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidFiniteValue(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x120): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidFiniteValue(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x153): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidFiniteValue(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_functions.cpp.o: in function `PlanningValidatorTestSuite_checkValidIntervalFunction_Test::TestBody()': test_planning_validator_functions.cpp:(.text+0x4f9): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x549): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidInterval(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x59b): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidInterval(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x5e0): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidInterval(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x638): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidInterval(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_functions.cpp.o: in function `PlanningValidatorTestSuite_checkValidCurvatureFunction_Test::TestBody()': test_planning_validator_functions.cpp:(.text+0xb24): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0xb70): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidCurvature(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_functions.cpp.o: in function `PlanningValidatorTestSuite_checkValidRelativeAngleFunction_Test::TestBody()': test_planning_validator_functions.cpp:(.text+0xde7): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0xe64): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidRelativeAngle(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0xec5): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidRelativeAngle(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0xf28): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidRelativeAngle(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0xfef): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidRelativeAngle(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_functions.cpp.o: in function `PlanningValidatorTestSuite_checkValidLateralJerkFunction_Test::TestBody()': test_planning_validator_functions.cpp:(.text+0x14b9): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x150a): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidLateralJerk(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x15ea): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidLateralJerk(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x1662): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidLateralJerk(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x17f5): undefined reference to `autoware::planning_validator::PlanningValidator::checkValidLateralJerk(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_functions.cpp.o: in function `PlanningValidatorTestSuite_checkTrajectoryShiftFunction_Test::TestBody()': test_planning_validator_functions.cpp:(.text+0x1d2b): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x1dda): undefined reference to `autoware::planning_validator::PlanningValidator::checkTrajectoryShift(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, geometry_msgs::msg::Pose_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x1e2a): undefined reference to `autoware::planning_validator::PlanningValidator::checkTrajectoryShift(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, geometry_msgs::msg::Pose_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x1e77): undefined reference to `autoware::planning_validator::PlanningValidator::checkTrajectoryShift(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, geometry_msgs::msg::Pose_<std::allocator<void> > const&)' /usr/bin/ld: test_planning_validator_functions.cpp:(.text+0x1ec6): undefined reference to `autoware::planning_validator::PlanningValidator::checkTrajectoryShift(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, geometry_msgs::msg::Pose_<std::allocator<void> > const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_pubsub.cpp.o: in function `prepareTest(autoware_planning_msgs::msg::Trajectory_<std::allocator<void> > const&, nav_msgs::msg::Odometry_<std::allocator<void> > const&, geometry_msgs::msg::AccelWithCovarianceStamped_<std::allocator<void> > const&)': test_planning_validator_pubsub.cpp:(.text+0x3164): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' /usr/bin/ld: CMakeFiles/test_autoware_planning_validator.dir/test/src/test_planning_validator_node_interface.cpp.o: in function `generateNode()': test_planning_validator_node_interface.cpp:(.text+0x14d5): undefined reference to `autoware::planning_validator::PlanningValidator::PlanningValidator(rclcpp::NodeOptions const&)' collect2: error: ld returned 1 exit status gmake[2]: *** [CMakeFiles/test_autoware_planning_validator.dir/build.make:736:test_autoware_planning_validator] 错误 1 gmake[1]: *** [CMakeFiles/Makefile2:761:CMakeFiles/test_autoware_planning_validator.dir/all] 错误 2 gmake: *** [Makefile:146:all] 错误 2 --- Failed <<< autoware_planning_validator [54.8s, exited with code 2] Summary: 400 packages finished [12min 14s] 13 packages failed: autoware_behavior_path_goal_planner_module autoware_costmap_generator autoware_cuda_pointcloud_preprocessor autoware_dummy_perception_publisher autoware_lidar_centerpoint autoware_lidar_transfusion autoware_obstacle_cruise_planner autoware_planning_validator autoware_probabilistic_occupancy_grid_map autoware_tensorrt_plugins autoware_tensorrt_yolox bevdet_vendor trt_batched_nms 393 packages had stderr output: agnocast_e2e_test agnocast_ioctl_wrapper agnocast_sample_application agnocast_sample_interfaces agnocastlib astra_camera astra_camera_msgs autoware_accel_brake_map_calibrator autoware_adapi_adaptors autoware_adapi_specs autoware_adapi_v1_msgs autoware_adapi_version_msgs autoware_agnocast_wrapper autoware_ar_tag_based_localizer autoware_auto_common autoware_automatic_pose_initializer autoware_autonomous_emergency_braking autoware_bag_time_manager_rviz_plugin autoware_behavior_path_avoidance_by_lane_change_module autoware_behavior_path_dynamic_obstacle_avoidance_module autoware_behavior_path_external_request_lane_change_module autoware_behavior_path_goal_planner_module autoware_behavior_path_lane_change_module autoware_behavior_path_planner autoware_behavior_path_planner_common autoware_behavior_path_sampling_planner_module autoware_behavior_path_side_shift_module autoware_behavior_path_start_planner_module autoware_behavior_path_static_obstacle_avoidance_module autoware_behavior_velocity_blind_spot_module autoware_behavior_velocity_crosswalk_module autoware_behavior_velocity_detection_area_module autoware_behavior_velocity_intersection_module autoware_behavior_velocity_no_drivable_lane_module autoware_behavior_velocity_no_stopping_area_module autoware_behavior_velocity_occlusion_spot_module autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_rtc_interface autoware_behavior_velocity_run_out_module autoware_behavior_velocity_speed_bump_module autoware_behavior_velocity_stop_line_module autoware_behavior_velocity_template_module autoware_behavior_velocity_traffic_light_module autoware_behavior_velocity_virtual_traffic_light_module autoware_behavior_velocity_walkway_module autoware_bezier_sampler autoware_bluetooth_monitor autoware_boundary_departure_checker autoware_bytetrack autoware_cluster_merger autoware_collision_detector autoware_compare_map_segmentation autoware_component_interface_specs autoware_component_interface_specs_universe autoware_component_interface_tools autoware_component_interface_utils autoware_component_monitor autoware_component_state_monitor autoware_control_evaluator autoware_control_msgs autoware_control_performance_analysis autoware_control_validator autoware_core autoware_core_control autoware_core_localization autoware_core_map autoware_core_perception autoware_core_planning autoware_core_sensing autoware_core_vehicle autoware_costmap_generator autoware_crop_box_filter autoware_crosswalk_traffic_light_estimator autoware_cuda_pointcloud_preprocessor autoware_cuda_utils autoware_default_adapi autoware_detected_object_feature_remover autoware_diagnostic_graph_aggregator autoware_diagnostic_graph_utils autoware_dummy_diag_publisher autoware_dummy_infrastructure autoware_dummy_perception_publisher autoware_duplicated_node_checker autoware_ekf_localizer autoware_elevation_map_loader autoware_euclidean_cluster autoware_euclidean_cluster_object_detector autoware_external_api_msgs autoware_external_cmd_converter autoware_external_cmd_selector autoware_external_velocity_limit_selector autoware_fake_test_node autoware_fault_injection autoware_freespace_planner autoware_freespace_planning_algorithms autoware_frenet_planner autoware_geo_pose_projector autoware_geography_utils autoware_global_parameter_loader autoware_glog_component autoware_gnss_poser autoware_goal_distance_calculator autoware_grid_map_utils autoware_ground_filter autoware_ground_segmentation autoware_gyro_odometer autoware_hazard_status_converter autoware_image_diagnostics autoware_image_transport_decompressor autoware_imu_corrector autoware_internal_localization_msgs autoware_interpolation autoware_iv_external_api_adaptor autoware_iv_internal_api_adaptor autoware_joy_controller autoware_kalman_filter autoware_kinematic_evaluator autoware_landmark_manager autoware_lane_departure_checker autoware_lanelet2_extension autoware_lanelet2_extension_python autoware_lanelet2_map_visualizer autoware_lanelet2_utils autoware_learning_based_vehicle_model autoware_lidar_centerpoint autoware_lidar_marker_localizer autoware_lidar_transfusion autoware_livox_tag_filter autoware_localization_error_monitor autoware_localization_evaluator autoware_localization_msgs autoware_localization_rviz_plugin autoware_localization_util autoware_map_based_prediction autoware_map_height_fitter autoware_map_loader autoware_map_msgs autoware_map_projection_loader autoware_map_tf_generator autoware_mission_details_overlay_rviz_plugin autoware_mission_planner autoware_mission_planner_universe autoware_motion_utils autoware_motion_velocity_dynamic_obstacle_stop_module autoware_motion_velocity_obstacle_cruise_module autoware_motion_velocity_obstacle_slow_down_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_obstacle_velocity_limiter_module autoware_motion_velocity_out_of_lane_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_motion_velocity_run_out_module autoware_mpc_lateral_controller autoware_mrm_comfortable_stop_operator autoware_mrm_emergency_stop_operator autoware_mrm_handler autoware_msgs autoware_multi_object_tracker autoware_ndt_scan_matcher autoware_node autoware_object_merger autoware_object_range_splitter autoware_object_recognition_utils autoware_object_velocity_splitter autoware_objects_of_interest_marker_interface autoware_obstacle_collision_checker autoware_obstacle_cruise_planner autoware_obstacle_stop_planner autoware_occupancy_grid_map_outlier_filter autoware_operation_mode_transition_manager autoware_osqp_interface autoware_overlay_rviz_plugin autoware_path_distance_calculator autoware_path_generator autoware_path_optimizer autoware_path_sampler autoware_path_smoother autoware_pcl_extensions autoware_perception_objects_converter autoware_perception_online_evaluator autoware_perception_rviz_plugin autoware_pid_longitudinal_controller autoware_planning_evaluator autoware_planning_factor_interface autoware_planning_rviz_plugin autoware_planning_test_manager autoware_planning_topic_converter autoware_planning_validator autoware_point_types autoware_pointcloud_preprocessor autoware_polar_grid autoware_pose2twist autoware_pose_covariance_modifier autoware_pose_estimator_arbiter autoware_pose_initializer autoware_pose_instability_detector autoware_predicted_path_checker autoware_probabilistic_occupancy_grid_map autoware_processing_time_checker autoware_pure_pursuit autoware_pyplot autoware_qp_interface autoware_radar_crossing_objects_noise_filter autoware_radar_fusion_to_detected_object autoware_radar_object_clustering autoware_radar_object_tracker autoware_radar_objects_adapter autoware_radar_scan_to_pointcloud2 autoware_radar_static_pointcloud_filter autoware_radar_threshold_filter autoware_radar_tracks_msgs_converter autoware_radar_tracks_noise_filter autoware_raw_vehicle_cmd_converter autoware_remaining_distance_time_calculator autoware_route_handler autoware_rtc_interface autoware_sampler_common autoware_scenario_selector autoware_scenario_simulator_v2_adapter autoware_sensing_msgs autoware_shape_estimation autoware_shift_decider autoware_signal_processing autoware_simple_object_merger autoware_simple_planning_simulator autoware_simple_pure_pursuit autoware_smart_mpc_trajectory_follower autoware_steer_offset_estimator autoware_stop_filter autoware_string_stamped_rviz_plugin autoware_surround_obstacle_checker autoware_system_diagnostic_monitor autoware_system_monitor autoware_system_msgs autoware_tensorrt_classifier autoware_tensorrt_plugins autoware_tensorrt_yolox autoware_test_node autoware_test_utils autoware_testing autoware_time_utils autoware_topic_relay_controller autoware_topic_state_monitor autoware_tracking_object_merger autoware_traffic_light_arbiter autoware_traffic_light_category_merger autoware_traffic_light_map_based_detector autoware_traffic_light_multi_camera_fusion autoware_traffic_light_occlusion_predictor autoware_traffic_light_recognition_marker_publisher autoware_traffic_light_selector autoware_traffic_light_utils autoware_traffic_light_visualization autoware_trajectory autoware_trajectory_follower_base autoware_trajectory_follower_node autoware_twist2accel autoware_universe_utils autoware_utils autoware_utils_debug autoware_utils_diagnostics autoware_utils_geometry autoware_utils_logging autoware_utils_math autoware_utils_pcl autoware_utils_rclcpp autoware_utils_system autoware_utils_tf autoware_utils_uuid autoware_utils_visualization autoware_v2x_msgs autoware_vehicle_cmd_gate autoware_vehicle_door_simulator autoware_vehicle_info_utils autoware_vehicle_msgs autoware_vehicle_velocity_converter autoware_velocity_smoother autoware_velodyne_monitor awapi_awiv_adapter awsim_labs_sensor_kit_description awsim_labs_sensor_kit_launch awsim_labs_vehicle_description awsim_labs_vehicle_launch awsim_sensor_kit_description awsim_sensor_kit_launch bevdet_vendor boost_io_context boost_serial_driver boost_tcp_driver boost_udp_driver camera_description can_bridge can_msgs cartop common_awsim_labs_sensor_launch common_sensor_launch continental_msgs continental_srvs cubtek_can cubtek_can_msgs cubtek_radar_adapter cuda_blackboard demo_cpp_tf dummy_status_publisher eagleye_coordinate eagleye_fix2kml eagleye_geo_pose_converter eagleye_geo_pose_fusion eagleye_gnss_converter eagleye_msgs eagleye_navigation eagleye_rt eagleye_tf glog imu_description imu_release livox_description llh_converter managed_transform_buffer morai_msgs mussp nebula_common nebula_decoders nebula_examples nebula_hw_interfaces nebula_msgs nebula_ros nebula_sensor_driver nebula_tests negotiated_examples pandar_description pandar_msgs perception_utils pointcloud_to_laserscan radar_description robosense_msgs ros2_wit_imu rtklib_bridge rtklib_msgs sample_sensor_kit_description sample_sensor_kit_launch sample_vehicle_description sample_vehicle_launch seyond single_lidar_common_launch single_lidar_sensor_kit_description single_lidar_sensor_kit_launch tier4_adapi_rviz_plugin tier4_api_msgs tier4_api_utils tier4_auto_msgs_converter tier4_autoware_api_launch tier4_camera_view_rviz_plugin tier4_control_launch tier4_control_msgs tier4_datetime_rviz_plugin tier4_debug_msgs tier4_deprecated_api_adapter tier4_dummy_object_rviz_plugin tier4_external_api_msgs tier4_hmi_msgs tier4_localization_launch tier4_localization_msgs tier4_localization_rviz_plugin tier4_map_launch tier4_map_msgs tier4_metric_msgs tier4_perception_msgs tier4_planning_factor_rviz_plugin tier4_planning_msgs tier4_rtc_msgs tier4_sensing_launch tier4_simulation_msgs tier4_state_rviz_plugin tier4_system_launch tier4_system_msgs tier4_system_rviz_plugin tier4_traffic_light_rviz_plugin tier4_v2x_msgs tier4_vehicle_launch tier4_vehicle_msgs tier4_vehicle_rviz_plugin tmlidar_msg tmlidar_sdk trt_batched_nms velodyne_description vls_description yabloc_common yabloc_image_processing yabloc_monitor yabloc_particle_filter yabloc_pose_initializer 11 packages not processed zy@zy-Lenovo-Legion-R7000P2020H:~/autoware$
08-30
Aug 15, 2025 2:21:21 PM com.kms.katalon.core.logging.KeywordLogger startTest INFO: -------------------- Aug 15, 2025 2:21:22 PM com.kms.katalon.core.logging.KeywordLogger startTest INFO: START Test Cases/try Aug 15, 2025 2:21:24 PM org.openqa.selenium.manager.SeleniumManager lambda$runCommand$1 WARNING: error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json) Aug 15, 2025 2:21:24 PM com.kms.katalon.core.logging.KeywordLogger log SEVERE: ❌ Test Cases/try FAILED. Reason: org.openqa.selenium.remote.NoSuchDriverException: Unable to obtain: chromedriver, error Command failed with code: 65, executed: [--browser, chrome, --language-binding, java, --output, json] error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json) Build info: version: '4.22.0', revision: 'c5f3146703' System info: os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.14' Driver info: driver.version: ChromeDriver at org.openqa.selenium.remote.service.DriverFinder.getBinaryPaths(DriverFinder.java:121) at org.openqa.selenium.remote.service.DriverFinder.getDriverPath(DriverFinder.java:55) at org.openqa.selenium.chrome.ChromeDriver.generateExecutor(ChromeDriver.java:99) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:88) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:83) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:51) at try.run(try:25) at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194) at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119) at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:448) at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:439) at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:418) at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:410) at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:285) at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:137) at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:125) at TempTestCase1755238875241.run(TempTestCase1755238875241.groovy:25) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) Caused by: org.openqa.selenium.WebDriverException: Command failed with code: 65, executed: [--browser, chrome, --language-binding, java, --output, json] error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json) Build info: version: '4.22.0', revision: 'c5f3146703' System info: os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.14' Driver info: driver.version: ChromeDriver at org.openqa.selenium.manager.SeleniumManager.runCommand(SeleniumManager.java:170) at org.openqa.selenium.manager.SeleniumManager.getBinaryPaths(SeleniumManager.java:247) at org.openqa.selenium.remote.service.DriverFinder.getBinaryPaths(DriverFinder.java:102) at org.openqa.selenium.remote.service.DriverFinder.getDriverPath(DriverFinder.java:55) at org.openqa.selenium.chrome.ChromeDriver.generateExecutor(ChromeDriver.java:99) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:88) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:83) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:51) at Script1755238419595.run(Script1755238419595.groovy:25) ... 13 more Aug 15, 2025 2:21:24 PM com.kms.katalon.core.logging.KeywordLogger log SEVERE: ❌ Test Cases/try FAILED. Reason: org.openqa.selenium.remote.NoSuchDriverException: Unable to obtain: chromedriver, error Command failed with code: 65, executed: [--browser, chrome, --language-binding, java, --output, json] error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json) Build info: version: '4.22.0', revision: 'c5f3146703' System info: os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.14' Driver info: driver.version: ChromeDriver at org.openqa.selenium.remote.service.DriverFinder.getBinaryPaths(DriverFinder.java:121) at org.openqa.selenium.remote.service.DriverFinder.getDriverPath(DriverFinder.java:55) at org.openqa.selenium.chrome.ChromeDriver.generateExecutor(ChromeDriver.java:99) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:88) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:83) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:51) at try.run(try:25) at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194) at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119) at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:448) at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:439) at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:418) at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:410) at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:285) at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:137) at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:125) at TempTestCase1755238875241.run(TempTestCase1755238875241.groovy:25) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) Caused by: org.openqa.selenium.WebDriverException: Command failed with code: 65, executed: [--browser, chrome, --language-binding, java, --output, json] error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json) Build info: version: '4.22.0', revision: 'c5f3146703' System info: os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.14' Driver info: driver.version: ChromeDriver at org.openqa.selenium.manager.SeleniumManager.runCommand(SeleniumManager.java:170) at org.openqa.selenium.manager.SeleniumManager.getBinaryPaths(SeleniumManager.java:247) at org.openqa.selenium.remote.service.DriverFinder.getBinaryPaths(DriverFinder.java:102) ... 19 more Aug 15, 2025 2:21:24 PM com.kms.katalon.core.logging.KeywordLogger endTest INFO: END Test Cases/try
08-16
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值