Kopieren Sie eine Datei auf vernünftige, sichere und effiziente Weise

Lesezeit: 6 Minuten

Ich suche nach einer guten Möglichkeit, eine Datei (binär oder Text) zu kopieren. Ich habe mehrere Beispiele geschrieben, alle funktionieren. Aber ich möchte die Meinung erfahrener Programmierer hören.

Ich vermisse gute Beispiele und suche einen Weg, der mit C++ funktioniert.

ANSI-C-WEG

#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;
}

POSIX-WEG (K&R verwendet dies in “Die C-Programmiersprache”, mehr Low-Level)

#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;
}

KISS-C++-Streambuffer-WAY

#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;
}

KOPIERALGORITHMUS-C++-WEG

#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;
}

EIGENER-BUFFER-C++-WEG

#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;
}

LINUX-WEG // benötigt Kernel >= 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;
}

Umfeld

  • GNU/LINUX (Archlinux)
  • Kernel 3.3
  • GLIBC-2.15, LIBSTDC++ 4.7 (GCC-LIBS), GCC 4.7, Coreutils 8.16
  • Verwenden von RUNLEVEL 3 (Mehrbenutzer, Netzwerk, Terminal, keine GUI)
  • INTEL SSD-Postville 80 GB, zu 50 % gefüllt
  • Kopieren Sie eine 270 MB OGG-VIDEO-DATEI

Schritte zum Reproduzieren

 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

Ergebnisse (verwendete CPU-ZEIT)

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  

Dateigröße ändert sich nicht.
sha256sum gibt die gleichen Ergebnisse aus.
Die Videodatei ist weiterhin abspielbar.

Fragen

  • Welche Methode würden Sie bevorzugen?
  • Kennen Sie bessere Lösungen?
  • Sehen Sie irgendwelche Fehler in meinem Code?
  • Kennen Sie einen Grund, eine Lösung zu vermeiden?

  • FSTREAM (KISS, Streambuffer)
    Ich mag dieses sehr, weil es wirklich kurz und einfach ist. Soweit ich weiß, ist der Operator << für rdbuf() überladen und konvertiert nichts. Richtig?

Danke

Aktualisierung 1

Ich habe die Quelle in allen Beispielen so geändert, dass das Öffnen und Schließen der Dateideskriptoren in die Messung einbezogen wird Uhr(). Es gibt keine weiteren wesentlichen Änderungen im Quellcode. Das Ergebnis ändert sich nicht! habe ich auch benutzt Zeit um meine Ergebnisse zu überprüfen.

Aktualisierung 2

ANSI C-Beispiel geändert: Der Zustand der while-Schleife ruft nicht mehr an Feof () stattdessen zog ich um Angst () in den Zustand. Es sieht so aus, als ob der Code jetzt 10.000 Takte schneller läuft.

Messung geändert: Die bisherigen Ergebnisse wurden immer zwischengespeichert, weil ich die alte Kommandozeile wiederholt habe rm to.ogv && sync && time ./program für jedes Programm ein paar Mal. Jetzt starte ich das System für jedes Programm neu. Die ungepufferten Ergebnisse sind neu und zeigen keine Überraschung. Die ungepufferten Ergebnisse haben sich nicht wirklich verändert.

Wenn ich die alte Kopie nicht lösche, reagieren die Programme anders. Überschreiben einer bestehenden Datei gepuffert ist mit POSIX und SENDFILE schneller, alle anderen Programme sind langsamer. Vielleicht die Optionen kürzen oder schaffen einen Einfluss auf dieses Verhalten haben. Das Überschreiben bestehender Dateien mit derselben Kopie ist jedoch kein realer Anwendungsfall.

Durchführen der Kopie mit vgl dauert ungepuffert 0,44 Sekunden und gepuffert 0,30 Sekunden. Damit vgl ist etwas langsamer als das POSIX-Beispiel. Sieht gut aus für mich.

Vielleicht füge ich auch Proben und Ergebnisse hinzu mmap() und copy_file() von boost::filesystem.

Aktualisierung 3

