总结文件操作函数-目录(三)-C语言

获取、改变当前目录:

原型为:

#include <unistd.h>   //头文件

char *getcwd(char *buf, size_t size); //获取当前目录,相当于pwd命令

int chdir(const char *path); //修改当前目录,即切换目录,相当于cd命令

其中getcwd()函数:将当前的工作目录绝对路径复制到参数buf所指的内存空间,参数size为buf的空间大小. 在调用此函数时,buf所指的内存空间要足够大,若工作目录绝对路径的字符串长度超过参数size大小,则回值NULL,errno的值则为ERANGE。倘若参数buf为NULL,getcwd()会依参数size的大小自动配置内存(使用malloc()),如果参数size也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完此字符串后自动利用free()来释放此空间。所以常用的形式:getcwd(NULL, 0);

#include<unistd.h>
main()
{
chdir(“/tmp”);
printf(“current working directory: %s\n”,getcwd(NULL,0));
}

获取目录信息:

原型为:

#include <sys/types.h>

#include <dirent.h>

DIR *opendir(const char *name); //打开一个目录

struct dirent *readdir(DIR *dir); //读取目录的一项信息,并返回该项信息的结构体指针

void rewinddir(DIR *dir); //重新定位到目录文件的头部

void seekdir(DIR *dir,off_t offset);//用来设置目录流目前的读取位置

off_t telldir(DIR *dir); //返回目录流当前的读取位置

int closedir(DIR *dir); //关闭目录文件

读取目录信息的步骤为:

用opendir函数打开目录;

使用readdir函数迭代读取目录的内容,如果已经读取到目录末尾,又想重新开始读,则可以使用rewinddir函数将文件指针重新定位到目录文件的起始位置;

用closedir函数关闭目录

opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,和文件操作函数open()类似,接下来对目录的读取和搜索都要使用此返回值。函数失败则返回NULL;

readdir()函数用来读取目录的信息,并返回一个结构体指针,该指针保存了目录的相关信息。有错误发生或者读取到目录文件尾则返回NULL。

dirent结构体如下:

struct dirent
{
	ino_t  d_ino;	          /* inode number(此目录进入点的inode) */
	off_t  d_off;             /* offset to the next dirent(目录开头到进入点的位移 */
	unsigned short d_reclen;  /* length of this record(目录名的长度) */
	unsigned char d_type;     /* type of file(所指的文件类型) */
	char   d_name[256];       /* filename(文件名) */
};

获取文件信息:

可以通过fstat和stat函数获取文件信息,调用完毕后,文件信息被填充到结构体struct stat变量中,函数原型为:

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

int stat(const char *file_name, struct stat *buf);   //文件名  通过文件名获取文件各种属性

经常与opendir(),readdir()结合使用

int fstat(int fd, struct stat *buf);   //文件描述词   stat结构体指针

结构体stat的定义为:

	struct stat {
           dev_t         st_dev;      /*如果是设备,返回设备表述符,否则为0*/
           ino_t         st_ino;      /* i节点号 */
           mode_t        st_mode;     /* 文件类型 */
           nlink_t       st_nlink;    /* 链接数 */
           uid_t         st_uid;      /* 属主ID */
           gid_t         st_gid;      /* 组ID */
           dev_t         st_rdev;     /* 设备类型*/
           off_t         st_size;     /* 文件大小,字节表示 */
           blksize_t     st_blksize;  /* 块大小*/
           blkcnt_t      st_blocks;   /* 块数 */
           time_t        st_atime;    /* 最后访问时间*/
           time_t        st_mtime;    /* 最后修改时间*/
           time_t        st_ctime;    /* 创建时间 */
    };

