zoukankan      html  css  js  c++  java
  • 总结文件操作函数-文件夹(三)-C语言

    获取、改变当前文件夹:

    原型为:

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

    char *getcwd(char *buf, size_t size); //获取当前文件夹。相当于pwd命令

    int chdir(const char *path); //改动当前文件夹。即切换文件夹。相当于cd命令

    当中getcwd()函数:将当前的工作文件夹绝对路径拷贝到參数buf所指的内存空间,參数sizebuf的空间大小. 在调用此函数时,buf所指的内存空间要足够大,若工作文件夹绝对路径的字符串长度超过參数size大小。则回值NULLerrno的值则为ERANGE。倘若參数bufNULLgetcwd()会依參数size的大小自己主动配置内存(使用malloc()),假设參数size也为0,则getcwd()会依工作文件夹绝对路径的字符串程度来决定所配置的内存大小,进程能够在使用完此字符串后自己主动利用free()来释放此空间。所以经常使用的形式:getcwd(NULL, 0);


    #include<unistd.h>
    main()
    {
    chdir(“/tmp”);
    printf(“current working directory: %s
    ”,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(文件名称) */
    };


    获取文件信息:

    能够通过fstatstat函数获取文件信息,调用完成后,文件信息被填充到结构体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
    ");
    	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
    ",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("
    ");
    	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 = '';
    }

    S_ISDIR(mode)

    推断是否是文件夹



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

    client发送文件名称 或者文件夹 到server, server读出当前文件夹或者相应文件的的内容

    发送给client。使用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!
    ");
    		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
    ");
    		close(fd_sever);
    		exit(-1);
    	}
    	//监听,设置为监听状态,第二个參数为监听人数,来请求放入监听队列。可放五人
    	if(listen(fd_sever,5)==-1)
    	{
    		perror("listen
    ");
    		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
    ",buf);
    	pthread_create(&tid,NULL,read_func,(void *)buf);
    	}
    	printf("ok
    ");
    	//printf("recv from IP :%s
     Msg:%s
    Len:%d
    ",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
    Msg:%s
    Len:%d
    ",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
    ",(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
    ",p);
    	sscanf(p,"%s",path);
    	//pid=atoi(cpid);
    	//index=strlen(cpid)+1;
    	//printf("index=%d
    ",index);
    	//printf("pid = %d
    ",pid);
    	//sscanf(p+index,"%s",path);//文件
    	printf("path:%s
    ",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);
    		Pdir=opendir(path);
    		while((myent=readdir(Pdir))!=NULL)
    		{
    			printf("pname=%s
    ",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
    ",buf);
    			write(fd_client,buf,strlen(buf));
    		}
    	}
    		close(fd_path);
    }
    

    client主要是与server建立连接

    发送请求

    #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!
    ");
    		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!
    ");
    	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
    ",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
    Msg:%s
    len=%d
    ",inet_ntoa(sever_addr.sin_addr),ntohs(sever_addr.sin_port),buf,recv_n);
    
    	close(fd_client);
    	return 0;
    }
    








  • 相关阅读:
    mysql 组合聚集函数
    mysql distinct()函数 去重
    mysql sum()函数 , 计算总和
    mysql max()函数,min()函数,获取最大值以及最小值
    mysql count() 函数,对结果统计计数
    三个实例演示 Java Thread Dump 日志分析
    借助LVS+Keepalived实现负载均衡
    配置Tomcat成为系统服务
    快速理解Docker
    tomcat 启动时设置 java 参数,mark
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5097159.html
Copyright © 2011-2022 走看看