আপনি স্ট্যান্ডার্ড সি ++ তে প্রতিটি ফাইল / ডিরেক্টরিতে পুনরাবৃত্তি করবেন কীভাবে?


115

আপনি স্ট্যান্ডার্ড সি ++ তে প্রতিটি ফাইল / ডিরেক্টরিতে পুনরাবৃত্তি করবেন কীভাবে?


আপনি boost.files systemm
ডগ টি।

1
স্ট্যান্ডার্ড সি ++ নয়: পোকোপ্রজেক্ট.আর্গ
কুরিয়ান

1
এই শীঘ্রই মাধ্যমে মান থাকা উচিত ফাইলসিস্টেম হিজড়া , সঙ্গে recursive_directory_iterator
আদি Shavit

যদি কোনও স্ট্যান্ডার্ড সি লাইব্রেরির ব্যবহার কোনও সি ++ প্রোগ্রামকে 'স্ট্যান্ডার্ড', nftw () হিসাবে কল করার পথে না আসে । এখানে একটি বাস্তব উদাহরণ
ছয়-কে

2
যে কেউ, যারা জানেন তারা কি করছেন, এটি আপডেট করতে এক ঘন্টা সময় নেওয়া উচিত।
জোশ সি

উত্তর:


99

স্ট্যান্ডার্ড সি ++ এ, প্রযুক্তিগতভাবে এটি করার কোনও উপায় নেই কারণ স্ট্যান্ডার্ড সি ++ এর ডিরেক্টরিগুলির কোনও ধারণা নেই। আপনি যদি নিজের জালটি কিছুটা প্রসারিত করতে চান তবে আপনি বুস্ট.ফাইসিসটেমটি ব্যবহার করতে পছন্দ করতে পারেন । এটি টিআর 2-এ অন্তর্ভুক্তির জন্য গৃহীত হয়েছে, সুতরাং এটি আপনার বাস্তবায়নটিকে যতটা সম্ভব মানের কাছাকাছি রাখার সেরা সুযোগ দেয়।

ওয়েবসাইট থেকে সরাসরি নেওয়া একটি উদাহরণ:

bool find_file( const path & dir_path,         // in this directory,
                const std::string & file_name, // search for this name,
                path & path_found )            // placing path here if found
{
  if ( !exists( dir_path ) ) return false;
  directory_iterator end_itr; // default construction yields past-the-end
  for ( directory_iterator itr( dir_path );
        itr != end_itr;
        ++itr )
  {
    if ( is_directory(itr->status()) )
    {
      if ( find_file( itr->path(), file_name, path_found ) ) return true;
    }
    else if ( itr->leaf() == file_name ) // see below
    {
      path_found = itr->path();
      return true;
    }
  }
  return false;
}

5
সি ++ এর ফাইলগুলির কোন ধারণা নেই? স্ট্যান্ড :: fstream সম্পর্কে কি? নাকি ফোপেন?
কেভিন

30
ফাইলগুলি, ডিরেক্টরি নয়
1800 তথ্যটি

22
সর্বশেষতম বুস্ট সংস্করণ সম্পর্কিত আপডেট করুন: যদি কেউ এই উত্তরটি অতিক্রম করে তবে সর্বশেষতম বুস্টে একটি সুবিধাসমূহ শ্রেণি বর্ধন অন্তর্ভুক্ত :: recursive_directory_iterator সুতরাং সুস্পষ্ট পুনরাবৃত্ত কল সহ উপরের লুপটি লেখার দরকার নেই। লিংক: boost.org/doc/libs/1_46_1/libs/files systemmvv3
doc

5
ভিসি ++ 11 এসডিডি :: ট্রাই :: :: সাইস নেমস্পেসের অধীনে <ফাইল্স সিস্টেম> শিরোনামে একই কার্যকারিতা সহ আসে।
মহিমান

3
এটি একটি ভাল উত্তর হিসাবে ব্যবহৃত হত, তবে এখন যে <ফাইল সিস্টেম> স্ট্যান্ডার্ড, কেবল সহজভাবে ব্যবহার করা ভাল (উদাহরণের জন্য অন্যান্য উত্তর দেখুন)।
গাথার

54

