栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

求职笔记之嵌入式知识点04

Java 更新时间:发布时间: 百科书网 趣学号

文章目录
  • 第一章 Linux中的文件IO
    • 一、文件IO基本介绍
    • 二、文件IO函数原型
    • 三、文件IO例子
  • 第二章 Linux中的标准IO
    • 一、标准IO基本介绍
    • 二、标准IO函数原型
    • 三、标准IO例子
  • 第三章 目录IO
    • 一、目录IO基本介绍
    • 二、文件IO函数原型
    • 三、目录IO例子
  • 综合例子

第一章 Linux中的文件IO 一、文件IO基本介绍

1.Linux常用的文件IO API
open、close、write、read、lseek。

2.文件操作的一般步骤
(1)open 打开一个文件,得到一个文件描述符,然后对文件进行读写操作(或其他操作),最后 close 关闭文件即可。
(2)文件平时是存放在文件系统中的块设备,我们把这种文件叫静态文件。当我们去 open打开一个文件时, Linux 的内核操作包括:在进程中建立一个打开文件的数据结构,记录下打开的这个文件;然后申请一段内存,将静态文件的内容从块设备读取到内存中的特定地址管理存放,称为动态文件。
(3)文件打开后,针对这份文件的读写操作,都是针对这份动态文件的。当我们 close 关闭动态文件时,内核就将内存中的动态文件更新到块设备中的静态文件。
(4)常见现象:打开一个大文件时比较慢;写了一半的文件如果没保存直接关机,重启后文件内容丢失。

3.文件描述符

  • 文件描述符实际是一个数字,在进程中表示一个特定的含义,当我们 open 打开一个文件时,操作系统在内存中构建了一些数据结构来表示这个动态文件,然后返回给应用程序一个数字作为文件描述符,即该进程中该文件的标识。
  • 文件描述符的作用域就是当前进程,出了当前进程这个文件描述符就没有意义了。
  • Linux 中的文件描述符 fd 的合法范围是 0 或者一个正整数,不可能是一个负数。
二、文件IO函数原型

1.open函数原型

#include 

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
返回值:成功返回新分配的文件描述符,出错返回-1并设置errno。
  • flag的常用选项(前面三个常数中必须指定一个,且仅允许指定一个)有:

    flag选项功能
    O_RDONLY只读
    O_WRONLY只写
    O_RDWR读写
    O_CREAT创建一个文件
    O_EXCL检测文件是否存在,对于文件已经存在的情况下,会报错而不是重新创建
    O_TRUNC打开文件覆盖
    O_APPEND打开文件追加

    写阻塞等待( O_SYNC)与非阻塞(O_NONBLOCK)方式打开设备文件:

    • 阻塞与非阻塞:如果一个函数是阻塞式的,则调用这个函数时有可能因为函数执行条件未具备而被卡住一直等待。如果它是非阻塞式的,那么调用这个函数后一定会立即返回,但函数有没有完成任务则不确定;
    • 阻塞式的结果有保障但是时间没有保障,非阻塞式的时间有保障但是结果没有保障
    • O_NonBLOCK 时 write 只是将内容写入底层缓冲区则返回,然后底层在合适的时候再将buf 内容一次性同步到硬盘中,这种设计是为了提升硬件操作的性能和效率以及硬件寿命。但有时我们希望硬件不要等待立即写入,则可用 O_SYNC。
  • open()创建文件的权限:mode &(~umask)
    比如:

    umask=0022 —>0777-0022=0755

    所以,设置权限之前要将默认权限关闭umask(0);。

2.close函数原型

#include 
int close(int fd)
返回值:成功返回0,出错返回-1并设置errno。

需要说明的是,当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在进程终止时内核也会自动关闭它打开的所有文件。

3.write函数原型

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

函数说明:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。
返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错误代码存入errno中。