Ich habe dies auch auf eine Blogseite gestellt und etwas erweitert. Einschließlich spleißen(), eine Low-Level-Funktion des Linux-Kernels. Vielleicht folgen noch weitere Beispiele mit Java.
http://www.ttyhoney.com/blog/?page_id=69

  • fstream ist definitiv eine gute Option für Dateioperationen.

    – Chris

    17. April 2012 um 16:40 Uhr

  • richelbilderbeek.nl/CppCopy_file.htm

    – Irgendein Korn

    17. April 2012 um 16:41 Uhr

  • Sie haben den faulen Weg vergessen: system(“cp from.ogv to.ogv”);

    – fbafelipe

    17. April 2012 um 16:45 Uhr

  • #include <copyfile.h> copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags);

    – Martin York

    17. April 2012 um 16:53 Uhr

  • Entschuldigen Sie, dass ich mich so spät einschalte, aber ich würde keine davon als “sicher” bezeichnen, da sie keine Fehlerbehandlung haben.

    – Richard Kettlewell

    22. Oktober 2016 um 14:36 ​​Uhr

Kopieren Sie eine Datei auf vernunftige sichere und effiziente Weise
Martin York

Kopieren Sie eine Datei auf vernünftige Weise:

#include <fstream>

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

    dst << src.rdbuf();
}

Dies ist so einfach und intuitiv zu lesen, dass es den Aufpreis wert ist. Wenn wir es viel tun, ist es besser, auf OS-Aufrufe an das Dateisystem zurückzugreifen. ich bin mir sicher boost hat eine Methode zum Kopieren von Dateien in seiner Dateisystemklasse.

Es gibt eine C-Methode für die Interaktion mit dem Dateisystem:

#include <copyfile.h>

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

  • copyfile ist nicht tragbar; Ich denke, es ist spezifisch für Mac OS X. Es existiert sicherlich nicht unter Linux. boost::filesystem::copy_file ist wahrscheinlich die portabelste Art, eine Datei über das native Dateisystem zu kopieren.

    – Mike Seymour

    17. April 2012 um 17:35 Uhr


  • @MikeSeymour: copyfile() scheint eine BSD-Erweiterung zu sein.

    – Martin York

    17. April 2012 um 17:47 Uhr

  • @duedl0r: Nein. Objekte haben Destruktoren. Der Destruktor für Streams ruft automatisch close() auf. codereview.stackexchange.com/q/540/507

    – Martin York

    12. Juni 2013 um 19:48 Uhr

  • @duedl0r: Ja. Aber das ist wie zu sagen “wenn die Sonne untergeht”. Sie können wirklich schnell nach Westen laufen und Ihren Tag vielleicht etwas länger machen, aber die Sonne wird untergehen. Es sei denn, Sie haben Fehler und Speicherlecks (es wird den Gültigkeitsbereich verlassen). Aber da es hier keine dynamische Speicherverwaltung gibt, kann es kein Leck geben und sie werden aus dem Geltungsbereich verschwinden (genauso wie die Sonne untergeht).

    – Martin York

    13. Juni 2013 um 15:29 Uhr

  • Wickeln Sie es dann einfach in einen Bereichsblock { } ein

    – paulm

    10. April 2015 um 15:42 Uhr

Mit C++17 ist die Standardmethode zum Kopieren einer Datei das Einschließen der <filesystem> Header und Verwendung:

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);

Die erste Form entspricht der zweiten mit copy_options::none als Optionen verwendet (siehe auch copy_file).

Die filesystem Die Bibliothek wurde ursprünglich als entwickelt boost.filesystem und schließlich ab C++17 zu ISO C++ zusammengeführt.

  • Warum gibt es keine einzelne Funktion mit einem Standardargument, wie z bool copy_file( const std::filesystem::path& from, const std::filesystem::path& to, std::filesystem::copy_options options = std::filesystem::copy_options::none);?

    – Jepessen

    2. November 2017 um 11:03 Uhr

  • @Jepessen Ich bin mir da nicht sicher. Vielleicht ist es wirklich egal.

    – manlio

    17. November 2017 um 10:26 Uhr


  • @Jepessen in der Standardbibliothek ist sauberer Code von größter Bedeutung. Überladungen (im Gegensatz zu einer Funktion mit Standardparametern) machen die Absicht des Programmierers klarer.

    – März 2377

    10. September 2019 um 6:27 Uhr

  • @Peter Dies sollte jetzt wahrscheinlich die akzeptierte Antwort sein, da C ++ 17 verfügbar ist.

    – Martin York

    30. Januar 2020 um 15:02 Uhr

Kopieren Sie eine Datei auf vernunftige sichere und effiziente Weise
Kartoffelklatsche

Zu viele!

Der “ANSI C”-Wege-Puffer ist redundant, da a FILE ist bereits gepuffert. (Die Größe dieses internen Puffers ist was BUFSIZ eigentlich definiert.)

