বুদ্ধিমান, নিরাপদ এবং দক্ষ উপায়ে একটি ফাইল অনুলিপি করুন


304

আমি কোনও ফাইল (বাইনারি বা পাঠ্য) অনুলিপি করার জন্য একটি ভাল উপায় অনুসন্ধান করি। আমি বেশ কয়েকটি নমুনা লিখেছি, সবাই কাজ করে। তবে আমি পাকা প্রোগ্রামারদের মতামত শুনতে চাই।

আমি ভাল উদাহরণগুলি হারিয়েছি এবং এমন একটি উপায় অনুসন্ধান করেছি যা সি ++ এর সাথে কাজ করে।

ANSI-সি-ওয়ে

#include <iostream>
#include <cstdio>    // fopen, fclose, fread, fwrite, BUFSIZ
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    // BUFSIZE default is 8192 bytes
    // BUFSIZE of 1 means one chareter at time
    // good values should fit to blocksize, like 1024 or 4096
    // higher values reduce number of system calls
    // size_t BUFFER_SIZE = 4096;

    char buf[BUFSIZ];
    size_t size;

    FILE* source = fopen("from.ogv", "rb");
    FILE* dest = fopen("to.ogv", "wb");

    // clean and more secure
    // feof(FILE* stream) returns non-zero if the end of file indicator for stream is set

    while (size = fread(buf, 1, BUFSIZ, source)) {
        fwrite(buf, 1, size, dest);
    }

    fclose(source);
    fclose(dest);

    end = clock();

    cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
    cout << "CPU-TIME START " << start << "\n";
    cout << "CPU-TIME END " << end << "\n";
    cout << "CPU-TIME END - START " << end - start << "\n";
    cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}

পজিক্স-ওয়ে ( কেএন্ডআর এটি "দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজে" আরও নিম্ন-স্তরের ব্যবহার করে)

#include <iostream>
#include <fcntl.h>   // open
#include <unistd.h>  // read, write, close
#include <cstdio>    // BUFSIZ
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    // BUFSIZE defaults to 8192
    // BUFSIZE of 1 means one chareter at time
    // good values should fit to blocksize, like 1024 or 4096
    // higher values reduce number of system calls
    // size_t BUFFER_SIZE = 4096;

    char buf[BUFSIZ];
    size_t size;

    int source = open("from.ogv", O_RDONLY, 0);
    int dest = open("to.ogv", O_WRONLY | O_CREAT /*| O_TRUNC/**/, 0644);

    while ((size = read(source, buf, BUFSIZ)) > 0) {
        write(dest, buf, size);
    }

    close(source);
    close(dest);

    end = clock();

    cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
    cout << "CPU-TIME START " << start << "\n";
    cout << "CPU-TIME END " << end << "\n";
    cout << "CPU-TIME END - START " << end - start << "\n";
    cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}

চুম্বন-সি ++ - Streambuffer একমুখী

#include <iostream>
#include <fstream>
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    ifstream source("from.ogv", ios::binary);
    ofstream dest("to.ogv", ios::binary);

    dest << source.rdbuf();

    source.close();
    dest.close();

    end = clock();

    cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
    cout << "CPU-TIME START " << start << "\n";
    cout << "CPU-TIME END " << end << "\n";
    cout << "CPU-TIME END - START " <<  end - start << "\n";
    cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}

কপি-অ্যালগরিদম-সি ++ - পথ

#include <iostream>
#include <fstream>
#include <ctime>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    ifstream source("from.ogv", ios::binary);
    ofstream dest("to.ogv", ios::binary);

    istreambuf_iterator<char> begin_source(source);
    istreambuf_iterator<char> end_source;
    ostreambuf_iterator<char> begin_dest(dest); 
    copy(begin_source, end_source, begin_dest);

    source.close();
    dest.close();

    end = clock();

    cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
    cout << "CPU-TIME START " << start << "\n";
    cout << "CPU-TIME END " << end << "\n";
    cout << "CPU-TIME END - START " <<  end - start << "\n";
    cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}

