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

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

1、打开目录

#include

#include

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

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

#include

int closedir(DIR *dirp);

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

int _findclose(

intptr_t handle

);

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

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

#include

#include

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

#include

#include // windows的CRT库

#include

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上面的示例代码并没有这一步。

-----------------------------------------------------------上面是之前的错误看法--------------------------------------------------------------

readdir是不可重入的函数,按照man的说明,readdir()的返回值会被接下来的调用给重写

The data returned by readdir() may be overwritten by subsequent calls

to readdir() for the same directory stream.

也就是说readdir的实现其实是类似这种

struct dirent *readdir(DIR *dp)

{

static struct dirent dir;

// ...

return &dir;

}

而不是使用动态申请内存然后再返回。修改上面列出的Linux遍历目录的示例代码,在while ((dirent p = readdir(dirp)) != NULL)的循环体内printf后面加一句delete dirp或者free(dirp)都会报错,而且是特别严重的Aborted (core dumped)。

看来当初自作聪明以为APUE上没顾及到内存的释放的我还是太嫩了,继续啃APUE~

[PHP]PHP自定义遍历目录下所有文件的方法

header('content-type:text/html;charset=utf-8');/** *   方法一:使用readir()遍历目录 */function listDir($dir){  ...

Python遍历目录下所有文件的最后一行进行判断若错误及时邮件报警-案例

遍历目录下所有文件的最后一行进行判断若错误及时邮件报警-案例: #-*- encoding: utf-8 -*- __author__ = 'liudong' import linecache,sys ...

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

linux 中 如何 搜索 指定目录 下 指定文件 的 指定内容

开发时,经常遇到 全局查找某些代码 linux 中 如何 检索 某 目录下指定文件 的 指定内容如下: //.点为查找当前目录 下 的 所有 *.php 文件里 有 hello 的文件 find . ...

Java精选笔记_IO流【File(文件)类、遍历目录下的文件、删除文件及目录】

File(文件)类 File类用于封装一个路径,该路径可以是从系统盘符开始的绝对路径,也可以是相对于当前目录而言的相对路径 File类内部封装的路径可以指向一个文件,也可以指向一个目录,在使用File ...

PHP遍历目录下的文件夹和文件 以及遍历文件下内容

1.遍历目录下的文件夹和文件: public function bianli1($dir) { $files = array(); if($head = opendir($dir)) { while( ...

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

#自定义函数: import ospath="D:\\Temp_del\\a"def gci (path): """this is a stateme ...

shell编程--遍历目录下的文件

假定目录text下有如下文件      目录:dir_1.dir_2.dir_3 文件:text_1.text_2 遍历目录下所有的文件是目录还是文件 if -- if类型: #!bin/sh for ...

Java遍历目录下全部文件并替换指定字符串

应用场景:比方有一个深层次的文件目录结构,如:javaAPI 每一个文件中面都有同样的内容,而我们要统一改动为其它内容.上千个文件假设一个个改动显得太不明智. import java.io.Buffe ...

随机推荐

软件工程(FZU2015)赛季得分榜,第八回合

目录 第一回合 第二回合 第三回合 第四回合 第五回合 第6回合 第7回合 第8回合 第9回合 第10回合 第11回合 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分 ...

hadoop2.6分布式部署时 livenodes等于1的原因

1.问题描述 在进行hadoop2.x版本的hdfs分布式部署时,遇到了一个奇怪的问题: 使用start-dfs.sh命令启动dfs之后,所有的datanode节点上均能看到datanode进程,然而 ...

apache.http.MalformedChunkCodingException: Chunked stream ended unexpectedly

产生的原因,应该是服务器返回的数据不是规范的格式 .我使用的xutils的httpUtils来实现网络通信的,关于读取数据是在 StringDownloadHandler类中源代码 inputStre ...

j2ee分布式缓存同步实现方案dlcache v1.0.0

现成的分布式K/V缓存已经有很多的实现,最主要的比如redis,memcached,couchbase.那为什么我们还要自己去实现呢,在我们解决了分布式系统下大量rpc调用导致的高延时后,我们发现很多 ...

C# 工程中引用出现感叹号

问题:在工程中引用出现感叹号 原因1:  这是由于之前引用的Dll文件不见了. 右键有感叹号的项,然后选择 “属性” 里边有一个路径属性 这个路径就是之前这个Dll文件的路径,现在这个文件不在了,你需 ...

Spring mvc中使用request和response

@ResponseBody @RequestMapping(value="/ip", method=RequestMethod.GET) public String getIP(H ...

v

360导航_新一代安全上网导航 http://www.cnblogs.com/xiaoheimiaoer/p/4309131.html

hash在Coreseek 中配置bigint

304 $sphinxapi->SetSelect('id, domain_hash'); 304 $sphinxapi->SetConnectTimeout(3); 305 $sphin ...

Android 使用AsyncTask 下载图片的例子,学会使用AsyncTask

1.添加布局文件:activity_main.xml 1

你可能感兴趣的:(linux,目录文件对比)