সি ++ 17 এর পরে, <filesystem>শিরোনাম এবং ব্যাপ্তি- for, আপনি কেবল এটি করতে পারেন:

#include <filesystem>

using recursive_directory_iterator = std::filesystem::recursive_directory_iterator;
...
for (const auto& dirEntry : recursive_directory_iterator(myPath))
     std::cout << dirEntry << std::endl;

সি ++ 17 হিসাবে, std::filesystemস্ট্যান্ডার্ড লাইব্রেরির অংশ এবং এটি <filesystem>শিরোনামে পাওয়া যাবে (আর "পরীক্ষামূলক" নয়)।


ব্যবহারের এড়িয়ে চলুন using, ব্যবহার namespaceপরিবর্তে।
ড্যান্টন

2
এবং এটা কেন? আপনি ব্যবহার করেন না এমন জিনিস আনার চেয়ে আরও সুনির্দিষ্ট।
আদি শবিত

দয়া করে আমার সম্পাদনা পর্যালোচনা করুন, আমি নিখোঁজ নেমস্পেসের এসডিও যুক্ত করেছি।
রই ড্যান্টন

5
<ফাইলসিসটেম> আর টিএস নয়। এটি সি ++ 17 এর অংশ। আপনার সম্ভবত উত্তরটি সেই অনুযায়ী আপডেট করা উচিত।
IInspectable

ম্যাক ব্যবহারকারীদের জন্য দ্রষ্টব্য, এর জন্য কমপক্ষে OSX 10.15 (ক্যাটালিনা) প্রয়োজন।
জাস্টিন

45

উইন 32 এপিআই ব্যবহার করে আপনি ফাইন্ডফার্সফায়াল এবং ফাইন্ডনেস্টফিল ফাংশন ব্যবহার করতে পারেন ।

http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx

ডিরেক্টরিগুলির পুনরাবৃত্তির ট্র্যাভারসাল করার জন্য আপনাকে অবশ্যই FIN_ATTRIBUTE_DIRECTORY বিট সেট আছে কিনা তা পরীক্ষা করতে প্রতিটি WIN32_FIND_DATA.dwFileAributes অবশ্যই পরীক্ষা করতে হবে । যদি বিটটি সেট করা থাকে তবে আপনি সেই ডিরেক্টরিটি পুনরাবৃত্তভাবে ফাংশনটিতে কল করতে পারেন। বিকল্পভাবে আপনি পুনরাবৃত্ত কলের একই প্রভাব সরবরাহের জন্য স্ট্যাক ব্যবহার করতে পারেন তবে খুব দীর্ঘ পথ গাছের জন্য স্ট্যাকের ওভারফ্লো এড়ানো।

#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>

using namespace std;

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();

    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        } 

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 && 
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {
                    files.push_back(path + L"\\" + ffd.cFileName);
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
}

int main(int argc, char* argv[])
{
    vector<wstring> files;

    if (ListFiles(L"F:\\cvsrepos", L"*", files)) {
        for (vector<wstring>::iterator it = files.begin(); 
             it != files.end(); 
             ++it) {
            wcout << it->c_str() << endl;
        }
    }
    return 0;
}

19
আপনি এটি লিখতে কত সময় নিলেন? আমি মনে করি সি ++ আঠায় আঠা লাগাতে এবং এটি এক লাইনে করতে কম সময় লাগবে।
ডাস্টিন গেটেজ

2
এটি একটি দুর্দান্ত, পুনরাবৃত্তিযোগ্য সমাধান (যা কখনও কখনও কার্যকর হয়!)।
জেএম

1
বিটিডব্লিউ, যদি কেউ হার্ডকডযুক্ত ("F: v cvsrepos") এর পরিবর্তে কোনও কমান্ড-লাইন প্যারামিটার আরগভি [1] গ্রহণের জন্য প্রোগ্রামটি সামান্য সম্পাদনা করতে চায় তবে মূল (আন্তঃ, চর) এর স্বাক্ষর বদলে যাবে wmain (int, wchar_t) এর মত: int wmain (int argc, wchar_t * argv [])
জেসদেব

1
ধন্যবাদ, তবে এই ফাংশনটি সিরিলিকের সাথে কাজ করে না। - б, в, г ইত্যাদি এর মতো সিরিলিক চরিত্রগুলি দিয়ে এটি কার্যকর করার কোনও উপায় আছে কি?
অমীমাংসিত_