নিজস্ব-বাফার-সি ++ - পথ

#include <iostream>
#include <fstream>
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    ifstream source("from.ogv", ios::binary);
    ofstream dest("to.ogv", ios::binary);

    // file size
    source.seekg(0, ios::end);
    ifstream::pos_type size = source.tellg();
    source.seekg(0);
    // allocate memory for buffer
    char* buffer = new char[size];

    // copy file    
    source.read(buffer, size);
    dest.write(buffer, size);

    // clean up
    delete[] buffer;
    source.close();
    dest.close();

    end = clock();

    cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
    cout << "CPU-TIME START " << start << "\n";
    cout << "CPU-TIME END " << end << "\n";
    cout << "CPU-TIME END - START " <<  end - start << "\n";
    cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}

লিনাক্স-ওয়ে // এর কার্নেল> = 2.6.33 প্রয়োজন

#include <iostream>
#include <sys/sendfile.h>  // sendfile
#include <fcntl.h>         // open
#include <unistd.h>        // close
#include <sys/stat.h>      // fstat
#include <sys/types.h>     // fstat
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    int source = open("from.ogv", O_RDONLY, 0);
    int dest = open("to.ogv", O_WRONLY | O_CREAT /*| O_TRUNC/**/, 0644);

    // struct required, rationale: function stat() exists also
    struct stat stat_source;
    fstat(source, &stat_source);

    sendfile(dest, source, 0, stat_source.st_size);

    close(source);
    close(dest);

    end = clock();

    cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
    cout << "CPU-TIME START " << start << "\n";
    cout << "CPU-TIME END " << end << "\n";
    cout << "CPU-TIME END - START " <<  end - start << "\n";
    cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}

পরিবেশ

  • জিএনইউ / লিনাক্স (আর্চলিনাক্স)
  • কার্নেল ৩.৩
  • জিলিবিসি -২.১৫, এলআইবিএসটিডিসি ++ ৪.7 (জিসিসি-এলআইবিএস), জিসিসি ৪.7, কোরিউটিলস ৮.১6
  • রুনলেভেল 3 (মাল্টিউজার, নেটওয়ার্ক, টার্মিনাল, কোনও জিইউআই নেই) ব্যবহার করা হচ্ছে
  • ইনটেল এসএসডি-পোস্টভিলি 80 জিবি, 50% পর্যন্ত পূর্ণ
  • একটি 270 এমবি ওজিজি-ভিডিও-ফাইল অনুলিপি করুন

ধাপ পুনর্গঠন কর

 1. $ rm from.ogg
 2. $ reboot                           # kernel and filesystem buffers are in regular
 3. $ (time ./program) &>> report.txt  # executes program, redirects output of program and append to file
 4. $ sha256sum *.ogv                  # checksum
 5. $ rm to.ogg                        # remove copy, but no sync, kernel and fileystem buffers are used
 6. $ (time ./program) &>> report.txt  # executes program, redirects output of program and append to file

ফলাফল (সিপিইউ সময় ব্যবহার করা হয়েছে)

Program  Description                 UNBUFFERED|BUFFERED
ANSI C   (fread/frwite)                 490,000|260,000  
POSIX    (K&R, read/write)              450,000|230,000  
FSTREAM  (KISS, Streambuffer)           500,000|270,000 
FSTREAM  (Algorithm, copy)              500,000|270,000
FSTREAM  (OWN-BUFFER)                   500,000|340,000  
SENDFILE (native LINUX, sendfile)       410,000|200,000  

ফাইলসাইজ পরিবর্তন হয় না।
sha256sum একই ফলাফল মুদ্রণ।
ভিডিও ফাইলটি এখনও প্লেযোগ্য।

