Linux嵌入式_应用开发_文件读写API

在这里插入图片描述

二/文件操作API:

1、open函数

使用:man 2 open 查询

功能:打开文件

//包含的头文件       
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

//函数原型
int open(const char *pathname, int flags);/*常用*/
int open(const char *pathname, int flags, mode_t mode);/*不常用,不用了解*/


/*
//参数
+pathname:字符串,是文件名,包含绝对路径,如果没有绝对路径,则默认是当前路径
+flags:以何种方式打开文件
    ++常用包括:
    	O_CREAT:如果文件不存在则创建,存在则打开
    	O_RDONLY:只读打开
   		O_WRONLY:只写打开
    	O_RDWR:可读可写打开文件
    	O_APPEND:追加
		O_NOCTTY:如果文件指向终端设备,不要将其用作控制终端
    	O_TRUNC:如果文件存在,并且是以只读或者读写方式打开,则将其长度截断为0
    	O_EXCL:文件存在的话,则出错,并且返回-1
+mode:添加权限
    
//返回值:成功返回文件句柄,失败返回-1;

*/

2、close函数

功能:关闭文件

//包含的头文件 
#include <unistd.h>

//函数原型
int close(int fd);

/*
//参数
+fd:需要关闭的文件的句柄
    
//返回值:成功返回0,失败返回-1;

*/



3、write函数

功能:将buf数组的内容写入count个字节到fd文件中

//包含的头文件 
#include <unistd.h>

//函数原型
ssize_t write(int fd, const void *buf, size_t count);

/*
//参数
+fd:需要写入的文件的句柄
+buf:数组
+count:需要写入的字节数
   
//返回值:成功返回实际写入的字节数,失败返回-1;

*/

4、read函数

功能:将fd文件的内容读出count个字节到buf数组中

//包含的头文件 
#include <unistd.h>

//函数原型
ssize_t read(int fd, void *buf, size_t count);


/*
//参数
+fd:需要读出的文件的句柄
+buf:数组
+count:需要读出的字节数
   
//返回值:成功返回实际读出的字节数,失败返回-1;

*/

争对write和read系统调用,可以读写文件描述符为0 (宏:STDIO),1(宏:STDOUT),2的文件(宏:STDERR),

0是标准输入(先到库缓存)

#include <unistd.h>                                                                                 

int main()
{
    char buff[20] = {0};
    read(0, buff, 10);
    write(1,buff, 10);
    return 0;
}

结果:执行./a.out后,等待输入,程序读取前十个字节,然后write输出到屏幕上,然后结束进程,输入缓冲区还剩下字符d niaho,就当作shell命令执行,最后找不到命令

在这里插入图片描述

#include <unistd.h>                                                                                 

int main()
{
    write(1, "hello world\n",sizeof("hello world\n"));
    return 0;
}

结果:执行./a.out在屏幕上输出hello world并且换行
在这里插入图片描述

2是标准错误输出(直接到系统缓存)

5、lseek函数

功能:读文件的时候,移动光标

//包含的头文件 
#include <sys/types.h>
#include <unistd.h>

//函数原型
off_t lseek(int fd, off_t offset, int whence);


/*
//参数
+fd:操作的文件
+offset:偏移量
+whence:
	++SEEK_SET:以当前offset为光标位置,比如offset=0,则光标定位到文件首(SEEK_SET模式下offset不能为负数)
	++SEEK_CUR:以当前光标所在的位置偏移offset多个位置,正数向右偏移,负数向左偏移
	++SEEK_END:将光标定位到文件尾后再偏移offset多个位置,正数向右偏移,负数向左偏移
   
   
//返回值:成功返回光标距离文件首的字节,失败返回-1;

*/

//以上API是linux下的系统调用函数接口,此外,标准C库里边也有类似的函数,如下fopen,fclose,fread,fwrite等

显然,C库的函数移植性更好

6、fopen函数

功能:打开文件输入输出流

//包含的头文件       
 #include <stdio.h>

//函数原型
FILE *fopen(const char *pathname, const char *mode);