31

আপনি এটি নতুন সি ++ 11 রেঞ্জ ভিত্তিক forএবং বুস্ট দিয়ে আরও সাধারণ করে তুলতে পারেন :

#include <boost/filesystem.hpp>

using namespace boost::filesystem;    
struct recursive_directory_range
{
    typedef recursive_directory_iterator iterator;
    recursive_directory_range(path p) : p_(p) {}

    iterator begin() { return recursive_directory_iterator(p_); }
    iterator end() { return recursive_directory_iterator(); }

    path p_;
};

for (auto it : recursive_directory_range(dir_path))
{
    std::cout << it << std::endl;
}

5
বৃদ্ধির দরকার নেই। ওপি বিশেষত স্ট্যান্ডার্ড সি ++ চেয়েছিল।
ক্রেগ বি

23

একটি দ্রুত সমাধান সি এর ডাইরেন্ট.এ লাইব্রেরি ব্যবহার করছে ।

উইকিপিডিয়া থেকে ওয়ার্কিং কোড টুকরা:

#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) {
    struct dirent *entry;
    DIR *dp;

    dp = opendir(path);
    if (dp == NULL) {
        perror("opendir: Path does not exist or could not be read.");
        return -1;
    }

    while ((entry = readdir(dp)))
        puts(entry->d_name);

    closedir(dp);
    return 0;
}

5
এই রুটিনটি পুনরাবৃত্ত হয় না।
ব্যবহারকারী 501138

@ টিমকুপার অবশ্যই তা করেন না, ডাইরেন্টটি পিক্সিক নির্দিষ্ট।
ভোরাক

1
আসলে এটা করে ভিসি কাজ ++, যদি তোমরা ++, টনি Ronkko দ্বারা চাক্ষুষ সি জন্য dirent.h একটি বন্দর পেতে। এটা FOSS। আমি এই চেষ্টা করেছি এবং এটি কাজ করে।
user1741137

10

উপরের উল্লিখিত বুস্ট :: ফাইল সিস্টেমের পাশাপাশি আপনি ডাব্লুএক্সউজেটস :: ডাব্লুএক্সডির এবং কিউটি :: কিউডিআর পরীক্ষা করতে চাইতে পারেন ।

ডাব্লুএক্সউজেডস এবং কিউটি উভয়ই ওপেন সোর্স, ক্রস প্ল্যাটফর্ম সি ++ ফ্রেমওয়ার্ক।