附加说明:

  • write()函数返回值一般无0,只有当如下情况发生时才会返回0:write(fp, p1+len, (strlen(p1)-len))中第三参数为0,此时write()什么也不做,只返回0;
  • write()函数从buf写数据到fd中时,若buf中数据无法一次性读完,那么第二次读buf中数据时,其读位置指针(也就是第二个参数buf)不会自动移动,需要程序员来控制,而不是简单的将buf首地址填入第二参数即可。如可按如下格式实现读位置移动:write(fp, p1+len, (strlen(p1)-len))。 这样write第二次循环时便会从p1+len处写数据到fp, 之后的也一样。由此类推,直至(strlen(p1)-len)变为0;
  • 在write一次可以写的最大数据范围内(貌似是BUFSIZ ,8192),第三参数count大小最好为buf中数据的大小,以免出现错误。(经过笔者再次试验,write一次能够写入的并不只有8192这么多,笔者尝试一次写入81920000,结果也是可以,看来其一次最大写入数据并不是8192,但内核中确实有BUFSIZ这个参数,具体指什么还有待研究)。

4.read函数原型

#include 

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

函数说明:read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。

返回值:返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。若参数count 为0, 则read()不会有作用并返回0。另外,以下情况返回值小于count。
(1)读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有50个字节而请求读100个字节,则read返回50,下次read将返回0;
(2)对于网络套接字接口,返回值可能小于count,但这不是错误,详细解释参考这篇文章https://blog.csdn.net/hhhlizhao/article/details/73912578

注意:读位置指针,也不会自动移动。但是如果读之前写过文件,指针会在后面,此时读不到写的内容,这时需配合lseek函数使用。

5.lseek函数原型
函数目的:调整读写的位置指针。

#include 
#include 

off_t lseek(int fd, off_t offset, int whence);

参数说明: fd - 当前文件的文件inode;
          offfset - 偏移量,每读写操作所移动的距离,单位是字节的数量。可正负;
		  whence - 当前位置的基点,有三个标志:
			①SEEK_SET:文件的开头;
			②SEEK_CUR:文件指针的当前位置;
			③SEEK_END:文件的结尾。  
返回值:-1时出错;成功时,文件指针的当前位置    

如果先对一个文件写入若干字节的内容后立即去读取的话, 是读不到刚写入的内容的,因为此时文件指针已经被 write 移动到了该内容后面。

三、文件IO例子

实现cp命令的实现例子

#include 
#include 
#include 
#include 	
int main(int argc, char *argv[])
{
	int  rd_fd, wr_fd;
	char read_buf[128] = {0};
	char write_buf[128] = {0};
	int rd_ret = 0;

	if(argc <3)
	{
		printf("please input src file and des file n");
		return -1;
	}

	rd_fd = open(argv[1],O_RDONLY);
	if(rd_fd < 0 )
	{
		printf("open src file %s failuren",argv[1])
		return -2;
	}
	wr_fd =  open (argv[2],O_WRONLY);
	if(wr_fd <0)
	{
		printf("open des file %s failuren",argv[2])
		return -3;
	}

	while(1)
	{
		rd_ret = read(rd_fd,read_buf,128);
		if(rd_ret < 128)
			break;
		write(wr_rd,read_buf,rd_ret);
		memset(wr_fd,read_buf,re_ret);
	}
	write(wr_rd,read_buf,rd_ret);

	close(rd_fd);	
	close(wr_fd);	
}
第二章 Linux中的标准IO 一、标准IO基本介绍

1.文件IO与标准IO的区别

  • (1)概念

    • 文件IO:文件I/O称之为不带缓存的IO。不带缓存指的是每个read,write都调用内核中的一个系统调用。头文件是unistd.h。
    • 标准IO是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准的IO提供了三种类型的缓存:全缓存、行缓存、不带缓存。
  • 区别

    • 两者一个显著的不同点在于,标准I/O默认采用了缓冲机制。标准 IO 其实是由文件 IO 封装而来的,其实就是在应用层加了一个缓冲机制。文件I/O读写文件时,每次操作都会执行相关系统调用,这样处理的好处是直接读写实际文件,坏处是频繁的系统调用会增加系统开销。而标准I/O可以看成是在文件I/O的基础上封装了缓冲机制。先读写缓冲区,必要时再访问实际文件,从而减少了系统调用的次数。
    • 文件I/O主要针对文件操作,读写硬盘等,它操作的是文件描述符;标准I/O针对的是控制台,打印输出到屏幕等,它操作的是字符流。对于不同设备得特性不一样,必须有不同api访问才最高效。

