cross-device kopieren mit std::filesystem
-
Hallo,
#include <iostream> #include <fstream> #include <filesystem> namespace fs = std::filesystem; int main(){ std::ofstream{"file"}.write("000", 3); std::string from = "file", to = "/mnt"; fs::copy_file(from, to, fs::copy_options::overwrite_existing); }
vs.
#include <iostream> #include <fstream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main(){ std::ofstream{"file"}.write("000", 3); std::string from = "file", to = "/mnt"; fs::copy_file(from, to, fs::copy_option::overwrite_if_exists); }
Ich versuche eine Datei auf ein Cross-Link Device zu kopieren, d.h. auf ein anderes Dateisystem. Mit Boost.Filesystem funktioniert das auch. Mit den Bordmitteln des neuen Standards jedoch nicht. Der Boost-Code wird erfolgreich ausgeführt. Mit
<filesystem>
wird eine Exception geworfen:terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: cannot copy file [file] [/mnt]
Die Datei wird angelegt, der Inhalt bleibt jedoch leer. Scheint wohl als wäre die Implementation von Boost immernoch besser als der Standard. Abwarten?
gcc --version
=>gcc (GCC) 9.1.0
clang --version
=>clang version 8.0.1
Mit Linux unterwegs.
-
Der Boost-Code wird erfolgreich ausgeführt.
Wird die Datei denn kopiert oder erkennt boost lediglich den Fehler nicht?
-
@manni66 sagte in cross-device kopieren mit std::filesystem:
Wird die Datei denn kopiert oder erkennt boost lediglich den Fehler nicht?
Die Datei wird mitsamt den drei Nullen kopiert. Mit dem Standard wird nur die Datei angelegt.
-
vermutlich verlangt die std implementierung dass der zielpfad auch auf eine datei zeigt und nicht auf ein Verzeichnis.
Daher änder mal den to part auf "/mnt/file"
-
@firefly sagte in cross-device kopieren mit std::filesystem:
Daher änder mal den to part auf "/mnt/file"
Erzeugt das gleiche Ergebnis.
-
Was kommt denn für ein Error Code raus wenn Du
bool copy_file( const path& from, const path& to, copy_options options, error_code& ec );
nimmst?
@firefly sagte in cross-device kopieren mit std::filesystem:
Daher änder mal den to part auf "/mnt/file"
Das auf jeden Fall: [fs.op.copy.file]/4.1.2:
[Report an error as specified in [fs.err.report] if:]
exists(to)
istrue
andis_regular_file(to)
isfalse
, [...]
-
Erstes Beispiel:
#include <fstream> #include <filesystem> #include <iostream> int main(){ std::ofstream{"file"}.write("000", 3); std::string from = "file", to = "/mnt/file"; std::error_code ec; if(std::filesystem::copy_file(from, to, std::filesystem::copy_options::overwrite_existing, ec)) std::cout << "Success\n"; else std::cerr << ec.value() << ':' << ec.message() << '\n'; }
Ausgabe; Datei wird angelegt, fehlen jedoch drei Nullen, es sei denn, ich führe das Programm mit Root-Rechten aus:
1:Operation not permitted
Dann mit Boost (ohne Root):
#include <fstream> #include <boost/filesystem.hpp> #include <iostream> int main(){ std::ofstream{"file"}.write("000", 3); std::string from = "file", to = "/mnt/file"; boost::system::error_code ec; boost::filesystem::copy_file(from, to, boost::filesystem::copy_option::overwrite_if_exists, ec); std::cerr << ec.value() << ':' << ec.message() << '\n'; }
Ausgabe:
0:Success
Dann
blkid /dev/smth
:/dev/smth /mnt type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096)
Versuche eine ext4-Datei auf ein exfat-Filesystem zu kopieren. Dann hab ich das hier versucht:
Und
{ echo '000' > /mnt/f && cat /mnt/f; } && echo $?;
:000 0
Dann hab ich noch
touch f; test -f f && echo yes
ohne Root-Permissions versucht:touch: setting times of 'f': Operation not permitted yes
-
push
-
pop