2011-07-24 6 views
9

Wygląda na to, że to pytanie jest dość proste, ale nie mogę znaleźć jasnego rozwiązania do kopiowania plików w języku C bez zależności od platformy.Jak mogę skopiować pliki w języku C bez zależności od platformy?

Użyłem wywołania system() w moim projekcie open source do tworzenia katalogu, kopiowania plików i uruchamiania programów zewnętrznych. Działa bardzo dobrze w systemie Mac OS X i innych systemach Unix-ish, ale zawiedzie w systemie Windows. Problemem było:

system("cp a.txt destination/b.txt"); 
  • Windows używa backslashy do separatora ścieżki. (w porównaniu z ukośnikami w Uniksie)
  • System Windows używa "kopii" dla polecenia kopiowania wewnętrznego. (vs cp w systemie Unix-ish)

Jak mogę napisać kod kopiowania bez zależności?

(Faktycznie, pisałem makra, aby rozwiązać ten problem, ale to nie jest cool. http://code.google.com/p/npk/source/browse/trunk/npk/cli/tests/testutil.h, L22-56)

+0

Problem nie jest zwisające na „kopiowanie” jak wspomniałem powyżej. – lqez

Odpowiedz

6

Musisz użyć standardowych funkcji bibliotecznych C w stdio.h.

W szczególności wystarczą fopen, fread, fwrite i fclose.

Pamiętaj, aby włączyć opcję b ("binary") w flagach do fopen.

[edytuj]

Niestety, same nazwy plików (Forward-ukośniki vs. back-ukośniki) są wciąż zależne od platformy. Będziesz potrzebował czegoś w rodzaju #ifdef lub podobnego, aby sobie z tym poradzić.

Lub możesz użyć cross-platform toolkit.

+0

Dziękuję za odpowiedź. Ale wieloplatformowe zestawy narzędzi są zbyt duże dla mojego małego projektu. Czy nie ma prostego rozwiązania problemu z ukośnikiem? – lqez

+2

Ponieważ organizacje katalogowe są specyficzne dla platformy, nie ma całkowicie trywialnego sposobu. Jednak na poziomie interfejsu API system Windows akceptuje ukośniki lub ukośniki w ścieżkach (jest to powłoka cmd.exe wymagająca ukośników odwrotnych). Tak więc, dopóki twoje nazwy Uniksa nigdy nie zawierają odwrotnego ukośnika (i prawdopodobnie nie dwukropka), będziesz w porządku. –

+0

@ Jonathan: OK, przyznaję, że tego nie wiedziałem. A co z nazwami plików z ukośnikami, które są legalne w systemie Windows?Może powinienem go kiedyś spróbować :-) – Nemo

0

Użyj standardowej biblioteki C stdio.h. Najpierw otwórz plik wejściowy do odczytu przy użyciu fopen(inputFilename, "rb") i otwórz plik wyjściowy do zapisu przy użyciu fopen(outputFilename, "wb"), skopiuj zawartość za pomocą fread i fwrire. Następnie zamknij oba pliki, używając fclose.

8

Funkcja system() jest o wiele trudniejsza niż jest warta; wywołuje powłokę w oddzielnym procesie i zazwyczaj należy jej unikać.

Zamiast fopen()a.txt i dest/b.text i używać getc()/putc() zrobić kopiowania (ponieważ biblioteka standardowa jest bardziej prawdopodobne, aby zrobić stronę wyrównany buforowania niż ty)

FILE *src = fopen("a.txt", "rb"); 
FILE *dst = fopen("dest/b.txt", "wb"); 
int i; 
for (i = getc(src); i != EOF; i = getc(src)) 
{ 
    putc(i, dst); 
} 
fclose(dst); 
fclose(src); 
+0

Dziękuję za odpowiedź. Ale nie rozwiązuje problemu z separatorem ścieżek. – lqez

+1

Według: http://msdn.microsoft.com/en-us/library/77859s1t(v=VS.71).aspx separatory ścieżek są problemem 'system()', a nie 'fopen()'. Zawodzi w systemie z powodu wywołania powłoki. – Dave

+0

Naprawdę doceniam Twoją pomoc. – lqez

Powiązane problemy