2.Linux常用的标准IO API

类型文件IO函数标准IO函数
打开openfopen
关闭closefclose
移位lseekfseek、rewind
读写read、write比较多,分为全缓存、航缓存和无缓存
读写类型文件IO函数标准IO函数
readgetc,fgetc,getchar,
writeputc,fputc,putchar,fputs,puts,fwrite
  • 文件打开关闭 :fopen、fclose
  • 文件读写: fread、fwrite
  • 从文件中读取/输出字符串:fgets、fputs
  • 获取、输出字符:gets、puts
  • 从文件中获取、输出字符:fgetc、fputc
  • 终端输出输入一个字符:getc、putc
  • 输出输入一个字符:getchar、putcahr
  • 格式化输入输出、从文件 :fscanf、fprintf
  • 从字符串:sscanf、sprintf
  • 从终端:scanf、printf
  • 冲刷缓存区(全缓冲、含缓冲):fflush
  • 光标定位:fseek ftell、rewind
  • 文件末尾:feof

3.标准IO缓存机制

  • 全缓冲
    只有在写满缓存时再进行I/O操作。注意,对于驻留在磁盘上的文件来说通常是由标准IO库实施全缓冲。

    读:fread 写:fwrite

  • 行缓冲
    在遇到新换行符n或写满缓存时,才会进行I/O操作。注意,当流涉及终端的时候,通常使用的是行缓冲。

    遇到换行符(n)或写满缓存时,调用系统调用函数:stdout
    读:fgets,gets,printf,fprintf,sprintf
    写:fputs,puts,scanf

  • 无缓冲
    无缓冲指的是标准IO库不对字符进行缓冲存储。注意,标准出错流stderr通常是无缓冲的。

    无缓存 stderr

二、标准IO函数原型

1.fopen、fclose函数原型

头文件:#include 
函数原型:
FILE *fopen(const char *path, const char *mode);
返回值: 成功  返回FILE * 类型的指针指向你要打开文件;
        失败  返回NULL。         
      
函数参数:const char *path  ----> 打开文件的位置 
		const char *mode  ----> 文件权限
			"b"     以二进制模式打开文件
			"r"     以只读的方式打开文件,文件必须存在
			"r+"    以可读可写的方式打开文件,文件必须存在
			"w"     以只写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
			"w+"    以可读可写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
			"a"     追加方式,如果文件不存在就新建 
			"a+"    以读取和追加(文件末尾的写入),如果文件不存在,则创建它。

补充:
fopen()函数创建的文件权限(umask=0)是666,和umask有关。默认情况下umask为022,666-022=644。

  • fclose
函数原型:
int fclose(FILE *fp);
返回值: 成功 返回0
		失败 返回feof()监测

函数参数:FILE *fp  文件描述符

注意: fclose会将缓存中的内容强制写入文件中,包含了fflush的功能。

2.fputs、fgets、fflush函数原型

  • fputs fgets:行缓存的读写函数
//从文件stream读取size个字节的数据放到指针s中
char *fgets(char *s, int size, FILE *stream);
返回值:如果成功返回读到的字符串的首地址指针s;否则,如果已处在文件尾端或出错为null

int puts(const char *s, FILE *stream);
返回值:如果成功返回非负值;否则,出错则为EROF -1
  • fflush :刷新缓冲区
int fflush(FILE *stream);

fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准],一般用不到;
fflush(stdout) 是行缓存,刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上;
stderr 是无缓存,会直接写到内核。