Der “OWN-BUFFER-C++-WAY” wird beim Durchlaufen langsam sein fstream, das viel virtuelles Dispatching durchführt und wiederum interne Puffer oder jedes Stream-Objekt verwaltet. (Der “COPY-ALGORITHMUS-C++-WAY” leidet darunter nicht, da der streambuf_iterator Klasse umgeht die Stream-Schicht.)

Ich bevorzuge den “KOPIER-ALGORITHMUS-C++-WEG”, aber ohne einen zu konstruieren fstreamerstellen Sie einfach nackt std::filebuf Fälle, in denen keine tatsächliche Formatierung erforderlich ist.

Was die Leistung betrifft, sind POSIX-Dateideskriptoren unschlagbar. Es ist hässlich, aber tragbar und schnell auf jeder Plattform.

Der Linux-Weg scheint unglaublich schnell zu sein – vielleicht ließ das Betriebssystem die Funktion zurückkehren, bevor die E/A beendet war? In jedem Fall ist das für viele Anwendungen nicht portabel genug.

BEARBEITEN: Ah, “natives Linux” kann die Leistung verbessern, indem es Lese- und Schreibvorgänge mit asynchronem I/O verschachtelt. Das Stapeln von Befehlen kann dem Festplattentreiber helfen, zu entscheiden, wann er am besten suchen soll. Sie können zum Vergleich Boost Asio oder pthreads ausprobieren. Was “POSIX-Dateideskriptoren nicht schlagen kann” angeht … nun, das stimmt, wenn Sie irgendetwas mit den Daten machen und nicht nur blind kopieren.

  • ANSI C: Aber ich muss der Funktion fread/fwrite eine Größe geben? pubs.opengroup.org/onlinepubs/9699919799/toc.htm

    – Petrus

    17. April 2012 um 17:00 Uhr


  • @PeterWeber Nun ja, es stimmt, dass BUFSIZ ein so guter Wert ist wie jeder andere und wahrscheinlich die Dinge relativ zu einem oder “nur ein paar” Zeichen gleichzeitig beschleunigen wird. Wie auch immer, die Leistungsmessung bestätigt, dass es nicht in jedem Fall die beste Methode ist.

    – Kartoffelklatsche

    17. April 2012 um 17:03 Uhr

  • Ich habe kein tiefgreifendes Verständnis davon, daher sollte ich mit Annahmen und Meinungen vorsichtig sein. Linux-Way läuft afaik im Kernelspace. Dies sollte einen langsamen Kontextwechsel zwischen Kernelspace und Userspace vermeiden? Morgen schaue ich mir nochmal die Manpage von sendfile an. Vor einiger Zeit sagte Linus Torvalds, dass er Userspace-Dateisysteme für schwere Aufgaben nicht mag. Vielleicht ist sendfile ein positives Beispiel für seine Ansicht?

    – Petrus

    17. April 2012 um 21:05 Uhr

  • sendfile() kopiert Daten zwischen einem Dateideskriptor und einem anderen. Da dieses Kopieren innerhalb des Kernels erfolgt, sendfile() ist effizienter als die Kombination von read(2) und write(2)was die Übertragung von Daten zum und vom Benutzerbereich erfordern würde.”: Kernel.org/doc/man-pages/online/pages/man2/sendfile.2.html

    – Max Lybbert

    8. Oktober 2012 um 21:52 Uhr

  • Könnten Sie ein Beispiel für die Verwendung von raw posten filebuf Objekte?

    – Kerrek SB

    5. Mai 2014 um 12:25 Uhr

Ich möchte die machen sehr Wichtiger Hinweis, dass die LINUX-Methode, die sendfile() verwendet, ein großes Problem hat, da sie keine Dateien mit einer Größe von mehr als 2 GB kopieren kann! Ich hatte es nach dieser Frage implementiert und stieß auf Probleme, weil ich damit HDF5-Dateien kopierte, die viele GB groß waren.

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

sendfile() überträgt höchstens 0x7ffff000 (2.147.479.552) Bytes und gibt die Anzahl der tatsächlich übertragenen Bytes zurück. (Dies gilt sowohl für 32-Bit- als auch für 64-Bit-Systeme.)

Qt hat eine Methode zum Kopieren von Dateien:

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

Beachten Sie, dass Sie dies verwenden müssen Installieren Sie Qt (Anweisungen Hier) und fügen Sie es in Ihr Projekt ein (wenn Sie Windows verwenden und kein Administrator sind, können Sie Qt herunterladen Hier stattdessen). Siehe auch diese Antwort.

  • QFile::copy ist aufgrund seiner 4k-Pufferung lächerlich langsam.

    – Nikolaus Holthaus

    26. Oktober 2017 um 18:04 Uhr

  • Die Langsamkeit wurde in neueren Versionen von behoben Qt. ich benutze 5.9.2 und die Geschwindigkeit entspricht der nativen Implementierung. Übrigens. Wenn man sich den Quellcode ansieht, scheint Qt tatsächlich die native Implementierung aufzurufen.

    – VK

    3. Dezember 2017 um 19:25 Uhr

