Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Lesen und Schreiben in bzw. aus einer Datei zwischen zwei Prozessen

Empfohlene Antworten

Veröffentlicht

hallo,

ich möchte in einem prozess aus einer datei einen datensatz lesen und diesen in eine pipe schreiben. in einem anderen prozess möchte ich aus der pipe diesen datensatz lesen und in eine andere datei schreiben.

ich habe also eine pipe erstellt und dieser zwei filediscriptoren zugewiesen.

anschließend habe ich mit fork() einen kindprozess erstellt. in dem kindprozess lese ich aus der quelldatei einen bestimmten datensatz und schreibe diesen in die pipe. im elternprozess lese ich den datensatz aus der pipe und schreibe ihn in die zieldatei. hier ist mein bisheriger quellcode.

anzumerken ist noch, dass ich die dateizugriffe in ein extra modul ausgelagert habe.


# include <stdio.h>

# include <sys/wait.h>

# include <errno.h>

# include <sys/time.h>

# include <unistd.h>

# include "fileio.h"


# define MAXLEN  120


///////////////MAIN//////////////////////////////////////////////

int main(int argc, char **argv)

{

   int    pid, tmp, len=0, fd[2];


   //ueberpruefe ob das Programm mit zwei Argumenten aufgerufen  

   //wurde

   if(argc!=3)

   {

      printf("Bitte geben Sie die Quell- und Zieldatei an\n");	

      return -1;

   }


   //Quell- und Zieldatei werden geoeffnet

   tmp=myopen(argv[1],argv[2]);

   if(tmp==E_OPEN_S)

   {

      printf("****************************************\n");

      printf("Fehler beim Oeffnen der Quelldatei\n");

      printf("****************************************\n");

      return -1;

   }

   if(tmp==E_OPEN_T)

   {

      printf("****************************************\n");

      printf("Fehler beim Oeffnen der Zieldatei\n");

      printf("****************************************\n");

      return -1;

   }


   //erzeugt eine Pipe zum Datenaustausch zwischen Eltern- undcKindprozess

   if(pipe(fd)==-1)

   {

      perror("pipe");

      return 1;

   }


   switch(pid=fork())

   {

      case -1:

         perror("fork");

	 return 1;


      case  0:

	 do

	{

           close(fd[0]);


	   if((len=myread(&fd[1],MAXLEN*sizeof(char))) == E_READ)

           {

	      printf("****************************************\n");

	      printf("Fehler beim Lesen der Quelldatei\n");

	      printf("****************************************\n");

	      return 1;

	   }

	   close(fd[1]);

	}while(len==MAXLEN);	


        break;


	default:

	   do

           {

		close(fd[1]);

		if((len=mywrite(&fd[0],sizeof(fd[0]))) == E_WRITE)

		{

		   printf("****************************************\n");

		   printf("Fehler beim Schreiben in die Datei\n");

		   printf("****************************************\n");

		   return 1;

		}

		close(fd[0]);

	    }while(len == MAXLEN);


            wait(0)

            break;

   }


   return 0;

}


und hier ist noch der code der ausgelagerten funktionen für die dateizugriffe

# include <sys/types.h>

# include <sys/stat.h>

# include <fcntl.h>

# include <unistd.h>

# include <stdio.h>

#include "fileio.h"


static int fd[2];

static int count;


int myopen(char quelle[], char ziel[])

{

	if( (fd[0] = open(quelle,O_RDONLY)) == -1 )

	{

		return E_OPEN_S;

	}


	if( (fd[1] = open(ziel,O_WRONLY|O_CREAT,0777)) == -1 )

	{

		return E_OPEN_T;

	}


	return 0;

}



void myclose()

{

	close(fd[0]);

	close(fd[1]);

}


int myread(void *buffer, int len)

{

	if((count=read(fd[0], buffer, len)) == -1 )

	{

		return E_READ;

	}


	return count;

}