注意: 读写操作同样存在位置指针

3.gets、puts函数原型
gets、puts函数参考链接

gets、puts:行缓存的读写函数。

char *gets(char *s);  
int puts(const char *s);

gets和fgets的区别:

  • gets()不能指定缓存的长度,这样容易造成缓存越界(如果该行长于缓存长度),写到缓存之后的存储空间中,从而产生不可预估的后果;
  • 另一个区别,gets()并不将新行符存入缓存中,fgets将新行符存入缓存中。

puts和fputs的区别:

  • puts()只能向标准输出中写;
  • puts()输出时会添加一个新行符,fputs不会。

4.fseek、rewind、ftell函数原型
fseek、rewind、ftell函数参考链接

调整文件的读写位置。

int fseek(FILE *stream, long offset, int whence);
返回值:成功 返回0
		失败 返回-1  
注意:lseek和fseek函数输入参数相同,但返回值不一样
参数:FILE *stream  FILE * 文件
		long offset   偏移量
		int whence    偏移的位置
		SEEK_SET  文件的开头
		SEEK_CUR  当前的位置
		SEEK_END  文件的末尾   

long ftell(FILE *stream);
返回值:成功 返回文件当前位置距离文件开头的字节数
		失败 返回-1
			 
void rewind(FILE *stream);//将文件的偏移设置为起始位置,函数没有返回值

例子:

fseek(filep1,0,SEEK_SET);//将文件的偏移设置为起始位置
long ftell(filep1);相当于fseek(filep1,0,SEEK_END);
void rewind(filp1)//等价于fseek(filep1,0,SEEK_SET)

5.fprintf、fscanf、sprintf、sscanf、printf函数原型

printf 只能输出到显示器中。

1) fprintf:可以输出到文件中,也可输出到显示器。
int fprintf(FILE *stream, const char *format, ...);
参数:
	FILE *stream        FILE *  文件名
	const char *format  字符串
	...
例子:fprintf(filep,"hello%s%d%.2fn",buf,year,d);

2) sprintf:输出内容到一个字符串中。
int sprintf(char *str, const char *format, ...);
//按照你指定的格式拼接字符串,比strcat要厉害
参数:
	char *str           字符串拼接指定位置
	const char *format  字符串格式
	... 
例子:sprintf(buf0,"%sworld-%d-%d-%d",buf,year,month,day);

3)  int fscanf(FILE *stream, const char *format, ...);
参数:FILE *stream        FILE *  文件名
	const char *format  字符串
	... 往文件里面添加内容

4) int sscanf(const char *str, const char *format, ...);
	//按照你指定的格式拆分字符串
参数:
	char *str           字符串拆分指定位置
	const char *format   字符串格式
	... 
例子:sscanf(time,"%d-%d-%d",&year,&month,&day);//访问的是地址 &

6.fputc、fgetc、getc、putc函数原型
fgets,fputs,fputc,fgetc总结

fputc fgetc:一个字符读写函数。

int fgetc(FILE *stream);//从文件中读取一个字符,等价于fread(buf,1,1,stream);
返回值:你读取到的那个字符的ASCII码

int fputc(int c, FILE *stream);//往文件中写入一个字符 
参数说明:第一个参数为要写的字符,第二个参数为文件流。
返回值:成功则返回输入的字符,出错EOF。

int getc(FILE *stream);//从文件当中读取一个字符 
返回值:你读取到的那个字符的ASCII码

int putc(int c, FILE *stream);//往文件中写入一个字符  

注意:
fputc对于换行符也是可以读入的;fputc有缓存,但不是行缓存函数。
思考怎么通过代码验证???

7.getchar、putchar函数原型
调用getchar()相当于调用fgetc(stdin)。
调用putchar©相当于调用fputc(c, stdout)

#include 

int getchar(void);//监测缓冲区的回车字符     
int putchar(int c);  //打印字符 