Für diejenigen, die Boost mögen:

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);

Beachten Sie, dass boost::filesystem::path gibt es auch als wpfad für Unicode. Und das könnte man auch gebrauchen

using namespace boost::filesystem

wenn Sie diese langen Typennamen nicht mögen

  • QFile::copy ist aufgrund seiner 4k-Pufferung lächerlich langsam.

    – Nikolaus Holthaus

    26. Oktober 2017 um 18:04 Uhr

  • Die Langsamkeit wurde in neueren Versionen von behoben Qt. ich benutze 5.9.2 und die Geschwindigkeit entspricht der nativen Implementierung. Übrigens. Wenn man sich den Quellcode ansieht, scheint Qt tatsächlich die native Implementierung aufzurufen.

    – VK

    3. Dezember 2017 um 19:25 Uhr

Ich bin mir nicht ganz sicher, was ein “guter Weg” zum Kopieren einer Datei ist, aber wenn “gut” “schnell” bedeutet, könnte ich das Thema ein wenig erweitern.

Aktuelle Betriebssysteme sind seit langem darauf optimiert worden, mit dem üblichen Kopieren von Dateien fertig zu werden. Kein cleverer Code wird das übertreffen. Es ist möglich, dass sich einige Varianten Ihrer Kopiertechniken in einigen Testszenarien als schneller erweisen, in anderen Fällen jedoch höchstwahrscheinlich schlechter abschneiden.

Typischerweise die sendfile Die Funktion kehrt wahrscheinlich zurück, bevor der Schreibvorgang ausgeführt wurde, und erweckt so den Eindruck, schneller als der Rest zu sein. Ich habe den Code nicht gelesen, aber es liegt mit Sicherheit daran, dass er seinen eigenen dedizierten Puffer zuweist und Speicher gegen Zeit eintauscht. Und der Grund, warum es nicht für Dateien funktioniert, die größer als 2 GB sind.

Solange Sie es mit einer kleinen Anzahl von Dateien zu tun haben, geschieht alles in verschiedenen Puffern (dem ersten der C++-Laufzeit, wenn Sie verwenden iostreamdie OS-internen, anscheinend ein zusätzlicher Puffer in Dateigröße im Fall von sendfile). Auf die eigentlichen Speichermedien wird erst zugegriffen, wenn genügend Daten verschoben wurden, um die Mühe wert zu sein, eine Festplatte zu drehen.

Ich nehme an, Sie könnten die Leistung in bestimmten Fällen leicht verbessern. Aus dem Kopf:

  • Wenn Sie eine riesige Datei auf dieselbe Festplatte kopieren, kann die Verwendung eines Puffers, der größer als der des Betriebssystems ist, die Dinge ein wenig verbessern (aber wir sprechen hier wahrscheinlich von Gigabyte).
  • Wenn Sie dieselbe Datei auf zwei verschiedene physische Ziele kopieren möchten, werden Sie wahrscheinlich schneller die drei Dateien gleichzeitig öffnen als zwei aufrufen copy_file sequentiell (obwohl Sie den Unterschied kaum bemerken werden, solange die Datei in den Betriebssystem-Cache passt)
  • Wenn Sie es mit vielen kleinen Dateien auf einer Festplatte zu tun haben, sollten Sie sie möglicherweise in Stapeln lesen, um die Suchzeit zu minimieren (obwohl das Betriebssystem bereits Verzeichniseinträge zwischenspeichert, um zu vermeiden, wie verrückt zu suchen, und winzige Dateien die Festplattenbandbreite wahrscheinlich sowieso drastisch reduzieren werden).

All dies liegt jedoch außerhalb des Bereichs einer Allzweck-Dateikopierfunktion.

Meiner wohl erfahrenen Programmiererin zufolge sollte eine C++-Dateikopie also nur C++17 verwenden file_copy dedizierte Funktion, es sei denn, es ist mehr über den Kontext bekannt, in dem die Dateikopie erfolgt, und einige clevere Strategien können entwickelt werden, um das Betriebssystem auszutricksen.

993520cookie-checkKopieren Sie eine Datei auf vernünftige, sichere und effiziente Weise

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy