dateien zusammenfügen



  • Mit fread kannst du effizient große Mengen Daten schaufeln.

    #include <stdio.h>
    
    char* files_available ( char** files, unsigned n ) {
    	FILE* fp; unsigned i;
    
    	for ( i=0; i<n; i++ ) {
    		if ( NULL == ( fp = fopen ( files[i], "rb" )))
    			return files[i];
    		else
    			fclose ( fp );
    	}
    	return NULL;
    }
    
    int join_files ( char* joined, char** files, unsigned n ) {
    	FILE* in, *out; unsigned bytes; char buf [4096] = {0};
    	unsigned i; char* fname = NULL;
    
    	if ( NULL != ( fname = files_available ( files, n ))) { // Sind wir alle daaa?!
    		printf ( "Can't open %s for reading!\n", fname );
    		return 1; // Nein!
    	}
    
    	if ( NULL == ( out = fopen ( joined, "wb" ))) { 
    		printf ( "Can't open %s for writing!\n", joined );
    		return 1; 
    	}
    
    	for ( i = 0; i < n; i++ ) {
    		if ( NULL == ( in = fopen ( files[i], "rb"))) {
    			printf ( "Can't open %s for reading!\n", files[i] );
    			fclose ( out );
    			return 1;
    		}
    		while ( 0 != ( bytes = fread ( buf, sizeof(char), sizeof(buf), in ))) {
    			fwrite ( buf, sizeof(char), bytes, out ) ;
    		}
    		if ( ferror (in) || ferror (out) ) {
    				printf ( "IO Error!" );
    				fclose (in), fclose (out);
    				return 1;
    		}
    		fclose ( in );
    	}
    
    	fclose ( out );
    	return 0;
    }
    
    int main() {
    	char* files[] = { "test1.txt", "test2.txt", "test3.txt" };
    
    	if ( join_files ( "joined.txt", files, 3 ))
    		puts ( "Can't join files!" );
    	else
    		puts ( "Files joined successfully!" );
    
    	return 0;
    }
    

    Gruß,
    B.B.



  • fein das zumindest einer code posten darf 😡



  • Big Brother schrieb:

    Mit fread kannst du effizient große Mengen Daten schaufeln.

    Ist das wirklich effizienter als die zeichenweisen Funktionen? Die haben ihren Puffer immerhin implizit auf eine passende Grösse eingestellt...
    Wieviel Overhead bleibt da noch?
    🙂



  • µngbd schrieb:

    Ist das wirklich effizienter als die zeichenweisen Funktionen? Die haben ihren Puffer immerhin implizit auf eine passende Grösse eingestellt...
    Wieviel Overhead bleibt da noch?
    🙂

    Ich bin der Meinung, das mal gemessen zu haben. Ist aber schon so lange her, dass ich nur noch eine blasse Erinnerung daran habe, dass fread die Nase vorn hatte.

    aus der coder hölle schrieb:

    fein das zumindest einer code posten darf 😡

    Und was ist mit dir kaputt, Bruder?



  • Falls es nur ums Ergebnis geht, kann man vielleicht sogar darauf verzichten, den Compiler anzuwerfen.

    copy *.txt join.txt
    


  • volkard schrieb:

    Falls es nur ums Ergebnis geht, kann man vielleicht sogar darauf verzichten, den Compiler anzuwerfen.

    copy *.txt join.txt
    

    Das wäre zu einfach.

    Irgendwie werden die DOS-Commands vernachlässigt.

    In C würde ich die mit read() binär einlesen und in die Ausgabe schreiben.
    Das geht definitiv am schnellsten. buffered I/O ist langsamer.



  • Scheppertreiber schrieb:

    In C würde ich die mit read() binär einlesen und in die Ausgabe schreiben.
    Das geht definitiv am schnellsten. buffered I/O ist langsamer.

    Nur schade, dass es in C kein read() gibt.
    🙂



  • read() geht genauso wenig wie copy... also bleibt nur eine lösung wie big brother postete oder man erfreut sich an einer schönen #ifdef verschachtelung



  • oder die langsamere version von µngbd.
    🙂



  • aus dem coder himmel schrieb:

    oder die langsamere version

    Und das hast du auf allen Systemen nachgemessen?
    🙂



  • wenn alle systeme die glibc verwenden dann schon 😉



  • aus der coder hölle schrieb:

    wenn alle systeme die glibc verwenden dann schon 😉

    Und die ist natürlich gar nicht portabel.
    🙄



  • wenn du unbedingt für jedes char ne funktion aufrufen willst dann lass dich durch mich nicht aufhalten, sonst nimm fread...



  • aus der coder hölle schrieb:

    wenn du unbedingt für jedes char ne funktion aufrufen willst dann lass dich durch mich nicht aufhalten, sonst nimm fread...

    Oder man: getc, das ist gar keine Funktion.
    🙂



  • also fread nimmt zumindest in der glibc intern falls mehr als 20 chars gelesen werden ein memcpy() schneller gehts eher selten, natürlich wenn du jetzt mit einer super exotischen hardware daher kommst mags schon sein das du recht hast aber das glaub ich eher weniger, kann natürlich auch sein das ich mich geirrt hab, ist immer so ein chaos in dem code...

    axo mal ein auszug für getc

    int
    _IO_getc (fp)
         FILE *fp;
    {
      int result;
      CHECK_FILE (fp, EOF);
      _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
      _IO_flockfile (fp);
      result = _IO_getc_unlocked (fp);
      _IO_funlockfile (fp);
      _IO_cleanup_region_end (0);
      return result;
    }
    


  • Wenn man es wirklich schnell haben will, dann sollte man auf systemabhängige Funktionen zurückgreifen.

    (zB man: tee(2) in Linux oder zumindest Memorymappedfiles)


Anmelden zum Antworten