如何用C语言实现linux下的ls命令
转载自:CND8学院(http://school.cnd8.com/c/jiaocheng/60408.htm)
首先我讲一下写这篇东西的目的。我觉得对于很多linux新手。尤其是在自学的同学。最好的学习的方法就是通过具体的例子。通过一个实践的例子,在学习相关的知识点的同时,就把它们应用到这例子中。这样不仅知道了原理。也知道了怎么去应用。下面就开始用一个常用的命令”ls”开始。所有的东西都是从最基本的原理开始。一步步来教你怎么实践出一个命令
(一)ls命令简单介绍
第一步当然是要明白ls究竟是做什么的。如果你要做一个东西却不知道要用来干嘛。会不会很搞笑?所以下面就简单的介绍ls命令的作用和怎么使用
1.Ls可以列出文件名和文件的属性
在命令行输入ls:
ls 命令.jpg
Ls的默认动作是找出当前所有文件的文件名。按字典排序后输出。
Ls还能显示其他的信息。如果加上-l就会列出每个文件的详细信息。也叫ls的长格式:
ls -l命令.jpg
2. 列出指定目录或文件的信息
Linux系统中会有很多目录。每个目录中又会有很多文件。如果要列出一个非当前目录的内容或者是一个特定文件的信息,则需要在参数中给出目录名或文件名。如:
ls /tmp //列出/tmp目录中各文件的文件名
ls – docs //列出docs目录中各文件的属性
ls *.c //列出当前目录下与*.c匹配的文件,即当前目录下所有以.c为后缀的文件
3. 经常用到的命令行选项
ls -l 在前面已经提到过,-l就是输出文件详细的信息。也叫长格式;
ls -a 列出的内容包含以“.“开头的让文件,即所谓有隐藏文件
ls –lu 显示最后访问时间
ls –t 输出时按时间排序
ls –F 显示文件类型
ls 命令的参数选项非常多,大多也可以组合使用。所以还是比较复杂的。但是我们第一步要实现的就是它最基本的功能:列出当前目录下的所有文件或子目录。
(二)学习必备的知识
既然是列出文件和目录,那么肯定是和linux文件系统有关系的,所以要写ls命令,至少要对文件系统的基本原理有一定的了解。为了不至于使这个帖子内容过于复杂,我把这方面的知识介绍单独开了一个帖子:
linux 文件系统详解
如果你对这些已经有所了解。就会知道linux下的文件都是以/为根目录的树型结构,虽然linux下有普通文件、目录文件、链接文件、设备文件、管道文件这几种类型。但链接文件、设备文件、管道文件都可以当做普通文件看待,那实际也就只要区分普通文件和目录文件这两种了。而目录文件的内容就是它所包含所有文件和子目录的一个列表,所以只要打开目录文件并读取对应目录块里的那个列表数据,就可以得到些目录下所有文件和子目录的名称了。其实这个流程简单,就是:打开目录->读取内容->显示文件名称->关闭打开的目录。用伪代码流程表示如下:
Mani(){
Opendir
While(readdir)
Print d_name
Closedir;
}
那么现在的问题是用什么函数去打开并读目录呢?又是怎么样来读出数据呢?这里介绍是的opendir 和readdir,但是可能对于一些新手来说,就算知道了函数名称也不一定知道怎么用。别急,下一步就是教你怎么去查相应函数的帮助资料。
linux下查看帮助手册的命令是man,关于man的详细介绍在这个帖子里我有详细介绍:linux 帮助手册页命令 man详解 如果对这方面还不是很清楚的可以先去学习一下。
好了,如果你已经明白man的用法,我们就开始查看opendir和readdir的用法
我们在命令行输入:
# man 3 opendir
怎样使用C语言列出某个目录下的文件?
转载自:http://see.xidian.edu.cn/cpp/html/1548.html
C语言本身没有提供象dir_list()这样的函数来列出某个目录下所有的文件。不过,利用C语言的几个目录函数,你可以自己编写一个dir_list()函数。
首先,头文件dos.h定义了一个find_t结构,它可以描述DOS下的文件信息,包括文件名、时间、日期、大小和属性。其次,C编译程序库中有_dos_findfirst()和_dos_findnext()这样两个函数,利用它们可以找到某个目录下符合查找要求的第一个或下一个文件。
dos_findfirst()函数有三个参数,第一个参数指明要查找的文件名,例如你可以用“*.*”指明要查找某个目录下的所有文件。第二个参数指明要查找的文件属性,例如你可以指明只查找隐含文件或子目录。第三个参数是指向一个find_t变量的指针,查找到的文件的有关信息将存放到该变量中。
dos_findnext()函数在相应的目录中继续查找由_dos_findfirst()函数的第一个参数指明的文件。_dos_findnext()函数只有一个参数,它同样是指向一个find_t变量的指针,查找到刚文件的有关信息同样将存放到该变量中。
利用上述两个函数和find_t结构,你就可以遍历磁盘上的某个目录,并列出该目录下所有的文件,请看下例:
#include <stdio.h>
#include <direct.h>
#include <dos.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
typedef struct find_t FILE_BLOCK
void main(void);
void main(void)
{
FILE_BLOCK f-block; /* Define the find_t structure variable * /
int ret_code; / * Define a variable to store the return codes * /
/ * Use the "*.*" file mask and the 0xFF attribute mask to list
all files in the directory, including system files, hidden
files, and subdirectory names. * /
ret_code = _dos_findfirst(" *. * ", 0xFF, &f_block);
/* The _dos_findfirst() function returns a 0 when it is successful
and has found a valid filename in the directory. * /
while (ret_code == 0)
{
/* Print the file's name * /
printf(" %-12s\n, f_block, name);
/ * Use the -dos_findnext() function to look
for the next file in the directory. * /
ret_code = _dos_findnext (&f_block);
}
printf("\nEnd of directory listing. \n" );
}
//-------------------------------------------------
linux下用C语言历遍目录( C语言列出目录)
转载自:http://blog.sina.com.cn/s/blog_49ea99e10100f40z.html
linux下历遍目录的方法一般是这样的:
打开目录-》读取-》关闭目录
相关函数是(函数原形)
opendir -> readdir -> closedir
#include <dirent.h>
DIR *opendir(const char *dirname);
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
#include <dirent.h>
int closedir(DIR *dirp);
dirent.h这个头文件,包括了目录的一些函数。
opendir用于打开目录,是类似于流的那种方式,返回一个指向DIR结构体的指针,他的参数*dirname是一个字符数组或者字符串常量。
readdir函数用于读取目录,他只有一个参数,这个参数主要是opendir返回的结构体指针。
dirent的结构如下定义
struct dirent
{
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name [NAME_MAX+1];
}
结构体中d_ino存放的是该文件的结点数目;
d_off 是文件在目录中的编移;
short d_reclen是这个文件的长度;
程序如下:
#include “apue.h"
#include <dirent.h>
int
main(int argc ,char *argv[])
{
DIR *dp;
struct dirent *dirp;
if(argc!=2)
err_quit("usage: ls directory_name");
if((dp=opendir(argv[1]))==NULL)
err_sys("can't open %s",argv[1]);
while((dirp=readdir(dp))!=NULL)
printf("%s\n",dirp->d_name);
closedir(dp);
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
void print_usage(void);
void print_usage(void)
{
printf("Usage: test dirname\n");
}
int main(int argc,char *argv[])
{
DIR * dp;
struct dirent *filename;
if (argc < 2)
{
print_usage();
exit(1);
}
dp = opendir(argv[1]);
if (!dp)
{
fprintf(stderr,"open directory error\n");
return 0;
}
while (filename=readdir(dp))
{
printf("filename:%-10s\td_info:%ld\t d_reclen:%us\n",
filename->d_name,filename->d_ino,filename->d_reclen);
}
closedir(dp);
return 0;
}
sudo gcc readdir.c
./a.out /home/growliming
结果如下:
filename:APUE.chm d_info:16746 d_reclen:20s
filename:src.tar.gz d_info:1063454 d_reclen:24s
filename:c d_info:24536 d_reclen:16s
filename:apue.2e d_info:32874 d_reclen:20s
filename:.. d_info:16353 d_reclen:16s
filename:. d_info:16708 d_reclen:16s
//-----------------------------------------------------------------
c语言列出文件夹中的文件
转载自:http://blog.csdn.net/gotoxy/article/details/1872332
/* TC2.0 下编译*/
#include "stdio.h"
#include "stdlib.h"
#include "dir.h"
#include "dos.h"
#define wait() getch()
/*
============目录函数(原型声明所在头文件为dir.h、dos.h)================
int chdir(char *path) 使指定的目录path(如:"C://WPS")变成当前的工作目录,成
功返回0
int findfirst(char *pathname,struct ffblk *ffblk,int attrib)查找指定的文件,成功
返回0
pathname为指定的目录名和文件名,如"C://WPS//TXT"
ffblk为指定的保存文件信息的一个结构,定义如下:
┏━━━━━━━━━━━━━━━━━━┓
┃struct ffblk ┃
┃{ ┃
┃ char ff_reserved[21]; //DOS保留字 ┃
┃ char ff_attrib; //文件属性 ┃
┃ int ff_ftime; //文件时间 ┃
┃ int ff_fdate; //文件日期 ┃
┃ long ff_fsize; //文件长度 ┃
┃ char ff_name[13]; //文件名 ┃
┃} ┃
┗━━━━━━━━━━━━━━━━━━┛
attrib为文件属性,由以下字符代表
┏━━━━━━━━━┳━━━━━━━━┓
┃FA_RDONLY 只读文件┃FA_LABEL 卷标号┃
┃FA_HIDDEN 隐藏文件┃FA_DIREC 目录 ┃
┃FA_SYSTEM 系统文件┃FA_ARCH 档案 ┃
┗━━━━━━━━━┻━━━━━━━━┛
例:
struct ffblk ff;
findfirst("*.wps",&ff,FA_RDONLY);
int findnext(struct ffblk *ffblk) 取匹配finddirst的文件,成功返回0
*/
void formatExt(char *dstr,char *sstr)
{
sscanf(sstr,"[^///:*?/"<>|]",dstr);
}
typedef int (*METHOD)();
int enum_allFile(METHOD method,char *dir,char *type,int filter)
{/*
method==NULL 仅显示文件名
dir==NULL 当前文件夹
*/
static struct ffblk ff;
static int ct,run_method;
run_method=0;
if(type!=NULL){
if(dir!=NULL) {
if(chdir(dir)){
puts("folder can't found!");
wait();
exit(1);
}
}
formatExt(type,type);
if(findfirst(type,&ff,filter)) {
puts("can't find file!");
ct=0;
return 0;
}
ct=1;
run_method=1;
}
else {
if(findnext(&ff) ==0){
ct++;
run_method=1;
}
else return ct;
}
if(run_method){
if(method!=NULL) method(ff.ff_name);
else printf("/n%s",ff.ff_name);
}
enum_allFile( method,NULL, NULL, 0);
return ct;
}
void TestFunc(char *fname)
{
puts(fname);
}
int main()
{
int ct;
ct=enum_allFile( TestFunc, NULL, "*.c", FA_RDONLY | FA_HIDDEN | FA_SYSTEM );/* */
printf("/n--------------%d-------------/n",ct);
wait();
return 0;
}
在Linux中用C语言实现目录检索和返回所有文件
转载自:http://blog.sina.com.cn/s/blog_48a83572010002p6.html
大家都知道,使用递归调用的方法可以完成对指定目录及其所有子目录的遍历.这在WINDOW下是不难实现的.而在LINUX下,由于我没有找到相关的实例.所以自己动手做了一个.请大家指正.
/*
* FUNCTION : ReadPath
* ABSTRACT : Get the file name from path and is't child path
* PARAMETER :
* char* path
* char file[FILE_CNT_MAX][256] the all files path and name int the specified path
* RETURN :
* 0 OK
* -1 FALSE
* CREATE : 2006-01-05 ZHANG.JINCUN
* NOTE :
*/
int g_iFileCnt = 0;
int ReadPath(char* path, char file[][256], char* filefmt)
{
DIR * pdir;
struct dirent * ptr;
char newpath[256];
struct stat filestat;
if(stat(path, &filestat) != 0){
printf("The file or path(%s) can not be get stat!\n", newpath);
return -1;
}
if((filestat.st_mode & S_IFDIR) != S_IFDIR){
printf("(%s) is not be a path!\n", path);
return -1;
}
pdir =opendir(path);
while((ptr = readdir(pdir))!=NULL)
{
if(g_iFileCnt + 1 > FILE_CNT_MAX){
printf("The count of the files is too much(%d > %d)!\n", g_iFileCnt + 1, FILE_CNT_MAX);
break;
}
if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) continue;
sprintf(newpath,"%s/%s", path,ptr->d_name);
if(stat(newpath, &filestat) != 0){
printf("The file or path(%s) can not be get stat!\n", newpath);
continue;
}
/* Check if it is path. */
if((filestat.st_mode & S_IFDIR) == S_IFDIR){
if(ReadPath(newpath, file, filefmt) != 0){
printf("Path(%s) reading is fail!\n", newpath);
continue;
}
}else if((filestat.st_mode & S_IFREG) == S_IFREG){
if(filefmt[0] != '\0'){
char* p;
if((p = strrchr(ptr->d_name,'.')) == 0) continue;
char fileformat[64];
char* token;
strcpy(fileformat, filefmt);
if((token = strtok( fileformat,";")) == NULL){
strcpy(file[g_iFileCnt], newpath);
g_iFileCnt++;
continue;
}else{
if(strcasecmp(token,p) == 0){
strcpy(file[g_iFileCnt], newpath);
g_iFileCnt++;
continue;
}
}
while((token = strtok( NULL,";")) != NULL){
if(strcasecmp(token,p) == 0){
strcpy(file[g_iFileCnt], newpath);
g_iFileCnt++;
continue;
} }
}else{
strcpy(file[g_iFileCnt], newpath);
g_iFileCnt++;
}
}
}
closedir(pdir);
return 0;
}
在上面的ReadPath()函数中,参数char* path是你要检索的目录,其内部可以有子目录;char file[][256]是检索结果,存放所有匹配的文件名;char* filefmt是你需要返回文件的类型,例如".cc;.c;.h".
请大家帮我看看这个函数的性能,也供大家参考使用.本函数已经在LINUX上运行通过.
本函数本人所有.请勿商业使用.谢谢!