In dem Buch “Linux-Programmierung” habe ich einige interessante Beispiele zum kopieren von Dateien unter Linux gefunden.
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main() {
char c;
int in, out;
// open - mit dem Systemaufruf open kann ein neuer Dateideskriptor erstellt werden
// ---------------------
// Modus -> Beschreibung
// ---------------------
// O_RDONLY -> nur zum lesen oeffnen
// O_WONLY -> nur zum schreiben oeffnen
// O_RDWR -> zum lesen und schreiben oeffnen
// ---------------------
// optionaler Modus -> Beschreibung
// ---------------------
// O_APPEND -> am Ende der Datei schreiben
// O_TRUNC -> Inhalt der vorhandenen Datei wird geloescht
// O_CREAT -> erstellt die Datei mit Berechtigungen
// O_EXCL -> stellt sicher, dass nicht zwei Programme
// die selbe Datei, zur gleichen Zeit erstellen
// ---------------------
// Berechtigung -> Beschreibung
// ---------------------
// S_IRUSR -> Lesen, Eigentuemer (owner)
// S_IWUSR -> Schreiben, Eigentuemer (owner)
// S_IXUSR -> Ausfuehren, Eigentuemer (owner)
// S_IRGRP -> Lesen, Gruppe (group)
// S_IWGRP -> Schreiben, Gruppe (group)
// S_IXGRP -> Ausfuehren, Gruppe (group)
// S_IROTH -> Lesen, Andere (others)
// S_IWOTH -> Schreiben, Andere (others)
// S_IXOTH -> Ausfuehren, Andere (others)
//
// weitere Infos unter: man 2 open
//
// 1 MB Datei erstellen -> dd if=/dev/zero of=file.in bs=1024 count=10240
//
// Datei "file.in" zum lesen oeffnen
in = open("file.in", O_RDONLY);
// Datei "file.out" erstellen (Eigentuemer -> Lesen + Schreiben)
out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
// Zeichen fuer Zeichen einlesen ...
while(read(in,&c,1) == 1) {
// ... und jedes Zeichen in die neue Datei schreiben
write(out,&c,1);
}
exit(0);
}
Wir gehen in diesem Beispiel davon aus, dass die Datei “file.in” (10 MB) bereits vorhanden ist.
Test:
dd if=/dev/zero of=file.in bs=1024 count=10240
time ./copy_system
Ausgabe:
./copy_system 7,54s user 88,56s system 99% cpu 1:36,23 total
Wie wir sehen, dauerte der Kopiervorgang insgesamt ~ 1 1/2 Minuten, da wir die Datei Zeichen für Zeichen kopiert haben, im nächsten Beispiel werden jeweills 1024 Byte eingelesen und in die neue Datei geschrieben.
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main() {
char block[1024];
int in, out, nread;
// open - mit dem Systemaufruf open kann ein neuer Dateideskriptor erstellt werden
// ---------------------
// Modus -> Beschreibung
// ---------------------
// O_RDONLY -> nur zum lesen oeffnen
// O_WONLY -> nur zum schreiben oeffnen
// O_RDWR -> zum lesen und schreiben oeffnen
// ---------------------
// optionaler Modus -> Beschreibung
// ---------------------
// O_APPEND -> am Ende der Datei schreiben
// O_TRUNC -> Inhalt der vorhandenen Datei wird geloescht
// O_CREAT -> erstellt die Datei mit Berechtigungen
// O_EXCL -> stellt sicher, dass nicht zwei Programme
// die selbe Datei, zur gleichen Zeit erstellen
// ---------------------
// Berechtigung -> Beschreibung
// ---------------------
// S_IRUSR -> Lesen, Eigentuemer (owner)
// S_IWUSR -> Schreiben, Eigentuemer (owner)
// S_IXUSR -> Ausfuehren, Eigentuemer (owner)
// S_IRGRP -> Lesen, Gruppe (group)
// S_IWGRP -> Schreiben, Gruppe (group)
// S_IXGRP -> Ausfuehren, Gruppe (group)
// S_IROTH -> Lesen, Andere (others)
// S_IWOTH -> Schreiben, Andere (others)
// S_IXOTH -> Ausfuehren, Andere (others)
//
// weitere Infos unter: man 2 open
//
// 1 MB Datei erstellen -> dd if=/dev/zero of=file.in bs=1024 count=10240
//
// Datei "file.in" zum lesen oeffnen
in = open("file.in", O_RDONLY);
// Datei "file.out" erstellen (Eigentuemer -> Lesen + Schreiben)
out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
// 1024 Byte werden eingelesen ...
while((nread = read(in,block,sizeof(block))) > 0) {
// ... und in die neue Datei geschrieben
write(out,block,nread);
}
exit(0);
}
Test:
rm file.out
time ./copy_block
Ausgabe:
./copy_block 0,01s user 0,15s system 98% cpu 0,158 total
Hier dauerte der gleiche Vorgang nur noch ~ 0,16 Sekunden. Daher nutzt man zum kopieren von ganzen Festplatten auch gerne “dd”! :-) Zum Schluss noch ein Beispiel, wo die Bibliothek (stdio.h) von C genutzt wurden.
#include <stdio.h>
#include <stdlib.h>
int main() {
char c;
FILE *in, *out;
// fopen - oeffnet eine Datei
// ---------------------
// Modus -> Beschreibung
// ---------------------
// r -> nur zum lesen oeffnen
// w -> nur zum schreiben oeffnen
// a -> am Ende der Datei anhaengen
// r+ -> zum Aktualisieren oeffnen (schreiben + lesen)
// w+ -> zum Aktualisieren oeffnen, auf Null-Laenge abschneiden
// a+ -> zum Aktualisieren oeffnen, am Ende der Datei anhaengen
//
// weitere Infos unter: man fopen
//
// fgetc - liefert das naechste Byte als Zeichen aus einem Datei-Stream zurueck,
// die Funktion liefert EOF (End of File) beim Ende der Datei bzw.
// bei einem Fehler zurück
//
// weitere Infos unter: man fgetc
//
// fputc - schreibt ein Zeichen in einen Ausgabe-Datei-Stream
//
// weitere Infos unter: man fputc
//
// 1 MB Datei erstellen -> dd if=/dev/zero of=file.in bs=1024 count=10240
//
// Datei "file.in" zum lesen oeffnen
in = fopen("file.in", "r");
// Datei "file.out" erstellen (Eigentuemer -> Lesen + Schreiben)
out = fopen("file.out", "w");
// Zeichen fuer Zeichen einlesen (+ interner Puffer in der Struktur FILE) ...
while((c = fgetc(in)) != EOF) {
// ... und jedes Zeichen in die neue Datei schreiben
fputc(c,out);
}
exit(0);
}
Test:
rm file.out
time ./copy_system_2
Ausgabe:
./copy_system_2 1,10s user 0,09s system 99% cpu 1,196 total
Hier brauchen wir für 10 MB zirka 1,2 Sekunden, was um einiges schneller ist als das erste Beispiel, wo die Zeichen einzeln kopiert wurden.