总结文件操作函数-文件夹(三)-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)

推断是否是文件夹

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

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!\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);
}

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!\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;
}
上一篇:Nagios 监控windows server Apache 服务


下一篇:Python全栈开发记录_第三篇(linux(ubuntu)的操作)