从任意目录加载特定文件?

时间:2014-08-21 23:00:15

标签: c++ boost file-io

我想加载foo.txtfoo.txt目录中可能存在data/bar/,或者data/New Folder/目录中可能存在foo.txt。这两个目录中可能都有不同的foo.txt,在这种情况下,我想要加载一个并根据我对目录进行排序的顺序忽略另一个(可能手动,也许是创建日期),或者加载它们并以某种方式组合结果。后者(结合两个/所有boost::filesystem文件的结果)是间接的,超出了这个问题的范围,但是我希望将来能够做到这一点。

我正在使用SDL和data/。我想保持我的依赖列表尽可能小,并尽可能地跨平台。

我猜我最好的办法是获取每个目录的列表(在foo.txt文件夹中),排序/过滤此列表,然后当我去加载data/foo/时,我在每个潜在目录中搜索它?如果我每次都有几十个可能的搜索目录,这听起来效率非常低。

实现这一目标的最佳方法是什么?

奖励:如果我想将某些目录归档,该怎么办?即。同时考虑data/bar.zipfoobar.txt两者都有效,并从任何一个中提取{{1}}而不关心。

2 个答案:

答案 0 :(得分:1)

我解决了自己的问题。我删掉了boost::filesystem,现在正在使用PhysicsFS,它支持我所需要的,是跨平台的,并且在任何地方都使用utf-8

答案 1 :(得分:0)

我不认为你的方法真的那么“低效”。在我的带有Debian测试的1.6 GHz Atom D510机器上,搜索stdio.h超过/usr/include(有大约1,300个目录和19,000个文件)只花了2.2秒和0.7秒,分别没有文件系统缓存和文件系统缓存。

至于ZIP存档支持,我认为Boost不能帮助你。您需要依赖libzip或替代库,例如https://code.google.com/p/miniz/(我还没有真正尝试过这个。)

目录扫描基准:

#include <iostream>
#include <chrono>

using namespace std;

#include <boost/filesystem.hpp>

using namespace boost;

static void doFind(const filesystem::path &path) {
    if ( ! filesystem::exists(path)) {
        cout << "Non-existent [" << path << "]" << endl;
        return;
    }   

    if (is_directory(path)) {
        for (auto it = filesystem::directory_iterator(path), end = filesystem::directory_iterator(); it != end; ++it) {
            doFind(it->path());
        }   
    } else if (is_regular_file(path)) {
        if (path.filename() == "stdio.h")
            cout << "found [" << path << "]" << endl;
    } else {
        cout << "cannot handle [" << path << "]" << endl;
    }   
}

int main(int argc, char *argv[]) {
    const char *root = "/usr/include";
    if (1 < argc)
        root = argv[1];

    auto t0 = chrono::steady_clock::now();
    doFind(root);
    auto t1 = chrono::steady_clock::now();
    auto msec = chrono::duration_cast<chrono::milliseconds>(t1 - t0);
    cout << "searching over [" << root << "] took " << msec.count() << " msec." << endl;
}

软件版本:

$ uname -a
Linux zbox 3.14-2-amd64 #1 SMP Debian 3.14.15-2 (2014-08-09) x86_64 GNU/Linux
$ g++ --version
g++ (Debian 4.9.1-4) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ LANG=C dpkg -l libboost-filesystem-dev
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                        Version            Architecture       Description
+++-===========================-==================-==================-============================================================
ii  libboost-filesystem-dev:amd 1.55.0.2           amd64              filesystem operations (portable paths, iteration over direct