标准IO和目录操作

1. 标准文件IO

1.1 知识点

标准IO和目录操作_第1张图片

2. fopen和fwrite、fread

标准IO和目录操作_第2张图片

标准IO和目录操作_第3张图片

2.1 使用fwrite和fread实现文件的拷贝

fcopy.c
#include 
#include 
#include 
//使用fwrite和fread实现文件的拷贝

int main()
{
	FILE *fp1 = fopen("./2.txt","r");
    if(fp1 == NULL)
	{
		perror("open 1.txt failed");
		return -1;
	}
    FILE *fp2 = fopen("./3.txt","w");
    if(fp2 == NULL)
	{
		perror("open 1.txt failed");
		return -1;
	}
	
	
	char *buf = calloc(5,20);
	
	while(1)
	{

		int start = ftell(fp1);//获取偏移量
		memset(buf,0,5*20);//清空
		size_t n = fread(buf,20,5,fp1);//1.数据块读满了,n == 4,文件没读完, n==3//装不满一块数据块,数据块个数为0		
        if(n == -1)//结束
		{
			perror("fread failed");
			return -1;
		}

        if(n == 5)//满了,文件不一定读完了
		{
            fwrite(buf,20,5,fp2);
		}
		
		if(n < 5)//结束
		{
            int end = ftell(fp1);

			fwrite(buf,end-start,1,fp2);
            fclose(fp1);
            fclose(fp2);
            break;
		}	
		
	}

    // while(fread(buf,1,1,fp1))
	// {

    //     fwrite(buf,1,1,fp2);
	// 	memset(buf,0,5*20);//清空
		
	// }
    // fclose(fp1);
    // fclose(fp2);

    return 0;
	
}

2. 目录和文件操作

2.1 知识点

现在来看看,对于一个目录而言,我们是怎么处理的。其实操作目录跟标准 IO 函数操 作文件类似,也是先获得“ 目录指针”,然后读取一个个的“目录项”。用到的接口函数是:

标准IO和目录操作_第4张图片

2.2  打开目录,查看普通文件

dir.c

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

/*
struct dirent
{
ino_t d_ino; // 文件索引号
off_t d_off; //  目录项偏移量
unsigned short d_reclen; // 该目录项大小
unsigned char d_type; // 文件类型
char d_name[256]; // 文件名
};

*/

int main(int argc, char **argv)
{
	DIR *dir = opendir(argv[1]);
	
	struct dirent *ep; 
	
	while(1)
	{
		ep = readdir(dir);//每一个目录项都会获得一个指向目录项结构体的指针ep,直到ep为空
		if(ep == NULL)
		{
			break;
		}
		if(ep->d_type == DT_REG)
		{
			printf("%s\n",ep->d_name);
		}
		
	}
	
	closedir(dir);
	
}

标准IO和目录操作_第5张图片

2.3 递归删除目录

my_rm.c

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


void myrm(char *path)//路径
{
	DIR *dir = opendir(path);//获取目录指针
	
	char pathname[128] = {0};//存放路径
	
	struct dirent *ep;
	
	while(1)
	{
		//读取目录
		ep = readdir(dir);//每一个目录项都会获得一个指向目录项结构体的指针ep,直到ep为空
		if(ep == NULL)
		{
			break;
		}
		
		//绕开两个隐藏的目录项.和.. ,用字符串比较函数strcmp(),和ep->name比较,如果相同,continue
		if(strcmp(ep->d_name,".") == 0 || strcmp(ep->d_name,"..") == 0)
		{
			continue;
		}
		
		//普通文件
		if(ep->d_type == DT_REG)
		{
			//argv[1]目录名称+文件名ep->d_name
			//把ep->d_name和argv[1]贴到一个pathname
			//举例
			// /mnt/hgfs/qianrushi230901/read.c   
			snprintf(pathname,sizeof(pathname),"%s/%s",path,ep->d_name);
			printf("贴好的文件路径:%s\n",pathname);													
			unlink(pathname);//删除文件
		}
		
		//目录
		if(ep->d_type == DT_DIR)
		{
			//argv[1]目录名称+文件名ep->d_name
			//把ep->d_name和argv[1]贴到一个pathname
			//举例
			// /mnt/hgfs/qianrushi230901/read 
			snprintf(pathname,sizeof(pathname),"%s/%s",path,ep->d_name);
			printf("贴好的目录路径:%s\n",pathname);

			myrm(pathname);//进入递归
		}
		rmdir(pathname);//删除目录
		
	}
	
	//关闭
	closedir(dir);
}


int main(int argc, char **argv)
{
	
	myrm(argv[1]);
	
}

3. 读取一行数据fgets

标准IO和目录操作_第6张图片

标准IO和目录操作_第7张图片

值得注意的有以下几点:

1 ,fgets( )跟 fgetc( )一样,当其返回 NULL 时并不能确定究竟是达到文件末尾还是碰 到错误,需要用 feof( )/ferror( )来进一步判断。

2,fgets( )每次读取至多不超过 size 个字节的一行,所谓“一行”即数据至多包含一个 换行符’\n’。

3,gets( )是一个已经过时的接口,因为他没有指定自定义缓冲区s 的大小,这样很容 易造成缓冲区溢出,导致程序段访问错误。

4,fgets( )和 fputs( ),gets( )和 puts( )一般成对使用,鉴于 gets( )的不安全性,一般 建议使用前者。

你可能感兴趣的:(Linux下的文件IO,linux,c语言)