প্রশ্নাবলি

  • আপনি কোন পদ্ধতি পছন্দ করবেন?
  • আপনি কি আরও ভাল সমাধান জানেন?
  • আপনি আমার কোড কোন ভুল দেখতে পাচ্ছেন?
  • আপনি কি সমাধান এড়ানোর কোনও কারণ জানেন?

  • FSTREAM (KISS, Streambuffer)
    আমি সত্যিই এটি পছন্দ করি কারণ এটি সত্যিই সংক্ষিপ্ত এবং সহজ। যতদূর আমি জানি অপারেটর << rdbuf () এর জন্য অতিরিক্ত লোড হয়েছে এবং কোনও কিছুই রূপান্তর করে না। সঠিক?

ধন্যবাদ

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

আপডেট 2
এএনএসআই সি নমুনা পরিবর্তিত হয়েছে: যখন লুপের শর্তটি আর ফয়েফ () কল করে না পরিবর্তে আমি শর্তের মধ্যে ফ্রেড () সরিয়েছি । দেখে মনে হচ্ছে, কোডটি এখন 10,000 টি ঘড়ি দ্রুত চালায়।

পরিমাপ পরিবর্তিত হয়েছে: পূর্ববর্তী ফলাফলগুলি সর্বদা বাফার হত, কারণ আমি পুরানো কমান্ড লাইন আরএম টু.ওভি & অ্যান্ড সিঙ্ক এবং & সময়। / প্রোগ্রামের জন্য কয়েকবার পুনরায় পুনর্বার করেছিলাম । এখন আমি প্রতিটি প্রোগ্রামের জন্য সিস্টেমটি পুনরায় বুট করি। আনফারড ফলাফলগুলি নতুন এবং কোনও বিস্ময় প্রকাশ করে না। আনফারড ফলাফলগুলি সত্যিই পরিবর্তিত হয়নি।

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

সিপি দিয়ে অনুলিপি সম্পাদন করতে 0.44 সেকেন্ডে আনফারড অ্যান্ড 0.30 সেকেন্ডের বাফার লাগে। সুতরাং সিপি POSIX নমুনার চেয়ে কিছুটা ধীর। আমার জন্য ভাল লাগছে।

হয়তো আমিও নমুনা এবং ফলাফল যোগ mmap () এবং copy_file()বুস্ট :: ফাইলসিস্টেম থেকে।

আপডেট 3
আমি এটি একটি ব্লগ পৃষ্ঠায় রেখেছি এবং এটি কিছুটা প্রসারিত করেছি। স্প্লাইস () সহ যা লিনাক্স কার্নেল থেকে নিম্ন-স্তরের ফাংশন। সম্ভবত জাভা সহ আরও নমুনা অনুসরণ করবে। http://www.ttyhoney.com/blog/?page_id=69


5
fstreamফাইল অপারেশনের জন্য অবশ্যই একটি ভাল বিকল্প।
খ্রিস্ট


28
আপনি অলস উপায়টি ভুলে গেছেন: সিস্টেম ("cp from.ogv থেকে.ogv");
fbafelip

3
#include <copyfile.h> copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags);
মার্টিন ইয়র্ক

3
এত দেরিতে চিপিংয়ের জন্য দুঃখিত, তবে আমি এগুলির কোনওটিকেই 'নিরাপদ' হিসাবে বর্ণনা করব না কারণ তাদের কোনও পরিচালনা করার ক্ষেত্রে ত্রুটি নেই।
রিচার্ড কেটেলওয়েল

উত্তর:


258

বুদ্ধিমানভাবে একটি ফাইল অনুলিপি করুন:

#include <fstream>

int main()
{
    std::ifstream  src("from.ogv", std::ios::binary);
    std::ofstream  dst("to.ogv",   std::ios::binary);

    dst << src.rdbuf();
}

এটি পড়ার জন্য এটি এত সহজ এবং স্বজ্ঞাত যে এটি অতিরিক্ত ব্যয়ের জন্য মূল্যবান। যদি আমরা এটি অনেক কিছু করছিলাম তবে ফাইল সিস্টেমে ওএস কলগুলিতে ফিরে আসাই ভাল। আমি নিশ্চিত boostযে এর ফাইল সিস্টেম ক্লাসে একটি অনুলিপি ফাইল পদ্ধতি আছে।