int mywrite(void *buffer, int len)

{

	if((count=write(fd[1], buffer, len)) == -1 )

	{

		return E_WRITE;

	}


	return count;

}

die dateizugriffe funktionieren alle. das eigentliche problem ist jedoch, dass nur ein kleiner teil in die zieldatei geschrieben wird. hab ich irgendwie einen denkfehler?

while(len==MAXLEN);

Deine do/while-Schleifen ergeben überhaupt keinen Sinn. Wozu eine Schleife, wenn du sowieso im ersten Durchlauf den Deskriptor zumachst? Und welchen Sinn hat es, das Lesen bzw. Schreiben gerade dann zu wiederholen, wenn alles auf einmal geschrieben bzw. gelesen werden konnte?

Grundsätzlich kannst du bei Pipes nicht davon ausgehen, dass du alles in einem Rutsch lesen oder schreiben kannst. Darauf musst du also angemessen reagieren.

das ich die diskriptoren zu mache war ein fehler von mir. sinn der sache war eigentlich, dass ich MAXLEN bytes aus der datei lese und diese in die pipe schreibe. vom anderen prozess wird soviel wie in der pipe drin steckt gelesen und in die zieldatei geschrieben. wenn beim lesen aus der quelldatei irgendwann weniger als MAXLEN bytes gelesen werden, war dies der letzte datensatz der datei. die do-schleife ist fertig denn der rückgabewert von myread, also len, ist ungleich MAXLEN. das gleiche gilt für den anderen prozess. aber irgendwie schein ich da einen denkfehler zu haben. kann ich selber nicht bestimmen, wieviel ich in die pipe schreibe? oder was ist an meiner idee falsch?

EDIT: VIELLEICHT NOCH ZUR INFO: in die zieldatei werden genau 4 bytes geschrieben. hab das schließen der jeweiligen diskriptoren entfernt. das programm scheint auch länger zu laufen als vorher(hab ne zeitmessung drin). aber die menge an daten die geschrieben werden sind die gleichen.

Bearbeitet von cable545

Ich habe mir das nochmal genauer angesehen. Du benutzt deine Pipe gar nicht. Du benutzt den Speicher, in dem die Pipe-Deskriptoren liegen, als Puffer, und überschreibst damit die Deskriptoren und den dahinter liegenden Speicher.

Der eine Prozess muss aus der Datei lesen und in die Pipe schreiben, und der andere muss aus der Pipe lesen und in die Datei schreiben. Du brauchst also read und write für beide Prozesse.

Und sizeof(fd[0]) ist auch Unsinn. fd[0] ist ein int, also hast du da sizeof(int), was vermutlich 4 ergibt. Das wiederum erklärt die Größe der Zieldatei. Aber selbst die 4 Bytes, die du da reinschreibst, stammen weder aus der Quelldatei, noch aus der Pipe.

Ich habe mir das nochmal genauer angesehen. Du benutzt deine Pipe gar nicht. Du benutzt den Speicher, in dem die Pipe-Deskriptoren liegen, als Puffer, und überschreibst damit die Deskriptoren und den dahinter liegenden Speicher.

Der eine Prozess muss aus der Datei lesen und in die Pipe schreiben, und der andere muss aus der Pipe lesen und in die Datei schreiben. Du brauchst also read und write für beide Prozesse.

Und sizeof(fd[0]) ist auch Unsinn. fd[0] ist ein int, also hast du da sizeof(int), was vermutlich 4 ergibt. Das wiederum erklärt die Größe der Zieldatei. Aber selbst die 4 Bytes, die du da reinschreibst, stammen weder aus der Quelldatei, noch aus der Pipe.

ah ok. ich wollte das was ich aus der datei gelesen hab, unmittelbar ohne umwege in die pipe schreiben. das hab ich glad verplant, dass man für die pipe ebenfalls read() und write() brauch. ich danke dir.

ok es funzt alles. vielen dank nochmal

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.