wxDirপুনরাবৃত্তিমূলকভাবে Traverse()একটি সহজ GetAllFiles()ফাংশন ব্যবহার করে ফাইলগুলি ট্র্যাভার করার একটি নমনীয় উপায় সরবরাহ করে । পাশাপাশি আপনি ট্র্যাভারসালটি GetFirst()এবং GetNext()ফাংশনগুলি প্রয়োগ করতে পারেন (আমি ধরে নিই যে ট্র্যাভার্স () এবং গেটএলফিলস () হ'ল এমন মোড়ক যা শেষ পর্যন্ত গেটফ্রাস্ট () এবং গেটনেক্সট () ফাংশন ব্যবহার করে)।

QDirডিরেক্টরি স্ট্রাকচার এবং তাদের সামগ্রীতে অ্যাক্সেস সরবরাহ করে। কিউডিআর দিয়ে ডিরেক্টরিগুলি অতিক্রম করার বিভিন্ন উপায় রয়েছে। আপনি QDirIterator :: সাবডাইরেক্টরিজ পতাকা দ্বারা ইনস্ট্যান্ট করা হয়েছে এমন QDirIterator সহ ডিরেক্টরি সামগ্র (উপ ডিরেক্টরি সহ) পুনরাবৃত্তি করতে পারেন। আর একটি উপায় হল কিউডিরের গেটইন্ট্রিলিস্ট () ফাংশনটি ব্যবহার করা এবং পুনরাবৃত্তির ট্র্যাভারসাল বাস্তবায়ন করা।

এখানে নমুনা কোড রয়েছে ( এখান থেকে # উদাহরণ 8-5 থেকে নেওয়া ) যা সমস্ত উপ ডিরেক্টরিতে পুনরাবৃত্তি করতে পারে তা দেখায়।

#include <qapplication.h>
#include <qdir.h>
#include <iostream>

int main( int argc, char **argv )
{
    QApplication a( argc, argv );
    QDir currentDir = QDir::current();

    currentDir.setFilter( QDir::Dirs );
    QStringList entries = currentDir.entryList();
    for( QStringList::ConstIterator entry=entries.begin(); entry!=entries.end(); ++entry) 
    {
         std::cout << *entry << std::endl;
    }
    return 0;
}

ডক্সিজেন QT কে তার ওএস সামঞ্জস্যতার স্তর হিসাবে ব্যবহার করে। মূল সরঞ্জামগুলি কেবলমাত্র ডিরেক্টরী স্টাফগুলিতে (এবং অন্যদের অনুপাতে) কোনও জিইউআই ব্যবহার করে না।
deft_code

7

বুস্ট :: ফাইল সিস্টেম পুনরাবৃত্ত_ডাইরেক্টরি_টিরেটর সরবরাহ করে যা এই কাজের জন্য বেশ সুবিধাজনক:

#include "boost/filesystem.hpp"
#include <iostream>

using namespace boost::filesystem;

recursive_directory_iterator end;
for (recursive_directory_iterator it("./"); it != end; ++it) {
    std::cout << *it << std::endl;                                    
}

1
"এটা" দয়া করে কি? একটি সিনট্যাক্স ত্রুটি আছে না? এবং আপনি কিভাবে "শেষ" খাওয়াবেন? (= কীভাবে আমরা সমস্ত
দিরকে

1
@YO_ আপনি ঠিক বলেছেন যে একটি টাইপো ছিল, পুনরাবৃত্ত_ডাইরেক্টরি_টিরেটরর জন্য ডিফল্ট কনস্ট্রাক্টর একটি "অবৈধ" পুনরাবৃত্তকারী নির্মাণ করবে, যখন আপনি দিরের উপর দিয়ে পুনরাবৃত্তি শেষ করবেন এটি "এটি" অবৈধ হয়ে যাবে এবং "শেষ" এর সমান হবে
ডিকোব্রআজ

5

আপনি পসিক্স সিস্টেমে সি বা সি ++ তে একটি ফাইল সিস্টেমের হায়ারার্কি ব্যবহার করতে ftw(3)বাnftw(3) হাঁটতে পারেন ।


github.com/six-k/dtreetrawl/blob/… এর উদাহরণ রয়েছে। কোডটি আরও কয়েকটি স্টাফ করে, তবে এটি nftw()ব্যবহারের জন্য একটি ভাল টিউটোরিয়াল কাজ করে ।
ছয়-কে

4

আপনি না। সি ++ স্ট্যান্ডার্ডের ডিরেক্টরিগুলির কোনও ধারণা নেই। স্ট্রিংটিকে একটি ফাইল হ্যান্ডলে পরিণত করা বাস্তবায়নের উপর নির্ভর করে। স্ট্রিংয়ের বিষয়বস্তু এবং এটিতে মানচিত্রগুলি ওএস নির্ভর। মনে রাখবেন যে ওএস লিখতে সি ++ ব্যবহার করা যেতে পারে, সুতরাং এটি এমন একটি স্তরে ব্যবহৃত হয় যেখানে কোনও ডিরেক্টরিতে পুনরাবৃত্তি করতে হবে তা জিজ্ঞাসা করা এখনও সংজ্ঞায়িত হয়নি (কারণ আপনি ডিরেক্টরি পরিচালনা কোডটি লিখছেন)।

এটি কীভাবে করবেন তার জন্য আপনার ওএস এপিআই ডকুমেন্টেশনটি দেখুন। আপনার যদি পোর্টেবল হওয়ার দরকার হয় তবে বিভিন্ন ওএসের জন্য আপনার কাছে একগুচ্ছ # আইফডিফ এস থাকতে হবে ।


4

আপনি সম্ভবত বুথ বা সি ++ 14 এর পরীক্ষামূলক ফাইল সিস্টেম স্টাফ দিয়ে সেরা হতে পারেন। যদি আপনি কোনও অভ্যন্তরীণ ডিরেক্টরি পার্স করছেন (যেমন প্রোগ্রামটি বন্ধ হওয়ার পরে আপনার প্রোগ্রামের জন্য ডেটা সঞ্চয় করার জন্য ব্যবহৃত হয়), তবে একটি সূচি ফাইল তৈরি করুন যাতে ফাইলের সামগ্রীর সূচি থাকে of যাইহোক, আপনাকে সম্ভবত ভবিষ্যতে বুস্ট ব্যবহার করতে হবে, সুতরাং যদি আপনি এটি ইনস্টল না করে থাকেন তবে এটি ইনস্টল করুন! দ্বিতীয়ত, আপনি শর্তসাপেক্ষ সংকলন ব্যবহার করতে পারেন, যেমন:

#ifdef WINDOWS //define WINDOWS in your code to compile for windows
#endif

প্রতিটি মামলার কোড https://stackoverflow.com/a/67336/7077165 থেকে নেওয়া হয়েছে

#ifdef POSIX //unix, linux, etc.
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) {
    struct dirent *entry;
    DIR *dp;

    dp = opendir(path);
    if (dp == NULL) {
        perror("opendir: Path does not exist or could not be read.");
        return -1;
    }

    while ((entry = readdir(dp)))
        puts(entry->d_name);

    closedir(dp);
    return 0;
}
#endif
#ifdef WINDOWS
#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>

using namespace std;

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();

    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        } 

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 && 
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {
                    files.push_back(path + L"\\" + ffd.cFileName);
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
}
#endif
//so on and so forth.

2

ফাইল সিস্টেম ট্র্যাভারসাল, যেমন open()এবং এর জন্য আপনাকে ওএস-নির্দিষ্ট ফাংশনগুলি কল করতে হবে readdir()। সি স্ট্যান্ডার্ড কোনও ফাইল সিস্টেম সম্পর্কিত ফাংশন নির্দিষ্ট করে না।


সি ++ এর কী হবে? আইস্ট্রিমে এমন কোনও ফাংশন রয়েছে?
অ্যারন মাইনপা

2
কেবল ফাইলের জন্য। কোনও ধরণের "ডিরেক্টরিতে আমাকে সমস্ত ফাইল দেখান" ফাংশন নেই।
1800 তথ্য

1
@ 1800: ডিরেক্টরিগুলি ফাইলগুলি।
অরবিটে লাইটনেস রেস

2

আমরা 2019 সালে আছি We আমাদের মধ্যে ফাইল সিস্টেমের স্ট্যান্ডার্ড লাইব্রেরি রয়েছে C++Filesystem libraryযেমন পাথ, নিয়মিত ফাইল, ও ডিরেক্টরিগুলি হিসাবে ফাইল সিস্টেম এবং তাদের উপাদান, উপর অপারেশন সম্পাদন জন্য সুবিধা প্রদান করে।

আপনি যদি বহনযোগ্যতার বিষয় বিবেচনা করছেন তবে এই লিঙ্কটিতে একটি গুরুত্বপূর্ণ নোট রয়েছে । এটা বলে:

যদি একটি হায়ারার্কিকাল ফাইল সিস্টেম বাস্তবায়নের অ্যাক্সেসযোগ্য না হয় বা এটি প্রয়োজনীয় ক্ষমতা সরবরাহ না করে তবে ফাইল সিস্টেম লাইব্রেরি সুবিধাগুলি অনুপলব্ধ হতে পারে। অন্তর্নিহিত ফাইল সিস্টেম দ্বারা সমর্থন না করা থাকলে কিছু বৈশিষ্ট্য উপলব্ধ নাও থাকতে পারে (যেমন এফএটি ফাইল সিস্টেমে প্রতীকী লিঙ্কের অভাব রয়েছে এবং একাধিক হার্ডলিঙ্ক নিষিদ্ধ করেছে)। এই ক্ষেত্রে ত্রুটিগুলি অবশ্যই রিপোর্ট করতে হবে।

ফাইল সিস্টেম লাইব্রেরিটি মূলত এই হিসাবে বিকাশিত হয়েছিল boost.filesystem, প্রযুক্তিগত স্পেসিফিকেশন আইএসও / আইইসি টিএস 18822: 2015 হিসাবে প্রকাশিত হয়েছিল এবং অবশেষে সি ++ 17 হিসাবে আইএসও সি ++ এ একীভূত হয়েছিল। বুস্ট বাস্তবায়ন বর্তমানে সি ++ 17 লাইব্রেরির চেয়ে বেশি সংকলক এবং প্ল্যাটফর্মগুলিতে উপলব্ধ।

@ আদি-শবিত এই প্রশ্নের উত্তর দিয়েছেন যখন এটি স্টাড :: পরীক্ষামূলক অংশ ছিল এবং তিনি এই উত্তরটি ২০১ 2017 সালে আপডেট করেছেন I আমি গ্রন্থাগার সম্পর্কে আরও বিশদ দিতে এবং আরও বিশদ উদাহরণ দেখাতে চাই।

std :: ফাইল সিস্টেম :: recursive_directory_iterator এমন একটি LegacyInputIteratorডিরেক্টরি যা ডিরেক্টরি ডিরেক্টরিতে অন্তর্ভুক্ত হয় এবং সমস্ত উপ-ডিরেক্টরিতে পুনরাবৃত্তভাবে প্রবেশ করে। প্রতিটি ডিরেক্টরি এন্ট্রি একবারে একবার পরিদর্শন করা বাদে পুনরাবৃত্তির ক্রমটি অনির্ধারিত।

আপনি যদি সাব-ডাইরেক্টরিগুলির প্রবেশগুলিতে পুনরাবৃত্তভাবে পুনরাবৃত্তি করতে না চান, তবে ডিরেক্টরি_ iterator ব্যবহার করা উচিত।

উভয় পুনরাবৃত্তির ডিরেক্টরি_তন্ত্রের একটি বস্তু প্রদান করে । directory_entryমত বিভিন্ন দরকারী সদস্য ফাংশন আছে is_regular_file, is_directory, is_socket, is_symlinkইত্যাদি path()সদস্য ফাংশন আয় একটি অবজেক্ট এসটিডি :: ফাইলসিস্টেম :: পাথ এবং এটি পেতে ব্যবহার করা যেতে পারে file extension, filename, root name

নীচের উদাহরণ বিবেচনা করুন। আমি Ubuntuটার্মিনালটি ব্যবহার করে এটি ব্যবহার এবং সংকলন করছি

g ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall

#include <iostream>
#include <string>
#include <filesystem>

void listFiles(std::string path)
{
    for (auto& dirEntry: std::filesystem::recursive_directory_iterator(path)) {
        if (!dirEntry.is_regular_file()) {
            std::cout << "Directory: " << dirEntry.path() << std::endl;
            continue;
        }
        std::filesystem::path file = dirEntry.path();
        std::cout << "Filename: " << file.filename() << " extension: " << file.extension() << std::endl;

    }
}

int main()
{
    listFiles("./");
    return 0;
}

1

আপনি না। স্ট্যান্ডার্ড সি ++ কোনও ডিরেক্টরি ধারণাটি প্রকাশ করে না। বিশেষত এটি কোনও ডিরেক্টরিতে সমস্ত ফাইল তালিকাভুক্ত করার উপায় দেয় না।

সিস্টেম () কলগুলি ব্যবহার করা এবং ফলাফলগুলি বিশ্লেষণ করা একটি ভয়ঙ্কর হ্যাক। সর্বাধিক যুক্তিসঙ্গত সমাধানটি হ'ল কিছু ধরণের ক্রস-প্ল্যাটফর্ম লাইব্রেরি যেমন কিউটি বা এমনকি পসিক্স ব্যবহার করা


1

আপনি ব্যবহার করতে পারেন std::filesystem::recursive_directory_iterator। তবে সাবধান থাকুন এর মধ্যে প্রতীকী (নরম) লিঙ্ক রয়েছে। এগুলি এড়াতে চাইলে আপনি ব্যবহার করতে পারেন is_symlink। ব্যবহারের উদাহরণ:

size_t directorySize(const std::filesystem::path& directory)
{
    size_t size{ 0 };
    for (const auto& entry : std::filesystem::recursive_directory_iterator(directory))
    {
        if (entry.is_regular_file() && !entry.is_symlink())
        {
            size += entry.file_size();
        }
    }
    return size;
}

1
শেষ কিন্তু কমপক্ষে নয়, আগের উত্তরগুলির চেয়ে আসলে ভাল।
মেহরান সায়াদতি সৈয়দ

0

আপনি যদি উইন্ডোজটিতে থাকেন তবে আপনি FindNextFile API এর সাথে FindFirstFile ব্যবহার করতে পারেন। প্রদত্ত পাথটি কোনও ফাইল বা ডিরেক্টরি কিনা তা পরীক্ষা করতে আপনি FindFileData.dwFileAttributes ব্যবহার করতে পারেন। যদি এটি কোনও ডিরেক্টরি হয় তবে আপনি পুনরাবৃত্তভাবে অ্যালগরিদম পুনরাবৃত্তি করতে পারেন।

এখানে, আমি কিছু কোড একসাথে রেখেছি যা একটি উইন্ডোজ মেশিনে সমস্ত ফাইল তালিকাভুক্ত করে।

http://dreams-soft.com/projects/traverse-directory


0

ফাইল ট্রি ওয়াক ftwহ'ল পথটিতে পুরো ডিরেক্টরি গাছটি প্রাচীর করার জন্য একটি পুনরাবৃত্ত উপায়। আরও বিশদ এখানে

দ্রষ্টব্য: আপনি ftsএমনটি ব্যবহার করতে পারেন যা লুকানো ফাইলগুলি এড়িয়ে যেতে পারে .বা ..বা.bashrc

#include <ftw.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>

 
int list(const char *name, const struct stat *status, int type)
{
     if (type == FTW_NS)
     {
         return 0;
     }

     if (type == FTW_F)
     {
         printf("0%3o\t%s\n", status->st_mode&0777, name);
     }

     if (type == FTW_D && strcmp(".", name) != 0)
     {
         printf("0%3o\t%s/\n", status->st_mode&0777, name);
     }
     return 0;
}

int main(int argc, char *argv[])
{
     if(argc == 1)
     {
         ftw(".", list, 1);
     }
     else
     {
         ftw(argv[1], list, 1);
     }

     return 0;
}

আউটপুট নিম্নলিখিত মত দেখাচ্ছে:

0755    ./Shivaji/
0644    ./Shivaji/20200516_204454.png
0644    ./Shivaji/20200527_160408.png
0644    ./Shivaji/20200527_160352.png
0644    ./Shivaji/20200520_174754.png
0644    ./Shivaji/20200520_180103.png
0755    ./Saif/
0644    ./Saif/Snapchat-1751229005.jpg
0644    ./Saif/Snapchat-1356123194.jpg
0644    ./Saif/Snapchat-613911286.jpg
0644    ./Saif/Snapchat-107742096.jpg
0755    ./Milind/
0644    ./Milind/IMG_1828.JPG
0644    ./Milind/IMG_1839.JPG
0644    ./Milind/IMG_1825.JPG
0644    ./Milind/IMG_1831.JPG
0644    ./Milind/IMG_1840.JPG

আপনি যদি *.jpg, *.jpeg, *.pngএকটি নির্দিষ্ট প্রয়োজনের জন্য কোনও ফাইলের নামের (উদাহরণস্বরূপ: সমস্ত ফাইলগুলির সন্ধান করা) ব্যবহার করতে চান তবে আমাদের বলুন fnmatch

 #include <ftw.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <iostream>
 #include <fnmatch.h>

 static const char *filters[] = {
     "*.jpg", "*.jpeg", "*.png"
 };

 int list(const char *name, const struct stat *status, int type)
 {
     if (type == FTW_NS)
     {
         return 0;
     }

     if (type == FTW_F)
     {
         int i;
         for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
             /* if the filename matches the filter, */
             if (fnmatch(filters[i], name, FNM_CASEFOLD) == 0) {
                 printf("0%3o\t%s\n", status->st_mode&0777, name);
                 break;
             }
         }
     }

     if (type == FTW_D && strcmp(".", name) != 0)
     {
         //printf("0%3o\t%s/\n", status->st_mode&0777, name);
     }
     return 0;
 }

 int main(int argc, char *argv[])
 {
     if(argc == 1)
     {
         ftw(".", list, 1);
     }
     else
     {
         ftw(argv[1], list, 1);
     }

     return 0;
 }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.