C++,Java遍历文件夹下所有文件(从简易版到工具类的构建)

2 篇文章 0 订阅
本文介绍了如何使用C++和Java遍历文件夹下的所有文件,强调了Java中File类的listFiles方法的便利性,并讨论了在扩展功能如查找特定类型文件时的实现策略,同时也指出不同语言在效率和灵活性之间的权衡。
摘要由CSDN通过智能技术生成
  • C++实现。
//文件读取核心api
intptr_t hFile;//64位的int,底层库中用来存放文件的句柄。
struct _finddata_t fileInfo;//一个文件信息的结构体,包括
/*
struct _finddata64i32_t {
    unsigned    attrib;
    __time64_t  time_create;    // -1 for FAT file systems
    __time64_t  time_access;    // -1 for FAT file systems
    __time64_t  time_write;
    _fsize_t    size;
    char        name[260];
};
*/
std::string p;
/*
_findfirst函数解析:
    参数1, 路径。
    参数2,传引用,处理后得到的文件的信息。
    返回值,文件的句柄,空的话返回-1.
*/
//.c_str() string类的方法,转为const char *类型
if((hFile = _findfirst(p.assign(dir).append("\\*").c_str(), &fileInfo)) == -1) {
    std::cout << "没有匹配的文件\n";	
} else {
    //找到了first文件
    files.push_back(fileInfo.name);
/*
_findnext函数解析:
    参数1,当前文件句柄。
    参数2,传引用,下一个文件的文件信息。
    返回值,成功(存在下一个文件)返回0,空返回-1.
*/
    while(_findnext(hFile, &fileInfo) == 0) {
        files.push_back(fileInfo.name);
    }
    _findclose(hFile);//通过句柄关闭文件
}
//=================================================================================
//不递归子文件夹,完整版
int main() {
	intptr_t hFile;
	struct _finddata_t fileInfo;
	std::string p;
	std::vector<std::string> files;
	std::string dir = "D:/myPollenAll/classic/cannyConn/conn";
	//"="的优先级低于"==",所以不加括号的话,会先判断_findfirst函数返回值是否等于-1,将该结果(bool)隐藏的转换成int,赋值给hFile
	//即(hFile = _findfirst(p.assign(dir).append("\\*").c_str(), &fileInfo) == -1)这种写法出错。
	//所以Java没有boolea和int的转换,也是有道理的。(避免了一些坑)
	if ((hFile = _findfirst(p.assign(dir).append("\\*").c_str(), &fileInfo)) == -1) {
		std::cout << "error\n";
	}
	else {
		files.push_back(fileInfo.name);
		while (_findnext(hFile, &fileInfo) == 0) {
			files.push_back(fileInfo.name);
			std::cout << fileInfo.name << std::endl;
		}
	}
	std::cin.get();
}
  • 工具类完整代码
//============================================================
//创建一个工具类,增加按后缀筛选出文件等功能。
//头文件FileUtil.h
#pragma once
#include <string>
#include <vector>
class FileUtil
{
private:
	std::string dir;
	std::vector<std::string> suffixs;
	std::vector<std::string> files;
	std::vector<std::string> filesAbsolute;
	std::vector<std::string> filesFiltered;
	void process();//遍历dir,将所有的文件放入
public:
	FileUtil();
	FileUtil(std::string dir) { this->dir = dir; }
	FileUtil(std::string dir, std::vector <std::string> suffixs) {
		this->dir = dir;
		this->suffixs = suffixs;
	}
	inline void setDir(std::string dir) { this->dir = dir; }
	inline void setSuffix(std::vector<std::string> suffixs) { this->suffixs = suffixs; }
	std::vector<std::string> getFiles();
	//返回路劲下后缀为jpg,JPG,JEPG,PNG,png的文件名。

	std::vector<std::string> getImages();
	std::vector<std::string> getImagesAbsolutePath();
	~FileUtil();
};
//cpp文件FileUtil.cpp
#include "FileUtil.h"
#include <direct.h>
#include <iostream>
#include <io.h>

