Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Dateiarbeit mit fwrite fread

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
22.03.2006, 16:36 Uhr
~Tester
Gast


Hi Leute,

ich habe eine kleines Programm geschrieben, welches alle dateien eines Ordners zusammengefügt in eine neue datei schreiben soll. aber irgendwie ist das, was der in die datei schreibt immer größer als das was er gelesen hat, und auch als der Puffer!

Weis nicht mehr weiter.. :-((


C++:
#include <dirent.h>        
#include <stdio.h>
#include <stdlib.h>

main()
{
  DIR * dir_p;
  struct dirent * dir_entry_p;
  FILE * pFile;
  FILE * pwFile;
  
  long lSize;
  char * buffer;

  
  dir_p = opendir(".");

  while( NULL != (dir_entry_p = readdir(dir_p)))
  {
            
    printf("GOT FILE %s \n", dir_entry_p->d_name);
      
     pFile = fopen (dir_entry_p->d_name,"rb");
    
      if ((pFile!=NULL) && !(strstr(dir_entry_p->d_name,"dir.exe")))
        {
        
            printf("OPENED => %s \n",dir_entry_p->d_name);
    
             // obtain file size.
              fseek (pFile , 0 , SEEK_END);
              lSize = ftell (pFile);
              rewind (pFile);

             printf("EST. PUFFER => %ld \n",lSize);
            
              // allocate memory to contain the whole file.
              buffer = (char*) malloc (lSize);
              if (buffer != NULL)
              {

                  // copy the file into the buffer.
                  fread (buffer,1,lSize,pFile);

                  /*** the whole file is loaded in the buffer. ***/

                    pwFile = fopen ("C:\myfile.txt","w+");
                    fwrite (buffer,1,lSize,pwFile);
                    fclose (pwFile);
                    printf("WRITE PUFFER TO FILE => %ld \n",lSize);
                  
                  // terminate
                  fclose (pFile);
                    printf("CLOSE FILE => %s \n",dir_entry_p->d_name);
                  free (buffer);
                    printf("FREE PUFFER");
              }
              else
              {
                  printf("NO PUFFER THERE => %s \n",dir_entry_p->d_name);
              }
        }
        else
        {
            printf("NOT OPENED => %s \n",dir_entry_p->d_name);
        }

  }

  closedir(dir_p);

}





Vielen Dank für eure Hilfe!!!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
22.03.2006, 16:53 Uhr
ao

(Operator)


Wenn du alle Dateien in einem File zusammenfügen willst, darfst du die Zieldatei nicht mit "w+" öffnen, dann wird sie nämlich bei jedem Öffnen überschrieben:

Zitat von MSDN-Hilfe zu fopen:
"w+"
Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.

Du musst die Datei auch gar nicht jedesmal schließen und wieder neu öffnen. Öffne sie einmal vor Beginn, halte sie während der Schleife offen und schreib immer nur rein und schließ sie am Ende.
Die Größenunterschiede erklären sich dadurch, dass du Binärdateien liest (fopen ("..", "rb") und Textdateien schreibst (fopen (""..", "w")). Binärdateien schreiben mit "wb".

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
22.03.2006, 19:39 Uhr
~Tester
Gast


Vielen Dank für die gute Antwort!

Ich werde das gleich mal umsetzen :-)

Eine Frage hätte ich trotzdem noch: Wie müsste ich jetzt vorgehen wenn ich auch alle Dateien aus Unterordnern mit einbeziehen wollte?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
23.03.2006, 08:49 Uhr
ao

(Operator)



Zitat von ~Tester:
Wie müsste ich jetzt vorgehen wenn ich auch alle Dateien aus Unterordnern mit einbeziehen wollte?

Beim Abarbeiten des Verzeichnisses(mit while (readdir != NULL)) bekommst du nacheinander alle Einträge, egal ob Datei oder Ordner. Die dirent-Struktur hat ein Feld, an dem du erkennen kannst, was du in der Hand hast. Wenn es ein Ordner ist, musst du den mit opendir öffnen und kannst ihn anschließend mit einer readdir-Schleife ausquetschen. closedir nicht vergessen.

Das ist übrigens eine typische Anwendung für Rekursion.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
23.03.2006, 10:31 Uhr
~Tester
Gast


Und welches Feld?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.03.2006, 11:13 Uhr
~Tester
Gast


Das mit der Rekursion habe ich soweit realisiert denke ich und ich erkenne jetzt auch ob es ein ordner ist... aber irgendwie findet er die dateien im ordner nicht! Habe ich den Pfad falsch aufgebaut oder woran kann das liegen?

Vielen Dank nochmal :-)


C++:
#include <dirent.h>        
#include <stdio.h>
#include <stdlib.h>

Lesen(DIR *,FILE *);

main()
{
  DIR * dir_p;
  FILE * pwFile;
  
  dir_p = opendir(".");
  pwFile = fopen ("m:\myfile.txt","ab");
  
  Lesen (dir_p, pwFile);
  
  fclose (pwFile);
  closedir(dir_p);

  return 0;
}


Lesen(DIR * dir_p, FILE * pwFile)
{

struct dirent * dir_entry_p;
FILE * pFile;
long lSize;
char * buffer;
char FileInfo[128];

printf("WHILE SCHLEIFE START\n");

while( NULL != (dir_entry_p = readdir(dir_p)))
  {
            
    printf("\n\nGOT ITEM %s \n", dir_entry_p->d_name);
      
    if ( NULL !=  opendir(dir_entry_p))
        {
        printf("**ordner**\n");
        printf("REKURSION START\n");
        printf("LINK IST => %s \n",dir_entry_p);
        Lesen(dir_entry_p, pwFile);
        printf("REKURSION BEENDET\n");
        }
    else
    {
        printf("**Datei**\n");
    }
      
     //eine Datei zum lesen öffnen
     pFile = fopen (dir_entry_p->d_name,"rb");
      
      if ((pFile!=NULL) && !(strstr(dir_entry_p->d_name,"dir.exe")))
        {
        
            printf("OPENED => %s \n",dir_entry_p->d_name);
    
            //Dateigröße und Größe für Puffer bestimmen
            fseek (pFile , 0 , SEEK_END);
            lSize = ftell (pFile);
            rewind (pFile);
            printf("EST. PUFFER => %ld \n",lSize);
            
            //Dateigröße,Pfadinformationen in Archiv schreiben
            sprintf(FileInfo, "%s%ld", dir_entry_p->d_name, lSize);
            fwrite (FileInfo,1,strlen(FileInfo),pwFile);
            
            //Speicher für Puffer anfordern
            buffer = (char*) malloc (lSize);
            
              if (buffer != NULL)
              {
                //Daten aus aktueller Datei in den Puffer lesen
                fread (buffer,1,lSize,pFile);
                //Daten von Puffer in Archiv schreiben
                fwrite (buffer,1,lSize,pwFile);
                printf("WRITE PUFFER TO FILE => %ld \n",lSize);
                //Datei schliessen
                fclose (pFile);
                printf("CLOSE FILE => %s \n",dir_entry_p->d_name);
                //Puffer leeren
                free (buffer);
                printf("FREE PUFFER");
              }
              else
              {
                //Wenn kein Speicher angefordert werden konnte..
                printf("NO PUFFER THERE => %s \n",dir_entry_p->d_name);
              }
              
        }
        else
        {
            //Wenn Datei nicht geöffnet werden konnte
            printf("NO FILE ACCESS! => %s \n",dir_entry_p->d_name);
        }

  }
    
    
    
    
}



 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
23.03.2006, 13:15 Uhr
ao

(Operator)


Ich hätte so gedacht:

C++:
/* Nur die Hauptschleife */
while( NULL != (dir_entry_p = readdir(dir_p)))
  {
            
    printf("\n\nGOT ITEM %s \n", dir_entry_p->d_name);

    switch (dir_entry_p->d_type)
    {
        case DT_DIR:
        printf("**ordner**\n");
        printf("REKURSION START\n");
        printf("LINK IST => %s \n",dir_entry_p); Das hier könnte Ärger machen -> einen Pointer als String formatiert ausdrucken!
        Lesen(dir_entry_p, pwFile);  /* ### rekursiver Aufruf ### */
        printf("REKURSION BEENDET\n");
        break;

        case DT_FILE:
        printf("**Datei**\n");
        /* Datei lesen und kopieren */
        break;

        default: /* andere Einträge, z.B. Devices, die hängen auf Unix-artigen Computern ebenfalls im Dateisystem */
        break;
    }



Zu dir_entry_p->d_type vergleiche das hier: www.gnu.org/software/libc/manual/html_node/Directory-Entries.html#Directory-Entries

Wenn der Filename nicht stimmt, kann das daran liegen, dass dir_entry_p->d_name nur der Filename *innerhalb* des Directory ist. Du musst dann zuerst den Pfad zur Datei zusammenbasteln, bevor du fopen machst. Eventuell den Pfad als weiteren Parameter in Lesen () reinreichen.

ao

Dieser Post wurde am 23.03.2006 um 13:16 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
23.03.2006, 13:33 Uhr
~Tester
Gast


Jetzt bekomme ich folgendes einen Fehler

undefined Symbol d_type...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
23.03.2006, 14:30 Uhr
ao

(Operator)


Dann schau mal nach, ob es das Member d_type überhaupt gibt. Falls nicht, hast du Pech gehabt und musst es anders machen - diese ganze Directory-Geschichte ist kein Teil des ANSI-Standards, also kann jeder libc-Hersteller das machen, wie er will, leider.

Welches Betriebssystem, welcher Compiler, und soll das in C gemacht werden oder geht auch C++?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
23.03.2006, 14:35 Uhr
~Tester
Gast


Sollte schon in C gemacht werden...

Nutze Windows XP mit dem Borland c++ Compiler 5.5.1
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: