3:目录文件的操作 在我们编写程序的时候,有时候会要得到我们当前的工作路径。C库函数提供了getcwd来解决这个问题。 #include
char *getcwd(char *buffer,size_t size);
我们提供一个size大小的buffer,getcwd会把我们当前的路径考到buffer中.如果buffer太小,函数会返回-1和一个错误号. Linux提供了大量的目录操作函数,我们学习几个比较简单和常用的函数. #include #include #include #include #include
int mkdir(const char *path,mode_t mode); DIR *opendir(const char *path); struct dirent *readdir(DIR *dir); void rewinddir(DIR *dir); off_t telldir(DIR *dir); void seekdir(DIR *dir,off_t off); int closedir(DIR *dir);
struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[NAME_MAX+1]; /* 文件名称 */
mkdir很容易就是我们创建一个目录,opendir打开一个目录为以后读做准备.readdir读一个打开的目录.rewinddir是用来重读目录的和我们学的rewind函数一样.closedir是关闭一个目录.telldir和seekdir类似与ftee和fseek函数. 下面我们开发一个小程序,这个程序有一个参数.如果这个参数是一个文件名,我们输出这个文件的大小和最后修改的时间,如果是一个目录我们输出这个目录下所有文件的大小和修改时间.
#include #include #include #include #include #include #include
static int get_file_size_time(const char *filename) { struct stat statbuf;
if(stat(filename,&statbuf)==-1) { printf("Get stat on %s Error:%s/n", filename,strerror(errno)); return(-1); }
if(S_ISDIR(statbuf.st_mode))return(1); if(S_ISREG(statbuf.st_mode)) printf("%s size:%ld bytes/tmodified at %s", filename,statbuf.st_size,ctime(&statbuf.st_mtime));
return(0); }
int main(int argc,char **argv) { DIR *dirp; struct dirent *direntp; int stats;
if(argc!=2) { printf("Usage:%s filename/n/a",argv[0]); exit(1); }
if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1);
if((dirp=opendir(argv[1]))==NULL) { printf("Open Directory %s Error:%s/n", argv[1],strerror(errno)); exit(1); }
while((direntp=readdir(dirp))!=NULL) if(get_file_size_time(direntp-br> closedir(dirp); exit(1); }
4:管道文件 Linux提供了许多的过滤和重定向程序,比如more cat 等等.还提供了< > | <<等等重定向操作符.在这些过滤和重 定向程序当中,都用到了管道这种特殊的文件.系统调用pipe可以创建一个管道. #include
int pipe(int fildes[2]);
pipe调用可以创建一个管道(通信缓冲区).当调用成功时,我们可以访问文件描述符fildes[0],fildes[1].其中fildes[0]是用来读的文件描述符,而fildes[1]是用来写的文件描述符. 在实际使用中我们是通过创建一个子进程,然后一个进程写,一个进程读来使用的. 关于进程通信的详细情况请查看进程通信
#include #include #include #include #include #include #include #define BUFFER 255
int main(int argc,char **argv) { char buffer[BUFFER+1]; int fd[2];
if(argc!=2) { fprintf(stderr,"Usage:%s string/n/a",argv[0]); exit(1); }
if(pipe(fd)!=0) { fprintf(stderr,"Pipe Error:%s/n/a",strerror(errno)); exit(1); } if(fork()==0) { close(fd[0]); printf("Child[%d] Write to pipe/n/a",getpid()); snprintf(buffer,BUFFER,"%s",argv[1]); write(fd[1],buffer,strlen(buffer)); printf("Child[%d] Quit/n/a",getpid()); exit(0); } else { close(fd[1]); printf("Parent[%d] Read from pipe/n/a",getpid()); memset(buffer,'/0',BUFFER+1); read(fd[0],buffer,BUFFER); printf("Parent[%d] Read:%s/n",getpid(),buffer); exit(1); } }
为了实现重定向操作,我们需要调用另外一个函数dup2. #include
int dup2(int oldfd,int newfd);
dup2将用oldfd文件描述符来代替newfd文件描述符,同时关闭newfd文件描述符.也就是说, 所有向newfd操作都转到oldfd上面.下面我们学习一个例子,这个例子将标准输出重定向到一个文件.
#include #include #include #include #include #include #include
#define BUFFER_SIZE 1024
int main(int argc,char **argv) { int fd; char buffer[BUFFER_SIZE];
if(argc!=2) { fprintf(stderr,"Usage:%s outfilename/n/a",argv[0]); exit(1); }
if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error:%s/n/a",argv[1],strerror(errno)); exit(1); }
if(dup2(fd,STDOUT_FILENO)==-1) { fprintf(stderr,"Redirect Standard Out Error:%s/n/a",strerror(errno)); exit(1); }
fprintf(stderr,"Now,please input string"); fprintf(stderr,"(To quit use CTRL+D)/n"); while(1) { fgets(buffer,BUFFER_SIZE,stdin); if(feof(stdin))break; write(STDOUT_FILENO,buffer,strlen(buffer)); } exit(0); }
好了,文件一章我们就暂时先讨论到这里,学习好了文件的操作我们其实已经可以写出一些比较有用的程序了.我们可以编写一个实现例如dir,mkdir,cp,mv等等常用的文件操作命令了. 想不想自己写几个试一试呢?
 
2/2 首页 上一页 1 2 |