/*
//参数
+pathname:字符串,是文件名,包含绝对路径,如果没有绝对路径,则默认是当前路径
+mode:以何种方式打开文件
	++包括:
	r:只读方式打开,文件必须存在
	r+:可读写,文件必须存在
	w:只写,存在则长度清零,不存在则建立文件
	w+:可读写,存在则长度清零,不存在则建立文件
	a:附加方式打开,只写,不存在则建立,存在则追加,EOF符保留
	a+:附加方式打开,可读写,不存在则建立,存在则追加,EOF符不保留
	
	rb+:打开二进制文件,可读写
	rt+:打开文本文件,可读写
	wb:打开二进制文件,只写
	wb+:打开或建立二进制文件,可读写
	wt+:打开或建立文本文件,可读写
	ab+:打开二进制文件,可读写,写的数据加载文件末尾
	at+:打开文本文件,可读写,写的数据加在文件末尾
	
    
//返回值:FILE是一个结构体,包含文件相关的个各种信息。成功返回指针,失败返回NULL;

*/



在这里插入图片描述

7、fclose函数

功能:关闭该stream指向文件的IO流

如果库缓冲区还剩下数据,则将剩余数据传到系统缓冲区。

//包含的头文件       
 #include <stdio.h>

//函数原型
int fclose(FILE *stream);

/*
//参数
+stream:文件指针,关闭该文件的IO流

//返回值:成功返回0,失败返回EOF

*/

8、fread和fwrite函数

功能:fread:从stream指向的文件读nmemb多次size字节到ptr缓冲区

​ fwrite:从文件ptr缓冲区写nmemb多次size字节到stream指向的文件

//包含的头文件       
 #include <stdio.h>

//函数原型
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

/*
//参数
+ptr:缓冲区指针
+size:一次读写字节数
+nmemb:读写次数
+stream:读写目标文件IO流

//返回值:成功返回实际读写次数(并非nmemb),失败返回-1

*/



扩展:

  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5     printf("nihao");
  6     fwrite("hello1",6, 1, stdout);                                                              
  7     fwrite("hello2",6, 1, stderr);
  8     while(1);
  9     return 0;
 10 }

执行以上代码,就可以知道只输出hello2,然后进入while(1)循环。“nihao”和“hello1”并不会打印到屏幕,而是还在库缓冲区。

9、fseek函数

功能:类似移动光标,实际是改文件内部指针位置

//包含的头文件       
 #include <stdio.h>

//函数原型
int fseek(FILE *stream, long offset, int whence);


//参数参考五、lseek系统调用,简直一样//
/*
//参数
+stream:操作的文件
+offset:偏移量
+whence:
	++SEEK_SET:以当前offset为光标位置,比如offset=0,则光标定位到文件首(SEEK_SET模式下offset不能为负数)
	++SEEK_CUR:以当前光标所在的位置偏移offset多个位置,正数向右偏移,负数向左偏移
	++SEEK_END:将光标定位到文件尾后再偏移offset多个位置,正数向右偏移,负数向左偏移
   
   
//返回值:成功返回0,失败返回-1;
注意:返回值跟lseek不一样

*/


10、fuptc函数族

fputs,fputs,putchar,puts:当遇到‘\n’或者库缓冲区满(1024字节)的时候,才将库缓冲区的数据送到系统缓冲区,进行数据传输,实现打印或者写入文件。否则一直存在库缓冲区,不会显示也不会写入到文件,只有等待文件关闭的时候(参考fclose函数),才将剩余的数据传给系统缓冲区。另外可以调用函数fflush,强制性将库缓冲区的数据传给系统缓冲区,实现打印到屏幕或者写到文件。

//包含的头文件
  #include <stdio.h>


//函数原型
	//1.将字符c写入文件流stream
   int fputc(int c, FILE *stream);

	//2.将字符串s写入文件流stream
   int fputs(const char *s, FILE *stream);
	
	//3.Putc()等价于fputc(),不同之处在于它可以作为一个宏来实现流不止一次。(不同之处不用看)
   int Putc(int c, FILE *stream);

	//4.将字符c输出到屏幕
   int putchar(int c);

	//5.将字符串s输出到屏幕
   int puts(const char *s);

//返回值:
   fputc(), putc(), and putchar() return the character written as an unsigned char cast to an
   int or EOF on error.
  
   puts() and fputs() return a nonnegative number on success, or EOF on error.
       
  nonnegative:正数
   

11、fflush函数

参考10

功能:将库缓冲区的数据强制传输到系统缓冲区

//包含的头文件
#include <stdio.h>

//函数原型
int fflush(FILE *stream);

12、getc族函数

//包含的头文件
  #include <stdio.h>

//函数原型