以上的函数结合使用模拟一个ls -l的功能

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
void mode_to_str(mode_t md, char* str) ;
void format(char* p) ;
int main(int argc, char* argv[])
{
	DIR* pDir ;
	char* ptm ;
	struct stat mystat ;
	struct dirent* myent;
	char str_mode[11]="";
	int col = 0 ;
	if(argc == 1)
	{
		pDir = opendir(".");
	}else
	{
		pDir = opendir(argv[1]);
	}
	if(pDir == NULL)
	{
		perror("open dir fail: ");
		exit(-1);
	}
	printf("nlink,mode,uid,gid,size,atime,name\n");
	while( (myent = readdir(pDir) ) != NULL )
	{
		memset(&mystat, 0, sizeof(mystat));
		stat(myent ->d_name, &mystat);
		memset(str_mode,0, 11);
		mode_to_str(mystat.st_mode,str_mode);
		ptm = ctime(&mystat.st_atime);
		format(ptm);
		if(strncmp(myent ->d_name, ".",1) !=0 && strncmp(myent->d_name,"..",2)!=0)
		{
			printf("%10s.%2d %-5s %-5s %5d %s %s\n",str_mode,mystat.st_nlink,getpwuid(mystat.st_uid)->pw_name,getgrgid(mystat.st_gid)->gr_name,mystat.st_size,ptm+4,myent ->d_name);
		}
	}
	printf("\n");
	return  0 ;
}

void mode_to_str(mode_t md, char* str)
{
	strcpy(str,"----------");
	if(S_ISDIR(md))
	{
		str[0]='d';
	}
	if(md & S_IRUSR)
	{
		str[1] ='r';
	}
	if(md & S_IWUSR)
	{
		str[2]='w';
	}
	if(md & S_IXUSR)
	{
		str[3] = 'x' ;
	}

	if(md & S_IRGRP)
	{
		str[4] ='r';
	}
	if(md & S_IWGRP)
	{
		str[5]='w';
	}
	if(md & S_IXGRP)
	{
		str[6] = 'x' ;
	}

	if(md & S_IROTH)
	{
		str[7] ='r';
	}
	if(md & S_IWOTH)
	{
		str[8]='w';
	}
	if(md & S_IXOTH)
	{
		str[9] = 'x' ;
	}
}
void format(char* p)
{
	while(*p)
	{
		p++ ;
	}
	while(*p != ':')
	{
		p-- ;
	}
	*p = '\0';
}

S_ISDIR(mode)


判断是否是目录

最后有一个总结性性的程序

客户端发送文件名 或者目录 到服务器, 服务器读出当前目录或者对应文件的的内容