ফাইল সিস্টেমের সাথে ইন্টারঅ্যাক্ট করার জন্য একটি সি পদ্ধতি রয়েছে:

#include <copyfile.h>

int
copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags);

28
copyfileবহনযোগ্য নয়; আমি মনে করি এটি ম্যাক ওএস এক্সের সাথে নির্দিষ্ট। এটি লিনাক্সটিতে অবশ্যই বিদ্যমান নেই। boost::filesystem::copy_fileনেটিভ ফাইল সিস্টেমের মাধ্যমে কোনও ফাইল অনুলিপি করার সম্ভবত সবচেয়ে বহনযোগ্য উপায়।
মাইক সিমুর

4
@ মাইকসিমুর: অনুলিপি () একটি BSD এক্সটেনশন বলে মনে হচ্ছে।
মার্টিন ইয়র্ক

10
@ duedl0r: নং অবজেক্টগুলির ডেস্ট্রাক্টর রয়েছে। স্ট্রিমগুলির ডেস্ট্রাক্টর স্বয়ংক্রিয়ভাবে কল () কল করে। কোডরেভিউ.স্ট্যাক্কেচেঞ্জঞ্জ
মার্টিন ইয়র্ক

11
@ দ্যুয়েডলিআর: হ্যাঁ তবে এটি "যদি সূর্য অস্ত যায়" বলার মতো। আপনি সত্যিই দ্রুত পশ্চিমে দৌড়াতে পারেন এবং আপনি আপনার দিনটি আরও দীর্ঘ করতে পারেন তবে সূর্য ডুবে যাচ্ছে। আপনার বাগ এবং লিক মেমরি না থাকলে (এটি সুযোগের বাইরে চলে যাবে)। তবে যেহেতু এখানে কোনও গতিশীল মেমরি পরিচালনা নেই সেখানে কোনও ফাঁস হতে পারে না এবং তারা সুযোগের বাইরে চলে যাবে (ঠিক যেমন সূর্য অস্ত যাবে)।
মার্টিন ইয়র্ক

6
তারপরে এটিকে কেবল :4} স্কোপ ব্লকে
পলম

62

সি ++ 17 দিয়ে কোনও ফাইল অনুলিপি করার স্ট্যান্ডার্ড পদ্ধতিতে <filesystem>শিরোনাম এবং ব্যবহার অন্তর্ভুক্ত থাকবে:

bool copy_file( const std::filesystem::path& from,
                const std::filesystem::path& to);

bool copy_file( const std::filesystem::path& from,
                const std::filesystem::path& to,
                std::filesystem::copy_options options);

প্রথম রূপটি দ্বিতীয়টির সমতুল্য copy_options::noneবিকল্প হিসাবে ব্যবহৃত (এটিও দেখুন copy_file)।

filesystemগ্রন্থাগার আদতে উন্নত ছিল boost.filesystemএবং পরিশেষে আইএসও C ++ সি ++ 17 এর হিসাবে মার্জ হয়েছে।


2
কেন একটি ডিফল্ট যুক্তি সহ একটি ফাংশন নেই bool copy_file( const std::filesystem::path& from, const std::filesystem::path& to, std::filesystem::copy_options options = std::filesystem::copy_options::none);?
জেপেসন

2
@ জেপেসেন আমি এটি সম্পর্কে নিশ্চিত নই সত্যিই এটা কোন ব্যাপার না
মানিলিও

স্ট্যান্ডার্ড লাইব্রেরিতে জিপসেন, ক্লিন কোডটি সর্বজনীন। অতিরিক্ত লোড (ডিফল্ট পরামিতিগুলির সাথে একটি ফাংশনের বিপরীতে) থাকা প্রোগ্রামারের উদ্দেশ্য আরও সুস্পষ্ট করে তোলে।
Mar.2.2377

@ পিটার এটি এখন সম্ভবত গ্রহণযোগ্য উত্তর হওয়া উচিত যে C ++ 17 উপলব্ধ।
মার্টিন ইয়র্ক

