歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux 程序設計學習筆記----文件管理實例應用

一、使用ls -l 以排序方式輸出目錄信息

1.需求以及知識點覆蓋

ls -l 命令根據後面的參數將列出某文件即目錄下的基本信息。

如果沒有具體的目錄或者文件,則列出當前目錄下所有的非隱藏文件的信息,包括文件類型,文件權限,硬鏈接個數,擁有者。擁有者所在組,文件大小,文件更新時間等。

such as :

若沒有指定的文件,則輸出所有目錄下的文件信息:

所以,本應用要實現的基本功能和需要的知識點有:

①參數檢查。包括參數個數檢查,如果有多個需要列出信息的文件及目錄,則遍歷所有的參數,另外需要讀取當前參數是文件還是目錄。(stat函數可以讀取)

②如果是普通文件,需要構建此文件的鏈表,然後使用stat()函數讀取鏈表成員文件的屬性,並根據stat輸出結果進行用戶ID到用戶名的轉化,組id到組名的轉換,以及時間的轉換(stat函數的時間是linux時間,1970-1-1至此刻的秒數)。

③如果是目錄文件,需要一次讀取該目錄先的文件列表,並按需存儲在鏈表中,本示例中選用簡單的插入排序,然後讀取該文件的基本信息。

Linux程序設計(原書第2版)(PDF中文版 + 源碼) http://www.linuxidc.com/Linux/2011-04/34147.htm

Linux常用命令大全-管理文件和目錄的命令 http://www.linuxidc.com/Linux/2011-08/40437.htm

Linux文件系統層次結構分析、目錄管理、文件管理、日期管理常用命令使用  http://www.linuxidc.com/Linux/2013-05/84988.htm

Linux 文件管理常用命令 http://www.linuxidc.com/Linux/2013-05/84732.htm

2.流程

主函數流程如下:

①參數檢查。參數不能少於兩個,如果參數大於兩個,列出對應的信息。

②檢測參數類型,如果是普通文件且存在,則讀取該文件的屬性。

③如果是目錄文件,循環查找目錄下的所有文件,采用及簡單的插入排序讀取信息,並列出整個鏈表文件信息。

3.代碼實現

具體代碼如下,詳細過程那個見注釋。

/*************************************************************************
> File Name: sort_l.c
> Author: SuooL 
> Mail: [email protected]
> Created Time: 2014年07月31日 星期五 15時44分32秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>

#define NAME_SIZE 256

// 構建的鏈表節點數據結構
struct fnode
{
 struct fnode *next;    // 下一個成員
 char name[NAME_SIZE];  // 當前成員文件名
};

struct fnode *insert_list(struct fnode *temp,struct fnode *head)
{
 if(head==NULL) //if linklist is empty,for temp is the first one
 {
  head=temp;
  return head;
 }

 if(strcmp(temp->name,head->name)<0) //temp will be insert before first one
 {
  temp->next=head;
  head=temp;
  return head;
 }
 
 struct fnode *next=head->next;
 struct fnode *prev=head;
 while(next!=NULL&& strcmp(temp->name,next->name)>0)
 {
  next=next->next;
  prev=prev->next;
 }
 temp->next=next;
 prev->next=temp;
 return head;
}

// 讀取文件權限屬性函數,根絕參數(lstat函數返回類型st_mode)列出各個文件的權限個類型字符
output_type_perm(mode_t mode)
{
 char  type[7]={'p','c','d','b','-','l','s'};
 int index=((mode>>12) & 0xF)/2;
 printf("%c",type[index]);

 char *perm[8]={"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};//rwx
 printf("%s",perm[mode>>6 &07]);
 printf("%s",perm[mode>>3 &07]);
 printf("%s",perm[mode>>0 &07]);
}

// 列出用戶及組
void output_user_group(uid_t uid,gid_t gid)
{
 struct passwd *user;
 user=getpwuid(uid);
 printf("  %s",user->pw_name);

 struct group *group;
 group=getgrgid(gid);
 printf(" %s",group->gr_name);
}

// 列出個文件基本信息函數將各個函數的返回值輸出的屏幕
output_mtime(time_t mytime)
{
 char buf[256];
 memset(buf,'\0',256);
 ctime_r(&mytime,buf);
 buf[strlen(buf)-1]='\0';
 //memcpy(buf,ctime(mytime),strlen(ctime(mytime))-1);
 printf("  %s",buf);
}

void output_info(struct fnode *head)
{
 struct fnode *temp=head;
 while(temp!=NULL)
 {
  struct stat mystat;
  if(-1==stat(temp->name,&mystat))
  {
   perror("stat");exit(EXIT_FAILURE);
  }
  output_type_perm(mystat.st_mode);
  printf("  %4d",mystat.st_nlink);
  output_user_group(mystat.st_uid,mystat.st_gid);
  printf(" %8ld",mystat.st_size);
  output_mtime(mystat.st_mtime);
  printf(" %s\n",temp->name);
  temp=temp->next;
 }

}
void free_list(struct fnode *ptr)
{
 struct fnode *temp=ptr;
 struct fnode *link=ptr;
 while(ptr)
 {
  temp=ptr;
  ptr=ptr->next;
  free(temp);
 }
}


// main()函數源碼
int main(int argc,char *argv[])
{
 if(argc < 2)
 {
  printf("usage :%s dir_name\n",argv[0]);exit(EXIT_FAILURE);
 }

 int i;
 for(i=1;i<argc;i++)
 {
  struct fnode *linklist=NULL;


  struct stat stat_info;
  if(stat(argv[i],&stat_info)==-1)
  {
   perror("stat");exit(EXIT_FAILURE);
  }
 
  if (S_ISREG(stat_info.st_mode))  //regular file
  {
   struct fnode *temp=(struct fnode *)malloc(sizeof(struct fnode));
   if(NULL==temp)
   {
    perror("malloc");exit(EXIT_FAILURE);
   }
   temp->next=NULL;
   memset(temp->name,'\0',NAME_SIZE);
   memcpy(temp->name,argv[i],strlen(argv[i]));
   linklist=insert_list(temp,linklist);
   output_info(linklist);//output information of the file
  }
  else if(S_ISDIR(stat_info.st_mode))
  {
   char buf[NAME_SIZE];
   getcwd(buf,128);
   
   DIR  *dirp=NULL;
   dirp=opendir(argv[i]);
   if(NULL==dirp)
   {
    perror("opendir");exit(EXIT_FAILURE);
   }

   struct dirent *entp=NULL;
   while(entp=readdir(dirp))
   {
    struct fnode *temp=(struct fnode *)malloc(sizeof(struct fnode));
    if(NULL==temp)
    {
     perror("malloc");exit(EXIT_FAILURE);
    }
    temp->next=NULL;
    memset(temp->name,'\0',NAME_SIZE);
    memcpy(temp->name,entp->d_name,strlen(entp->d_name));
    linklist=insert_list(temp,linklist);
   }
   chdir(argv[i]);//change the current dirctory
   close(dirp);
   output_info(linklist);
   chdir(buf);   
  } 
  free_list(linklist);
 } 
 return 1;
}

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-08/104983p2.htm

Copyright © Linux教程網 All Rights Reserved