发送给客户端。使用TCP和创建线程处理请求。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <fcntl.h>
#include <pthread.h>
#include <dirent.h>
#define IP "192.168.1.61"
#define PORT 8888
int fd_sever,fd_client;
void *read_func(void *arg);
int main(int argc,char *argv[])
{
	pthread_t tid;
	signal(13,SIG_IGN);
	//socket当作文件
	fd_sever=socket(AF_INET,SOCK_STREAM,0);//协议不用管,会自己判断ipv4,
	if(fd_sever==-1)
	{
		perror("socket failed!\n");
		exit(-1);
	}
	//绑定,端口号IP绑定到socket
	struct sockaddr_in sever_addr;
	memset(&sever_addr,0,sizeof(sever_addr));
	sever_addr.sin_family=AF_INET;
	sever_addr.sin_port=htons(PORT);//小端转大端
	sever_addr.sin_addr.s_addr=inet_addr(IP);//网络字节序
	if(bind(fd_sever,(const struct sockaddr *)&sever_addr,sizeof(sever_addr))==-1)
	{
		perror("bind\n");
		close(fd_sever);
		exit(-1);
	}
	//监听,设置为监听状态,第二个参数为监听人数,来请求放入监听队列,可放五人
	if(listen(fd_sever,5)==-1)
	{
		perror("listen\n");
		close(fd_sever);
		exit(-1);
	}
	//从监听队列获取请求,返回客户端描素福,与对面联系。取出连接
	struct sockaddr_in client_addr;
	int len=sizeof(client_addr);

	fd_client=accept(fd_sever,(struct sockaddr *)&client_addr,&len);
	//recv ,对面先发则先收read也可以,sever只负责取连接,
	char buf[1024]="";
//	int recv_n=recv(fd_client,buf,1024,0);
	while(recv(fd_client,buf,1024,0)>0)
	{
	printf("%s\n",buf);
	pthread_create(&tid,NULL,read_func,(void *)buf);
	}
	printf("ok\n");
	//printf("recv from IP :%s\n Msg:%s\nLen:%d\n",inet_ntoa(client_addr.sin_addr),recv_buf,recv_n);
	//int send_n=send(fd_client,recv_buf,recv_n,0);
	//printf("send from IP :%s:%d\nMsg:%s\nLen:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),recv_buf,send_n);

	close(fd_sever);
	close(fd_client);

	return 0;
}
void *read_func(void *arg)
{
	char *p=(char *)arg;
	printf("arg:%s\n",(char *)arg);
	pthread_detach(pthread_self());//系统回收资源
	int pid,fd_write,fd_path,n,index=0;
	//char cpid[1024]="";
	char path[1024]="";
	//char fifo_write[1024]="";
	char buf[1024];
	DIR *Pdir;
	struct dirent *myent;
	//printf("p = %s\n",p);
	sscanf(p,"%s",path);
	//pid=atoi(cpid);
	//index=strlen(cpid)+1;
	//printf("index=%d\n",index);
	//printf("pid = %d\n",pid);
	//sscanf(p+index,"%s",path);//文件
	printf("path:%s\n",path);
	//sprintf(fifo_write,"%d_read.fifo",pid);//客户端读管道,系统成为写管道
	//fd_write=open(fifo_write,O_WRONLY);
	n=chdir(path);
	if(n==0)//目录
	{
		printf("n=%d\n",n);
		Pdir=opendir(path);
		while((myent=readdir(Pdir))!=NULL)
		{
			printf("pname=%s\n",myent->d_name);
			fd_path=open(myent->d_name,O_RDONLY);
			while(memset(buf,0,1024),read(fd_path,buf,1024)>0)
			{
				write(fd_client,buf,strlen(buf));
			}
		}
	}
	else//文件
	{
		fd_path=open(path,O_RDONLY);
		while(memset(buf,0,1024),read(fd_path,buf,1024)>0)
		{
	//	printf("fd_path:%s\n",buf);
			write(fd_client,buf,strlen(buf));
		}
	}
		close(fd_path);
}

客户端主要是与服务器建立连接

发送请求

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#define SEVER_PORT 8888
#define SEVER_IP "192.168.1.61"
int main(int argc,char *argv[])
{
	int fd_client;
	struct sockaddr_in sever_addr;
	memset(&sever_addr,0,sizeof(struct sockaddr_in));
	fd_client=socket(AF_INET,SOCK_STREAM,0);
	if(fd_client==-1)
	{
		perror("socket!\n");
		exit(-1);
	}
	sever_addr.sin_family=AF_INET;
	sever_addr.sin_port=htons(SEVER_PORT);
	sever_addr.sin_addr.s_addr=inet_addr(SEVER_IP);
	connect(fd_client,(struct sockaddr*)&sever_addr,sizeof(sever_addr));
	printf("connecting!\n");
	char *p="/home/study/0701";
	send(fd_client,p,strlen(p),0);
	char buf[1024]="";
	while(memset(buf,0,1024),read(fd_client,buf,1024))
	{
		//printf("%s\n",buf);
		write(1,buf,strlen(buf));
		fflush(stdout);
	//	send(fd_client,buf,strlen(buf),0);
	}
	//int recv_n=recv(fd_client,buf,1024,0);
	//printf("recv from ip:port %s:%d\nMsg:%s\nlen=%d\n",inet_ntoa(sever_addr.sin_addr),ntohs(sever_addr.sin_port),buf,recv_n);

	close(fd_client);
	return 0;
}

总结文件操作函数-目录(三)-C语言

时间: 2024-10-05 00:29:47

总结文件操作函数-目录(三)-C语言的相关文章