8.feof、ferror、clearerr函数原型
feof、ferror、clearerr函数参考链接

feof 判断是否已经到文件结束;
ferror 判断是否读写错误;
clearerr 清除流错误。

int feof(FILE *stream);
函数功能:判断是否已经到文件结束。
返回值:到达文件结束,返回非0;没有则0

int ferror(FILE *stream);
函数功能:判断是否读写错误。

int clearerr(FILE *stream);
函数功能:清除流错误。

9.fstat函数原型
获取文件属性。

头文件:#include 

int fstat(int fildes, struct stat *buf);
返回值:成功  返回0
		失败  返回-1
参数:
	int fildes  你要获取属性的那个文件的文件描述符
	struct stat *buf 存放你获取到的文件属性

10.fread、fwrite函数原型
文件的全缓存读写。

头文件:#include 

函数原型:
	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
函数参数:void *ptr     ----> 存储空间名
			size_t size   ---->每一个数据块的大小 单位:字节
			size_t nmemb  ---->打算读取多少个数据块
			FILE *stream  ---->文件类型的FELE *的文件指针
返回值: 成功 返回读取到完整的数据块的个数
		失败 返回0或者小于的数
		判断文件是否读完不要在用返回值判断,新方式feof()判断

	size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

fwrite有缓存,不是行缓存,是全缓存。

三、标准IO例子

1.实现cat

#include "stdio.h"
#include "fcntl.h"
#include "unistd.h"
#include "string.h"
int main(int argc, char** argv)
{
	FILE *src_fp;
	int read_ret;
	if(argc < 2)
	{
		printf("please input src filen");
		return -1;
	}

	src_fp=fopen(argv[1],"r");
	if(src_fp ==NULL)
	{
		printf("open src file %s failuren",argv[1]);
		return -1;
	}
	printf("open drc file %s sucessn",argv[1]);

	// start read write
	while(1)
	{
		read_ret = fgetc(src_fp);
		if(feof(src_fp))
		{
			printf("read file %s endn",argv[1]);
			break;
		}
		fputc(read_ret,stdout); 
	}
	fclose(src_fp);
	return 0;
}

2.比较read/write,fgetc/fputc效率
文件io

// read.c
#include 
#include 
#include 
#include 
int main(int argc,char **argv)
{
	int src_fd,des_fd;
	int read_ret=0;
	char buf[128]={0};
	if(argc <3)
	{
		printf("please input src and des filen");
		return -1;
	}
	src_fd = open(argv[1],O_RDONLY);
	if(src_fd<0)
	{
		printf("open src file %s failuren",argv[1]);
		return -2;
	}
	printf("open src file %s sucessn",argv[1]);

	des_fd=open(argv[2],O_CREAT | O_WRONLY,0777);
	if(des_fd<0)
	{
		printf("open des file %s failuren",argv[2]);
		return -3;
	}
	printf("open des file %s sucessn",argv[2]);

	//start resd write
	while(1)
	{
		read_ret=read(src_fd,buf,128);
		write(des_fd,buf,read_ret);
		if(read_ret<128)
		{
			printf("raed file %s end!n",argv[1]);
			break;
		}
	}
	write(des_fd,buf,read_ret);
	close(src_fd);
	close(des_fd);	

	return 0;
}

标准io函数

//fgetc.c
#include 
#include 
#include 
#include 
int main(int argc,char **argv)
{
	FILE *src_fp,*des_fp;
	int read_ret=0;
	if(argc <3)
	{
		printf("please input src and des filen");
		return -1;
	}
	src_fp = fopen(argv[1],"r");
	if(src_fp==NULL)
	{
		printf("open src file %s failuren",argv[1]);
		return -2;
	}
	printf("open src file %s sucessn",argv[1]);

	des_fp=fopen(argv[2],"w");
	if(des_fp==NULL)
	{
		printf("open des file %s failuren",argv[2]);
		return -3;
	}
	printf("open des file %s sucessn",argv[2]);

	//start resd write
	while(1)
	{
		read_ret=fgetc(src_fp);
		fputc(read_ret,des_fp);
		if(feof(src_fp))
		{
			printf("raed file %s end!n",argv[1]);
			break;
		}
	}
	fclose(src_fp);
	fclose(des_fp);	

	return 0;
}
类型read/writefgetc/fputc
real0.131s0.533s
user0.016s0.366s
sys0.115s0.134s

