Linux和Windows的遍历目录下所有文件的方法对比

首先两者读取所有文件的方法都是采用迭代的方式,首先用函数A的返回值判断目录下是否有文件,然后返回值合法则在循环中用函数B直到函数B的返回值不合法为止。最后用函数C释放资源。

1、打开目录

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);

先看Linux的,返回的是DIR*,因此出错时返回NULL(0)。而这里不用关心DIR结构具体定义,只需要知道是对它进行操作(注意:DIR不是保存文件信息的结构)

而Windows的方法很多,包括MFC的CFileFind类、WINAPI的WIN32_FIND_DATA和C运行库的_finddata_t,这里选取最后一种

intptr_t _findfirst(
   const char *filespec,
   struct _finddata_t *fileinfo
);

返回类型是intptr_t,这是用来表示两个指针(地址)之间距离的类型(比如对指针类型p1,p2,用intptr_t来接收p1-p2的返回值),比如指针在32位系统上是4个字节,而在64位系统上是8个字节,通过#ifdef宏来实现跨平台的类型。

这里返回值其实是一个标识当前目录下所有文件的HANDLE而不是实际指针类型,所以出错时返回-1而不是0(NULL)。

再看输入参数,第1个参数是filespec(而不是filename),很容易用错,因为它不是像Linux的opendir一样简单地接收目录名,而是接收一个特定格式。比如C:\*.*就代表搜索C盘下所有类型文件,而C:\*.txt则代表搜索C盘下所有txt文件。第2个参数是struct _finddata_t是实际存储文件信息的结构。

2、遍历文件

每个文件都有一个具体的结构来描述它的属性,这里只以文件名作为示例,其他属性不具体探,具体定义可以查找文档。

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

Linux下的方法依然很简单,通过第一步得到的DIR*作为输入参数,方法成功则返回指向当前文件的dirent*,struct dirent即保存文件信息的结构

           struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };

如果读取失败则返回空指针NULL(0)

再看Windows下的方法

int _findnext(
   intptr_t handle,
   struct _finddata_t *fileinfo
);

这里返回值是int,依旧是出错时返回-1。(C没有异常处理机制,而是采用朴素的错误码机制,于是诞生了让初学者感到很困惑的问题:返回0到底是代表正确还是不正确呢?对错误码而言,0往往代表正确,而对指针而言0则代表失败,也就是空指针NULL)

第1个输入参数也是第1个函数的返回值,第2个输入参数也是描述文件的结构体的指针。struct _finddata_t即保存文件信息的结构,它也是个跨(Windows)平台的定义,以32位系统为例

struct _finddata32_t
{
    unsigned    attrib;
    __time32_t  time_create;    // -1 for FAT file systems
    __time32_t  time_access;    // -1 for FAT file systems
    __time32_t  time_write;
    _fsize_t    size;
    char        name[260];
};

3、关闭目录

#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);

Linux下的,输入参数是第1个函数的返回值,而这里返回值不再是指针,而是错误码,因此返回值为0时代表关闭directory stream成功,为-1代表失败

int _findclose(
   intptr_t handle
);

Windows下的也一样,输入参数是第1个函数的返回值,返回0代表关闭handle成功,为-1代表失败。

最后分别给出Linux和Windows上遍历目录下所有文件的示例代码(为了简化忽略错误处理)

#include <stdio.h>
#include <dirent.h>

int main(int argc, char** argv)
{
   struct dirent *direntp;
   DIR *dirp = opendir("/");

   if (dirp != NULL) {
       while ((direntp = readdir(dirp)) != NULL)
           printf("%s\n", direntp->d_name);
   }

   closedir(dirp);
   return 0;
}
// Windows(C++)
#include <stdio.h>
#include <stdlib.h>
#include <io.h>  // windows的CRT库
#include <string>

int main()
{
	_finddata_t fd;
	intptr_t handle;
	std::string dir_name = "C:\\";

	if ((handle = _findfirst((dir_name + "*.*").c_str(), &fd)) != -1) {
		while (_findnext(handle, &fd) != -1)
			printf("%s\n", fd.name);
	}

	_findclose(handle);
	return 0;
}