void FileUtil::process() {
	if (dir.empty()) {
		std::cout << "File Util Class: error, dir is empty.\n";
		return;
	}
	if (suffixs.size() == 0) {
		std::cout << "File Util Class: warnning, suffix did't set, no file would be filtered.\n";
	}
	intptr_t hFile;//__int64
	struct _finddata_t fileInfo;//用来存储文件各种信息的结构体,使用这个结构体要引用的头文件为“ #include <io.h>”
	std::string p;
	if ((hFile = _findfirst(p.assign(dir).append("\\*").c_str(), &fileInfo)) == -1) {
		std::cout << "没有匹配的文件";
	}
	else {
		std::cout << hFile;
		files.push_back(fileInfo.name);
		while (_findnext(hFile, &fileInfo) == 0) {
			files.push_back(fileInfo.name);
		}
		_findclose(hFile);
	}
	//filter
	for (std::string fileName : files) {
		for (std::string suffix : suffixs) {
			if (fileName.substr(fileName.find_last_of(".") + 1) == suffix) {
				filesFiltered.push_back(fileName);
				filesAbsolute.push_back(dir + "/" + fileName);
			}
		}
	}
}

FileUtil::FileUtil() {
	//不传入参数的话,以当前路径为目录
	char buffer[80];
	_getcwd(buffer, 80);
	dir = buffer;
}


std::vector<std::string> FileUtil::getFiles()
{
	process();
	return files;
}
//获取所有的图片(jpg png JPG JPEG PNG后缀)
std::vector<std::string> FileUtil::getImages()
{
	std::vector<std::string> suffixs_temp = suffixs;
	suffixs.clear();
	filesFiltered.clear();
	suffixs.push_back("jpg");
	suffixs.push_back("png");
	suffixs.push_back("JPG");
	suffixs.push_back("JPEG");
	suffixs.push_back("PNG");
	process();
	suffixs = suffixs_temp;//暂时用上面五个来代替。
	
	return filesFiltered;
}

std::vector<std::string> FileUtil::getImagesAbsolutePath()
{
	std::vector<std::string> suffixs_temp = suffixs;
	suffixs.clear();
	filesFiltered.clear();
	suffixs.push_back("jpg");
	suffixs.push_back("png");
	suffixs.push_back("JPG");
	suffixs.push_back("JPEG");
	suffixs.push_back("PNG");
	process();
	suffixs = suffixs_temp;//暂时用上面五个来代替。
	return filesAbsolute;
}

FileUtil::~FileUtil() {
}

int main_test() {
	std::vector<std::string> suffixs;

	FileUtil* fileUtil = new FileUtil("D:/myPollenAll", suffixs);
	std::vector<std::string> files = fileUtil->getImagesAbsolutePath();
	for (auto s : files) {
		std::cout << s <<'\n';
	}
	delete fileUtil;
	std::cin.get();
	return 0;
}
int main() {
    FileUtil* fileUtil = new FileUtil("D:/myPollenAll/classic/cannyConn/conn");
	std::vector<std::string> files = fileUtil->getImagesAbsolutePath();//通过两句,就获得了某路径下所有图片的绝对路径。
	delete fileUtil;
}



  • Java实现

Java就简单了,java.io.File类中有一个 listFiles的方法,如果File对象是文件夹的话,返回文件夹下所有文件的数组,还有很多其他好用的方法。

System.out.println(Arrays.toString(new File("E:/").listFiles()));//一句话打印输出某文件夹下所有文件名
  • Java不用造轮子,对于常规的操作方便了很多。但是想扩展,比如找到路径下所有的图片名称该怎么办呢?

对于java.lang.String这种final类(不可继承)可能没有简单的方法,但是对于java.io.File这种,继承一下即可.

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class FileUtil extends File {
    public FileUtil(String pathname) {
        super(pathname);
    }
    public List<String> getImgFile() {
        File[] files = super.listFiles();
        ArrayList<String> res = new ArrayList<>();
        for(File f : files) {
            String s = f.getName();
            if(isImage(s)){
                res.add(s);
            }
        }
        return res;
    }
    private boolean isImage(String s) {
        if(s.endsWith(".jpg")||s.endsWith(".PNG")||s.endsWith(".JPG")||s.endsWith(".JPEG")||s.endsWith("png"))
            return true;
        else
            return false;
    }

    public static void main(String[] args) {
        FileUtil fileUtil = new FileUtil("E:/");
        List<String> images = fileUtil.getImgFile();
        for(String s : images) {
            System.out.println(s);
        }
    }
}
  • 不用造轮子真的快捷了很多,不过不主动了解的话,对底层原理了解就少了。而且运行效率可能低一些(包括使用了endsWith()等方法),两者各有优劣吧。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值