总结文件操作函数(一)-C语言

在进程一开始运行,就自动打开了三个对应设备的文件,它们是标准输入.输出.错误流,分别用全局文件指针stdin.stdout.stderr表示,对应的文件描述符为0,1,2:stdin具有可读属性,缺省情况下是指从键盘的读取输入,stdout和stderr具有可写属性,缺省情况下是指向屏幕输出数据. 将文件路径转化为文件指针: #include <stdio.h>  //头文件包含 FILE *fopen(const char *pach,const char *mode);  //文件名  模

总结文件操作函数(二)-C语言

格式化读写: #include <stdio.h> int printf(const char *format, ...);                   //相当于fprintf(stdout,format,-); int scanf(const char *format, -); int fprintf(FILE *stream, const char *format, ...);      //中间的参数为写入文件的格式 int fscanf(FILE *stream, const

C语言样式的文件操作函数

使用C语言样式的文件操作函数,需要包含stdio.h头文件. 1.打开文件的函数: 1 //oflag的取值为“w”或“r”,分别表示以写或读的方式打开 2 FILE* fd = fopen(filename.c_str(), oflag); 2.写文件的函数原型: size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream ); 其中buffer是需要向文件中写入的内容在内存中的首地址指针,size是待写入

C语言文件操作函数的编写

 编写文件操作的头文件 /************************************************************************** Copyright(C)    :2014-08-5 toto Filename       :file.h Author          :涂作权 Version         :V1.1 Date            :2014-08-05 Description     :文件操作的头文件 Others  

c语言文件操作函数

c语言文件操作函数大全 fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const char * mode); 函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态. mode有下列几种形态字符串: r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须存在. w 打开只写文件,若文件存在则文件长度清为0,即该文件

C语言文件操作函数大全(超详细)

C语言文件操作函数大全(超详细) 作者: 字体:[增加 减小] 类型:转载 本篇文章是对C语言中的文件操作函数进行了详细的总结分析,需要的朋友参考下 fopen(打开文件)相关函数 open,fclose表头文件 #include<stdio.h>定义函数 FILE * fopen(const char * path,const char * mode);函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态.mode有下列几种形态字符串:r 打开只读文件,

LINUX/UNIX的文件操作函数

本文用于记录在LINUX编程中,常用的文件操作函数,包括系统调用和库函数,以备查阅. 针对输入输出操作,直接使用底层系统调用的一个问题是它们的效率十分低,原因在于: 1.使用系统调用会影响系统的性能,与函数调用相比,系统调用的开销要大些,因为在执行系统调用时,Linux必须从运行用户代码切换到执行内核代码,然后再返回用户代码. 2.硬件会限制对底层系统调用一次所能读写的数据块大小.比如,磁带机通常一次能写的数据块长度是10K,所以若你试图写的数据量不是10K的整数倍,磁带机还是以10K为单位卷绕

【阅读笔记】《C程序员 从校园到职场》第六章 常用文件操作函数 (Part 1)

参考链接:https://blog.csdn.net/zhouzhaoxiong1227/article/details/24926023 让你提前认识软件开发(18):C语言中常用的文件操作函数总结及使用方法演示代码 - CSDN博客 Contents: 1. C语言中常用的文件操作函数总结 (1) fopen   作用:打开文件 (2) fclose  作用:关闭文件 (3) fgetc   作用:由文件中读取一个字符. (4) fgets   作用:由文件中读取一字符串. (5) fflu

文件操作函数及文件流详解

这几天着重研究了一下文件操作函数的原理及实现,在这里与大家分享一下----开心 1.文件流 2.几种文件操作函数 (1)  fopen (2) fclose (3)fread (4)fwrite (5)fgets (6)fputs 先来看FILE结构体: #ifndef _FILE_DEFINED struct _iobuf { char *_ptr;//文件缓存的当前位置 int _cnt;//缓存里可以读取的字节数 char *_base;//文件缓存的起始位置 int _flag; int