21

অনেক বেশী!

"এএনএসআই সি" ওয়ে বাফারটি রিফান্ড্যান্ট, যেহেতু একটি FILEইতিমধ্যে বাফার হয়েছে। (এই অভ্যন্তরীণ বাফারের আকারটি BUFSIZআসলে সংজ্ঞা দেয়)

"OWN-BUFFER-C ++ - WAY" এর ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে পড়ে যায় fstream। ("কপি-অ্যালগোরিথ-সি ++ - ওয়ে" এতে ক্ষতিগ্রস্থ হয় না, কারণ streambuf_iteratorশ্রেণিটি স্ট্রিম স্তরটিকে বাইপাস করে))

আমি "কপি-অ্যালগোরিথ-সি ++ - ওয়ে" পছন্দ করি তবে কোনটি fstreamতৈরি std::filebufনা করে যখন কোনও আসল বিন্যাসের প্রয়োজন হয় না তখন খালি নজির তৈরি করি ।

কাঁচা পারফরম্যান্সের জন্য, আপনি পসিক্স ফাইল বর্ণনাকারীদের মারতে পারবেন না। এটি কুৎসিত তবে পোর্টেবল এবং যে কোনও প্ল্যাটফর্মে দ্রুত fast

লিনাক্স উপায়টি অবিশ্বাস্যরূপে দ্রুত প্রদর্শিত হচ্ছে - সম্ভবত ওএস আই / ও শেষ হওয়ার আগে ফাংশনটি ফিরে আসতে দেয়? যাই হোক না কেন, এটি অনেক অ্যাপ্লিকেশনগুলির জন্য পর্যাপ্ত পোর্টেবল নয়।

সম্পাদনা : আহ, "নেটিভ লিনাক্স" অবিচ্ছিন্ন আই / ও দিয়ে ইন্টারলিভ রিড এবং লেখার মাধ্যমে পারফরম্যান্সের উন্নতি করতে পারে। কমান্ড পাইল আপ করতে দেওয়া ডিস্ক ড্রাইভারকে কখন সন্ধান করা ভাল তা সিদ্ধান্ত নিতে সহায়তা করে। আপনি তুলনা করার জন্য বুস্ট অসিও বা পাইথ্রেডগুলি চেষ্টা করতে পারেন। যেমন "পসিক্স ফাইল বর্ণনাকারীদের পরাজিত করতে পারে না"… ঠিক আছে যদি আপনি কেবল অন্ধভাবে অনুলিপি না করে ডেটা দিয়ে কিছু করছেন।


এএনএসআই সি: তবে আমাকে ফাংশনটি ফ্রেড / ফিরিয়ে দিতে হবে? pubs.opengroup.org/onlinepubs/9699919799/toc.htm
পিটার

@ পিটারওবার ওয়েল, হ্যাঁ, এটি সত্য যে বুফএসআইজেড যে কোনও হিসাবে খুব ভাল মানের এবং সম্ভবত একবারে এক বা "মাত্র কয়েকটি" চরিত্রের তুলনায় জিনিসগুলিকে গতি বাড়িয়ে তুলবে। যাইহোক, পারফরম্যান্সের পরিমাপটি প্রমাণ করে যে এটি কোনও ক্ষেত্রেই সেরা পদ্ধতি নয়।
পোটোটোভটার

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

5
" sendfile()। একটি ফাইল বর্ণনাকারী এবং অন্য মধ্যে কপি ডেটা কারণ এই কপি কার্নেল মধ্যে সম্পন্ন করা হয়, sendfile()সমন্বয় অধিক কার্যকরী হয় read(2)এবং write(2)যা প্রয়োজন এবং ইউজার-স্পেস থেকে ডেটা ট্রান্সফারের প্রয়োজন।": Kernel.org/doc/man-pages /online/pages/man2/sendfile.2.html
ম্যাক্স

1
আপনি কাঁচা filebufবস্তু ব্যবহারের একটি উদাহরণ পোস্ট করতে পারেন ?
কেরেরেক এসবি