3.比较fgets/fputs、fread/fwrite效率

//fgets.c
#include 
#include 
#include 
#include 
int main(int argc,char **argv)
{
	FILE *src_fp,*des_fp;
	int read_ret=0;
	char readbuf[128]={0};
	if(argc <3)
	{
		printf("please input src and des filen");
		return -1;
	}
	src_fp = fopen(argv[1],"r");
	if(src_fp==NULL)
	{
		printf("open src file %s failuren",argv[1]);
		return -2;
	}
	printf("open src file %s sucessn",argv[1]);

	des_fp=fopen(argv[2],"w");
	if(des_fp==NULL)
	{
		printf("open des file %s failuren",argv[2]);
		return -3;
	}
	printf("open des file %s sucessn",argv[2]);

	//start resd write
	while(1)
	{
		fgets(readbuf,128,src_fp);
		fputs(readbuf,des_fp);
		if(feof(src_fp))
		{
			printf("raed file %s end!n",argv[1]);
			break;
		}
	}
	fclose(src_fp);
	fclose(des_fp);	

	return 0;
}
//fread.c
#include 
#include 
#include 
#include 
int main(int argc,char **argv)
{
	FILE *src_fp,*des_fp;
	int read_ret=0;
	char readbuf[128]={0};
	if(argc <3)
	{
		printf("please input src and des filen");
		return -1;
	}
	src_fp = fopen(argv[1],"r");
	if(src_fp==NULL)
	{
		printf("open src file %s failuren",argv[1]);
		return -2;
	}
	printf("open src file %s sucessn",argv[1]);

	des_fp=fopen(argv[2],"w");
	if(des_fp==NULL)
	{
		printf("open des file %s failuren",argv[2]);
		return -3;
	}
	printf("open des file %s sucessn",argv[2]);

	//start resd write
	while(1)
	{
		read_ret=fread(readbuf,1,128,src_fp);
		fwrite(readbuf,1,read_ret,des_fp);
		if(read_ret<128)
		{
			printf("raed file %s end!n",argv[1]);
			break;
		}
	}
	fwrite(readbuf,1,read_ret,des_fp);
	fclose(src_fp);
	fclose(des_fp);	

	return 0;
}

类型read/write(上一节例子)fgetc/fputc(上一节例子)fgets/fputsfread/fwrite
real0.131s0.533s0.059s0.049s
user0.045s0.366s0.006s0.011s
sys0.087s0.134s0.052s0.008s

故效率,fread/fwrite > fgets/fputs > fgetc/fputc。

第三章 目录IO 一、目录IO基本介绍

1.头文件及常用的IO API

  • 头文件
    #include 
    #include 
    
  • 目录IO与文件IO的比较
二、文件IO函数原型

1.mkdir函数原型
新建目录。

#include 
函数原型:
	int mkdir(const char *path, mode_t mode);
参数:
	const char *path  ----》欲创建的目录文件路径
	mode_t mode      ----》新建文件的权限 0777

注意:生成的目录权限仍和umask有关系,默认umask=0022.

2.opendir、closedir函数原型
目录的打开、关闭。

#include 
#include 
函数原型:
	DIR *opendir(const char *name);
返回值:
	成功 返回DIR类型的指针指向你打开的目录
	失败 返回NULL
参数:
	const char *name 完整的目录路径
返回值:
	成功返回目录流指针,出错返回NULL。

int closedir(DIR *dirp);//结构体指针

3.readdir函数原型
目录的读取。

#include 