//读一个字符,返回该字符,在文件的结尾或者错误返回EOF
int fgetc(FILE *stream);

//读stream到s缓冲区size字节,成功返回s指针,失败返回NULL
char *fgets(char *s, int size, FILE *stream);

int getc(FILE *stream);//读文件stream一个字符

int getchar(void);//读键盘一个字符

int ungetc(int c, FILE *stream);



/*//返回值:
       fgetc(),  getc(),  and  getchar() return the character read as an unsigned char cast to an
       int or EOF on end of file or error.

       fgets() returns s on success, and NULL on error or when end of file occurs while no  char‐
       acters have been read.

       ungetc() returns c on success, or EOF on error.
*/

13、rewind函数

将光标回到文件头;rewind(fd)等价于fseek(fd,0,SEEK_SET);

void rewind(FILE *stream);

14.feof,ferror函数

#include <stdio.h>

void clearerr(FILE *stream);//清除错误标志

int feof(FILE *stream);//文件是否结束

int ferror(FILE *stream);//文件是否出错

int fileno(FILE *stream);//不重要

15.静态动态库

add.c

int add(int a,int b)
{
	return (a+b);
}

main.c

#include <stdio.h>
int add(int a,int b);

int main()
{
	int x = 1,y = 5;
	printf("he = %d \n",add(x, y));
	return 0;
}

①、静态库:

gcc add.c -c -o add.o		//生成.o文件(与文件路径有关)
ar -cr -o libadd.a add.o	//生成add静态库文件,libadd.a中add才是名字,lib是前缀表示库,.a是后缀表示静态库
gcc main.c -L. -ladd		//生成a.out可执行文件,-L.表示在当前文件找,-ladd表示链接上add库
./a.out 					//执行a.out文件

②、动态库:

//生成.o文件(与文件路径无关,)
gcc -c -fpic add.c					

//生成add动态库文件,libadd.so中add才是名字,lib是前缀表示库,.so是后缀表示动态库  
gcc -shared add.o -o libadd.so

gcc main.c -ladd -L.	//生成a.out

./a.out		//执行

但是运行时会显示无法找到该动态库:

解决方法一

配置环境变量:LD_LIBRARY_PATHadd

export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH 

注意pwd上的两个``是Tab键上的那个点,不是‘’。

但是export方式在重启终端后失效

**方法二:**将libadd.so复制到/usr/lib下

sudo cp libadd.so /usr/lib

复制完后执行a.out,然后删除/usr/lib目录下的libadd.so(学习而已,不要乱加东西到库里面)

​ **说明:**库要和头文件一起使用,因为没有头文件,别人不知道这个库中有哪些函数,就无法使用。

库可以看作是将头文件里面定义的函数进行实际实现的代码。

在使用gcc编译的时候,加上参数 -l xxx -L (库文件的目录)

比如说 gcc main.c -ladd -L.,其中add表示使用libadd.so的库文件,命令中只需要写库名称省略前缀后缀。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C是一个广泛使用的计算机编程语言。C语言由贝尔实验室的Dennis Ritchie在20世纪70年代初开发。从那时起,C语言一直是最受欢迎和广泛使用的编程语言之一。 C语言具有直接而简单的语法结构,因此易于学习和使用。它提供了丰富的编程功能和灵活性,使得开发者可以编写高效且可移植的代码。C语言可以用于开发各种应用程序,例如操作系统、编译器、数据库、嵌入式系统和网络应用等。 C语言广泛应用于计算机科学和软件开发领域。它是大多数计算机科学专业学生的必修课程,并且被广泛使用于编程教育和训练中。许多著名的软件和计算机系统,如UNIX操作系统和Linux内核,都是用C语言编写的。 C语言的最大特点之一是它的效率和性能。由于其与硬件之间的密切关系,开发者可以直接访问计算机的底层资源,使得C语言编写的程序速度快且占用内存少。此外,C语言还提供了丰富的库函数和工具,方便开发者进行程序设计和调试。 然而,使用C语言编写程序也存在一些挑战。首先,C语言对细节要求严格,需要程序员注意内存管理和指针操作等细节。其次,C语言没有内置的面向对象特性,需要开发者自己实现;这在某些情况下可能会增加开发的复杂性。 总而言之,C语言是一种功能强大且广泛应用的计算机编程语言。它具有直接而简单的语法结构、高效和可移植性等优点,因此在计算机科学和软件开发领域得到了广泛的应用和认可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值