14

আমি খুব গুরুত্বপূর্ণ নোটটি রাখতে চাই যে লিনাক্স পদ্ধতিটি সেন্ডফিল () ব্যবহার করে একটি বড় সমস্যা রয়েছে যে এটি 2 জিবি আকারের চেয়ে বেশি ফাইল অনুলিপি করতে পারে না! আমি এই প্রশ্নটি অনুসরণ করে এটি বাস্তবায়ন করেছি এবং সমস্যাগুলি মারছিলাম কারণ আমি অনেক জিবি আকারের এইচডিএফ 5 ফাইল অনুলিপি করতে এটি ব্যবহার করছিলাম।

http://man7.org/linux/man-pages/man2/sendfile.2.html

সেন্ডফাইল () সর্বাধিক 0x7ffff000 (2,147,479,552) বাইট স্থানান্তর করবে, বাইটের সংখ্যার প্রকৃতপক্ষে স্থানান্তরিত করবে। (এটি 32-বিট এবং 64-বিট উভয় সিস্টেমে সত্য)


1
সেন্ডফিল 64 () এর কি একই সমস্যা আছে?
গ্রেভোল্ফ

1
@ পালাদিন মনে হয় এই সীমাবদ্ধতাটি পাওয়ার জন্য সেন্ডফিল 64 তৈরি করা হয়েছিল। ম্যান পেজ থেকে: "" "মূল লিনাক্স সেন্ডফিল () সিস্টেম কলটি বড় ফাইল অফসেটগুলি পরিচালনা করার জন্য ডিজাইন করা হয়নি quently ফলস্বরূপ, লিনাক্স ২.৪ অফসেট আর্গুমেন্টের জন্য আরও বিস্তৃত প্রকারের সাথে সেন্ডফিল 64৪ () যুক্ত করেছে gl স্বচ্ছভাবে কার্নেলের পার্থক্য নিয়ে কাজ করে। ""
4

সেন্ডফিল 64 এর একই সমস্যা রয়েছে বলে মনে হচ্ছে। তবে অফসেট প্রকারের off64_tব্যবহারটি লিঙ্কযুক্ত প্রশ্নের উত্তরে প্রদর্শিত ফাইল হিসাবে বড় ফাইলগুলি অনুলিপি করতে একটি লুপ ব্যবহার করতে দেয় ।
পিসওয়ার্ল্ড

এটি মানুষের মধ্যে সজ্জিত: 'নোট করুন যে সেন্ডফাইলে একটি সফল কল () অনুরোধের চেয়ে কম বাইট লিখতে পারে; যদি ফোন না পাঠানো বাইটস থাকে তবে কলটি আবার চেষ্টা করার জন্য প্রস্তুত থাকতে হবে। ' সেন্ডফাইল বা সেন্ডফিল 64 সম্পূর্ণ কপি না হওয়া পর্যন্ত একটি লুপের মধ্যে কল করার প্রয়োজন হতে পারে।
ফিলিপ্পে লার্ডি

2

ফাইলগুলি অনুলিপি করার জন্য কিউটির একটি পদ্ধতি রয়েছে:

#include <QFile>
QFile::copy("originalFile.example","copiedFile.example");

নোট করুন যে এটি ব্যবহারের জন্য আপনাকে কিউটি ইনস্টল করতে হবে ( এখানে নির্দেশাবলী ) এবং এটি আপনার প্রকল্পে অন্তর্ভুক্ত করতে হবে (যদি আপনি উইন্ডোজ ব্যবহার করছেন এবং আপনি প্রশাসক না হন তবে আপনি এখানে পরিবর্তে কিউটি ডাউনলোড করতে পারেন )। আরো দেখুন এই উত্তর


1
QFile::copyএটি 4k বাফারিংয়ের কারণে হাস্যকরভাবে ধীরে ধীরে ।
নিকোলাস