struct dirent *readdir(DIR *dirp);
返回值:成功则为struct dirent指针,若在目录尾或出错则返回NULL。

dirent结构体定义在头文件dirent.h中:
struct dirent {
		ino_t          d_ino;       
		off_t          d_off;       
		unsigned short d_reclen;    
		unsigned char  d_type;      
		char           d_name[256]; 
};//存放的是目录当中的每个文件的相关信息

文件类型d_type判断:
	DT_BLK      This is a block device. //块设备文件

	DT_CHR      This is a character device.//字符设备文件

	DT_DIR      This is a directory.//目录文件

	DT_FIFO     This is a named pipe (FIFO).//管道文件

	DT_LNK      This is a symbolic link.//软连接文件

	DT_REG      This is a regular file.//普通问价

	DT_SOCK     This is a UNIX domain socket.//套接字文件

	DT_UNKNOWN  The file type is unknown.//不认识类型

4.rewinddir函数原型
重置读取目录流的位置为开头

void rewinddir(DIR *dr);  
参数:目录流指针

5.telldir函数原型
获取当前位置指针的位置

long telldir(DIR *dirp)  
函数说明:telldir()返回参数dir 目录流目前的读取位置. 此返回值代表距离目录文件开头的偏移量返回值返回下个读取位置, 有错误发生时返回-1.

6.seekdir函数原型
可以定位到任意位置。类似于文件定位函数fseek(),在目录流上设置下一个readdir()操作的位置。

void seekdir(DIR *dirp , long loc)   
函数说明:seekdir()用来设置参数dir 目录流目前的读取位置, 在调用readdir()时便从此新位置开始读取. 参数offset 代表距离目录文件开头的偏移量
三、目录IO例子
#include 
#include 
#include 
int main()
{
    DIR * dir;
    struct dirent * ptr;
    int i;
    dir = opendir("/etc/rc.d");
    while((ptr = readdir(dir))!= NULL)//链表遍历
    {
        printf("d_name : %sn", ptr->d_name);
    }
    closedir(dir);
	return 0;
}
综合例子

单机模式下的文件上传与下载
(1) 输入服务器的地址: 路径和目录名
(2) 列出服务器中有哪些文件: opendir readdir
(3) 输入从服务器下载的文件名 或 上传文件到服务器的文件名
(4) 文件下载 或 文件上传送

文件IO: open read write close
标准IO fopen fputs fgets fputc fgetc fread fwrite fclose

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc,char **argv)
{
	DIR *dp;
	struct dirent * dir;
	char server[128]={0};
		
	int fd;
	char file[128]={0};
	int src_fd,des_fd;
	char buf[128]={0};
	int ret;

start:
	printf("please input server PATH and Directory namen");
	scanf("%s",server);

	//list server fildes
	dp = opendir(server);
	if(dp==NULL)
	{
		printf("open server %s errorn",server);
		goto start;
	}
	printf("open server %s successn",server);

	//read server dir
	while(1)
	{
		dir = readdir(dp);
		if(dir==NULL)
		{
			break;
		}
		else
		{
			printf("inode=%ld name =%sn",dir->d_ino,dir->d_name);
		}
	}

	printf("please input download file namen");
	scanf("%s",file);

	//open server file
	src_fd = open(strcat(strcat(server,"/"),file),O_RDONLY);
	if(src_fd<0)
	{
		printf("open download file %s failuren",file);
		return -1;
	}
	printf("open download file %s successn",file);

	des_fd=open(file,O_CREAT | O_WRONLY);
	if(des_fd < 0)
	{
		printf("create file %s errorn",file);
		return -2;
	}
	printf("create file %s successn",file);

	while(1)
	{
		ret=read(src_fd,buf,128);
		write(des_fd,buf,ret);
		if(ret < 128){
			break;
		}
	}
	write(des_fd,buf,ret);
	close(des_fd);
	close(src_fd);
	closedir(dp);

	return 0;
}
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/276019.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号