如何通过降低文件大小来排序文件

时间:2018-05-13 16:39:55

标签: c++ boost

我需要从目录中输出5个最大的文件。为此,我使用了boost文件系统c ++。在编写程序的过程中,我遇到了困难。我可以输出目录中的所有文件,文件大小,文件创建日期和文件属性。在向量中我放了文件的名称,但我无法弄清楚如何按大小排序。我需要从指定目录输出5个最大的文件。我认为您必须首先按降序排序文件大小。也就是说,从较大的值到较小的值。然后不需要扫描。最有可能需要在循环中完成。请帮帮我。

    #define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <boost/filesystem.hpp>

using namespace std;
using namespace boost::filesystem;


void ShowAttributes(DWORD attributes);
void AttribFile(const char* str);
void Attrib();

int main(int argc, char* argv[])
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    if (argc < 2)
    {
        cout << "Using Name Directory" << endl;
        return 1;
    }

    path Part(argv[1]);

    try
    {
        if (exists(Part))
        {
            if (is_regular_file(Part))
            {

                cout << Part << " Size " << file_size(Part) << " bytes ";
                time_t Time = last_write_time(Part);
                cout << asctime(localtime(&Time)) << endl;
            }

            else if (is_directory(Part))
            {
                cout << "Directory " << Part << " include:" << endl;

                vector<string> vecList;

                for (auto j : directory_iterator(Part))
                    vecList.push_back(j.path().filename().string());

                sort(vecList.begin(), vecList.end());
                string filePath;

                for (auto i : vecList)
                {
                    cout << "    " << i;
                    filePath = Part.parent_path().string() + "/" + i;
                    if (is_regular_file(filePath))
                    {
                        if (Is_Executable_File(filePath))
                            cout << "*";

                        cout << " Size " << file_size(filePath) << " bytes ";
                        time_t Time = last_write_time(Part);
                        cout << asctime(localtime(&Time)) << endl;
                        AttribFile(filePath.c_str());
                    }
                    cout << endl;
                }
            }
        }
        else
            cout << Part << " Erroe!" << endl;
    }

    catch (const filesystem_error& ex)
    {
        cout << ex.what() << endl;
    }
    return 0;
}

void ShowAttributes(DWORD attributes)
{
    if (attributes & FILE_ATTRIBUTE_ARCHIVE)
        cout << "   archive" << endl;
    if (attributes & FILE_ATTRIBUTE_DIRECTORY)
        cout << "   directory" << endl;
    if (attributes & FILE_ATTRIBUTE_HIDDEN)
        cout << "   hidden" << endl;
    if (attributes & FILE_ATTRIBUTE_NORMAL)
        cout << "   normal" << endl;
    if (attributes & FILE_ATTRIBUTE_READONLY)
        cout << "   read only" << endl;
    if (attributes & FILE_ATTRIBUTE_SYSTEM)
        cout << "   system" << endl;
    if (attributes & FILE_ATTRIBUTE_TEMPORARY)
        cout << "   temporary" << endl;
}

void AttribFile(const char* str)
{
    DWORD attributes;
    attributes = GetFileAttributesA(str);
    ShowAttributes(attributes);
}

void Attrib()
{
    char filename[MAX_PATH];
    DWORD attributes;

    cout << "Name of file: ";
    cin >> filename;
    attributes = GetFileAttributesA(filename);
    ShowAttributes(attributes);
}

2 个答案:

答案 0 :(得分:0)

创建一个类或结构来保存每个文件所需的信息,例如

struct MyFile
{
    std::string name;
    size_t size;
}

创建这些文件的向量并读取文件夹中的所有文件

然后对矢量进行排序并进行自定义比较(例如以lambda的形式),有关详细信息,请参阅Sorting a vector of custom objects

答案 1 :(得分:0)

这是一个基于标准库的程序,可以执行您的意图:

<强> Live On Coliru

  

更新:改为使用C ++ 11和Boost文件系统: Live On Coliru

#include <algorithm>
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>

namespace fs = std::filesystem;

struct tm *last_modified(fs::path const &p) {
    auto ftime = fs::last_write_time(p);
    auto cftime = decltype(ftime)::clock::to_time_t(ftime);
    return std::localtime(&cftime);
}

bool is_executable(fs::path const& p) {
    return fs::perms::none != (fs::status(p).permissions() & 
        (fs::perms::owner_exec |
         fs::perms::group_exec |
         fs::perms::others_exec));
}

void report(fs::path const& file) {
    if (is_executable(file))
        std::cout << "*";
    std::cout << file << "\tSize:" << fs::file_size(file);
    std::cout << "\tModified:" << std::asctime(last_modified(file));
}

template <typename Accessor, typename Cmp = std::less<> >
static auto compare_by(Accessor&& f, Cmp cmp = {}) {
    return [f=std::forward<Accessor>(f),cmp](auto const& a, auto const& b) {
            return cmp(f(a), f(b));
        };
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        std::cout << "Using: " << argv[0] << " [Name|Directory]" << std::endl;
        return 1;
    }

    fs::path filespec(argv[1]);

    try {
        if (is_regular_file(filespec)) {
            // print
            report(filespec);

        } else if (is_directory(filespec)) {
            std::cout << "Directory " << filespec << " include:" << std::endl;

            std::vector<fs::directory_entry> const entries { fs::directory_iterator{filespec}, {} };

            // filter just files
            std::vector<fs::path> files;
            std::remove_copy_if(entries.begin(), entries.end(),
                    back_inserter(files),
                    [](auto& de) { return de.is_directory(); });

            // get the top 5, or fewer
            auto b    = files.begin(),
                 top5 = b + std::min(5ul, files.size()),
                 e    = files.end();

            // ordered by size, descending
            std::partial_sort(b, top5, e,
                compare_by([](auto& p) { return fs::file_size(p); }, std::greater<>{}));

            files.erase(top5, e);

            // print
            for (auto& f : files)
                report(f);
        } else {
            std::cout << filespec << " Error!" << std::endl;
        }
    } catch (const fs::filesystem_error &ex) {
        std::cout << ex.what() << std::endl;
    }
}

打印,例如./a.out /usr/lib

Directory "/usr/lib/" include:
"/usr/lib/libruby-1.9.1-static.a"   Size:3654748    Modified:Wed Nov 19 21:41:25 2014
"/usr/lib/libruby-1.9.1.so.1.9.1"   Size:2087600    Modified:Wed Nov 19 21:41:20 2014
"/usr/lib/libruby-1.9.1.so" Size:2087600    Modified:Wed Nov 19 21:41:20 2014
"/usr/lib/libruby-1.9.1.so.1.9" Size:2087600    Modified:Wed Nov 19 21:41:20 2014
"/usr/lib/libc++.so.1"  Size:1460461    Modified:Mon Sep  8 20:01:17 2014