由于Windows下还要对dir_name附上一段字符串所以直接用std::string了,用char数组然后strcpy太麻烦。

对比可以发现,Windows是把文件结构的指针作为输入参数,而Linux则是作为返回参数,Linux下的这种做法更为自然,而且即使用的是C风格,代码也非常简单易懂。

但是要注意,Linux这种做法实际上是动态申请了空间,需要手动free(direntp)来释放内存,虽然APUE上面的示例代码并没有这一步。

时间: 2024-12-25 04:58:08

Linux和Windows的遍历目录下所有文件的方法对比的相关文章

Python递归遍历目录下所有文件

#自定义函数: import ospath="D:\\Temp_del\\a" def gci (path): parents = os.listdir(path) for parent in parents: child = os.path.join(path,parent) #print(child) if os.path.isdir(child): gci(child) # print(child) else: print(child) gci(path) #使用os.walk方

(实用篇)PHP不用递归遍历目录下所有文件的代码

<?php /** * PHP 非递归实现查询该目录下所有文件 * @param unknown $dir * @return multitype:|multitype:string */ function scanfiles($dir) { if (! is_dir ( $dir )) return array (); // 兼容各操作系统 $dir = rtrim ( str_replace ( '\\', '/', $dir ), '/' ) . '/'; // 栈,默认值为传入的目录 $

Linux编译多个不同目录下的文件以及静态库、动态库的使用

先看两篇博文,作为基础知识.如果对C/C++编译链接过程都了解的话,可以跳过不看. http://www.firedragonpzy.com.cn/index.php/archives/2556 http://www.cppblog.com/shifan3/archive/2007/01/05/17325.html 一.  编译不同目录下的多个文件 各个文件的布局如下: head.h文件的代码: [cpp] view plaincopy #ifndef  HEAD_H #define  HEAD

Linux中通过setfacl实现目录下创建文件

在Linux 系统中,可以通过setfacl 来实现目录下创建文件或子目录,并继承父目录的权限. 下面以 root 用普通用户 user1 .在目录/mnt下 [[email protected] mnt]# setfacl -m u:user1:rwx share        //为目录添加ower = user1 ,并赋予rwx 的权根. [[email protected]redhat-7 mnt]# setfacl -d -m  u:user1:rwx share    //为目录添加

[转载]Python递归遍历目录下所有文件

#自定义函数: import ospath="D:\\Temp_del\\a"def gci (path):"""this is a statement"""parents = os.listdir(path)for parent in parents:child = os.path.join(path,parent)#print(child)if os.path.isdir(child):gci(child)# print(

perl 递归地遍历目录下的文件

#!/usr/bin/perl -w use strict; use File::Spec; local $\ ="\n";#当前模块的每行输出加入换行符 my %options; #目录路径 $options{single_case} = '/home/jiangyu/src/pl/Example'; my @cases; if (-d $options{single_case}) {#判断目录是否存在 my @files; my $dh; push(@files, $options

遍历目录下的文件

#!/bin/sh for file in ./*do if [ -f $file ];then echo $file echo 是文件 fi if [ -d $file ];then echo $file echo 是目录 fidone

C/C++遍历目录下的所有文件(Windows篇,超详细)

注:本文讨论的是怎么用Windows API遍历目录下的所有文件.除Windows API,还有一种Windows/Linux通用的方式,使用<io.h>. WIN32_FIND_DATA结构 遍历目录下的文件需要用到WIN32_FIND_DATA结构.实际上有两种结构:WIN32_FIND_DATAA和WIN32_FIND_DATAW.A和W分别代表ASCII和宽字符(Unicode).定义UNICODE宏时,WIN32_FIND_DATA指WIN32_FIND_DATAW:否则指WIN32

Lua 遍历Linux目录下的文件夹

代码如下,里面有注释,应该能看懂. function getFile(file_name) local f = assert(io.open(file_name, 'r')) local string = f:read("*all") f:close() return string end function writeFile(file_name,string) local f = assert(io.open(file_name, 'w')) f:write(string) f:cl