- 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()等方法),两者各有优劣吧。