1
আস্তে নতুন সংস্করণে স্থির করা হয়েছে Qt। আমি ব্যবহার করছি 5.9.2এবং গতি দেশীয় প্রয়োগের সাথে সমান। BTW। উত্স কোডটি একবার দেখে, Qt মনে হয় আসলে নেটিভ বাস্তবায়নটিকে কল করে।
ভি কে

1

যারা উত্সাহ চান তাদের জন্য:

boost::filesystem::path mySourcePath("foo.bar");
boost::filesystem::path myTargetPath("bar.foo");

// Variant 1: Overwrite existing
boost::filesystem::copy_file(mySourcePath, myTargetPath, boost::filesystem::copy_option::overwrite_if_exists);

// Variant 2: Fail if exists
boost::filesystem::copy_file(mySourcePath, myTargetPath, boost::filesystem::copy_option::fail_if_exists);

নোট করুন যে বুস্ট :: ফাইল সিস্টেম :: পাথ ইউনিকোডের জন্য wpath হিসাবে উপলব্ধ । এবং আপনি এটি ব্যবহার করতে পারে যে

using namespace boost::filesystem

আপনি যদি এই দীর্ঘ টাইপ নাম পছন্দ না করেন


বুস্টের ফাইল সিস্টেমে পাঠাগারটি এমন ব্যতিক্রমগুলির মধ্যে একটি যা এটি সংকলন করা প্রয়োজন। জাস্ট এফআইআই!
সাইমনসি

0

কোনও ফাইল অনুলিপি করার একটি "ভাল উপায়" কী তা আমি পুরোপুরি নিশ্চিত নই, তবে "ভাল" অর্থ "দ্রুত" অর্থ ধরে নিয়ে আমি বিষয়টিকে কিছুটা প্রসারিত করতে পারি।

বর্তমান অপারেটিং সিস্টেমগুলি মিল ফাইলের অনুলিপি চালানোর জন্য দীর্ঘকালীন অনুকূলিত হয়েছে। কোডের কোনও চালাক বিট এটি বীট করবে না। এটি সম্ভবত আপনার অনুলিপি কৌশলগুলির কিছু বৈকল্পিক কিছু পরীক্ষার দৃশ্যে দ্রুত প্রমাণিত হবে তবে তারা সম্ভবত অন্যান্য ক্ষেত্রে আরও খারাপ হতে পারে।

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

যতক্ষণ আপনি অল্প সংখ্যক ফাইলের সাথে লেনদেন করছেন, ততক্ষণ পর্যন্ত সমস্ত কিছু বিভিন্ন বাফারের অভ্যন্তরে ঘটে থাকে (আপনি যদি ব্যবহার করেন তবে সিএস + রানটাইমের প্রথমটি iostream, ওএস অভ্যন্তরীণগুলি, সম্ভবত ফাইলের আকারের অতিরিক্ত বাফার sendfile)। একটি হার্ড ডিস্ক স্পিনিংয়ের সমস্যায় যথেষ্ট পরিমাণে ডেটা স্থানান্তরিত হয়ে গেলে আসল স্টোরেজ মিডিয়াটি কেবল তখনই অ্যাক্সেস করা যায়।

আমি মনে করি আপনি নির্দিষ্ট ক্ষেত্রে পারফরম্যান্সে কিছুটা উন্নতি করতে পারেন। আমার মাথার উপরে:

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

তবে যা কিছু সাধারণ উদ্দেশ্যে ফাইল অনুলিপি ফাংশনের সুযোগের বাইরে।

সুতরাং আমার তর্কিতভাবে পাকা প্রোগ্রামারের মতামতে, একটি সি ++ ফাইল অনুলিপিটি কেবল সি ++ 17 file_copyডেডিকেটেড ফাংশনটি ব্যবহার করা উচিত , যদি না ফাইল কপিটি ঘটে থাকে সেই প্রসঙ্গে আরও কিছু না জানা থাকে এবং ওএসকে ছাড়িয়ে যাওয়ার জন্য কিছু চতুর কৌশল তৈরি করা যেতে পারে।

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