2009-05-06 9 views
29

Funkcja API Windows CopyFile ma argument BOOL bFailIfExists, który pozwala kontrolować, czy plik docelowy ma zostać zastąpiony, jeśli istnieje.sposób wykonywania boost :: system plików copy_file z nadpisaniem

Funkcja nie ma takiego argumentu i zakończy się niepowodzeniem, jeśli plik docelowy istnieje. Czy istnieje elegancki sposób użycia funkcji boost copy_file i zastąpienia pliku docelowego? A może lepiej skorzystać z interfejsu API systemu Windows? Moja obecna platforma docelowa to Windows, ale wolę używać STL i tam, gdzie to możliwe, zwiększać niezależność platformy kodu.

Dziękuję.

Odpowiedz

52

Nie ma trzeciej enum argument copy_file, boost :: plików :: copy_option :: overwrite_if_exists

copy_file(source_path,destination_path,copy_option::overwrite_if_exists); 
+0

Dzięki anno. Nie wiedziałem o tym. Wydaje się, że ta opcja została dodana kiedyś między wersją 1.35, której używałem, gdy zadałem pytanie, a wersją 1.41, której teraz używam. Nie mogę znaleźć zmiany w historii zmian w bibliotece. W każdym razie problem rozwiązany. Nie jestem pewien, czy powinienem teraz zaakceptować twoją odpowiedź, może zapytam na meta. –

+2

Uwaga: wydaje się, że istnieje problem z tym trzecim argumentem w implementacji POSIX. Zobacz odpowiedź od Witalija. –

+2

@DanivanderMeer na rzecz odwiedzających tę stronę, [błąd został naprawiony wiele lat temu] (https://svn.boost.org/trac/boost/ticket/4930). –

9

Sprawdza czy plik docelowy istnieje pierwszy i jeśli nie następnie wyjąć go:

if (exists (to_fp)) 
    remove (to_fp); 
copy_file (from_fp, to_fp); 

Albo jeśli martwisz się o pliku występującego pomiędzy testem i kopii następnie można zapisać do pliku tymczasowego a następnie zmień nazwę na plik docelowy.

+0

Tak, jest to możliwe. Ale co, jeśli operacja kopiowania nie powiedzie się? Już usunąłeś cel. Nie ma tej samej semantyki transakcyjnej jak CopyFile. –

+0

Czy zmiana nazwy nie daje tego? W każdym razie patrząc na źródło boost API nie pozwala na opcjonalne zastąpienie pliku. Możesz im to zaproponować jako ulepszenie. W międzyczasie możesz wziąć własną kopię funkcji copy_file boost i zmodyfikować ją, aby pobrać dodatkowy parametr "overwrite" bool. –

+0

Cóż, domyślam się, że logika zmiany nazwy zadziała, ale miałem nadzieję, że w bibliotece jest coś, co rozwiązuje to i że sam nie będę musiał tego rozwiązywać :). Spróbuję zaproponować to jako ulepszenie. Myślę, że jest to logiczna i pomocna funkcja. W każdym razie, dzięki za pomoc. Prawdopodobnie na razie używam CopyFile. –

2

Czy istnieje elegancki sposób wykorzystania funkcji boost copy_file i zastąpienia pliku docelowego?

Najwyraźniej nie ma bezpośredniego interfejsu API, aby to zrobić.

A może lepiej użyć interfejsu API systemu Windows? Moja obecna platforma docelowa to Windows, ale wolę używać STL i tam, gdzie to możliwe, zwiększać niezależność platformy kodu.

Z dokumentacji:

Propozycja, N1975, aby zawierać Boost.Filesystem w Raporcie Technicznym 2 został przyjęty przez Komitet Standardów C++. Biblioteka Boost.Filesystem pozostanie w zgodzie z propozycją systemu plików TR2, ponieważ przechodzi ona przez proces TR2. Należy jednak pamiętać, że przestrzeń nazw i rozdrobnienie nagłówka różnią się między Boost.Filesystem a propozycją TR2.

Co zdecydowanie sugeruje, że trzymanie się z boost::filesystem jest dobrym pomysłem.

17

Strzeż boost :: copy_file z copy_option :: overwrite_if_exists! Jeśli plik docelowy istnieje i jest mniejszy niż źródło, funkcja będzie nadpisywać tylko pierwszy bajt wielkości (from_file) pliku docelowego.

Przynajmniej dla mnie był to zastrzeżenie odkąd domniemywać copy_option :: overwrite_if_exists wpływa plików a nie zawartości

+0

Próbowałem odtworzyć na mojej platformie (Windows), ale nie mogłem. nadpisanie wpływa na cały plik, niezależnie od rozmiaru. Na jakiej platformie testowałeś? –

+0

IFAIK copy_option :: overwrite_if_exists istnieje tylko w * nix (przynajmniej w boost-1.44 dla systemu plików v2). Ale można go łatwo zobaczyć w kodzie źródłowym, plik jest otwarty do zapisu z O_WRONLY, ale bez zestawu flag O_TRUNC. –

+0

Używam boost 1.41. copy_option :: overwrite_if_exists istnieje również dla Windows. copy_file wywołuje API win32 CopyFile (wersja A lub W) z bFailIfExists zgodnie z opcją przekazaną do boost :: copy_file. Czy więc zachowanie systemu Windows i POSIX jest inne? –

Powiązane problemy