<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Datei einlesen in eine verkettete Liste]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein kleines, eig. sogar 2 Probleme:<br />
Ich versuche eine Datei einzulesen (binär) und diese in eine verkettete Liste zu speichern um sie später über ein Socket an einen Client oder Server zu senden.</p>
<p>Probleme:<br />
i) Das ganze läuft sehr unperformant. Es dauert schon einiges an Zeit bei &gt;1MB<br />
ii)Teilweise wird nicht die ganze Datei reingeladen</p>
<p>Im folgenden Codeabschnitt ist eig. die ganze Logik des dargestellten Problemes:</p>
<pre><code class="language-cpp">#define MAX_PACKET_SIZE	1024		// Maximale Packetgroesse (in Byte)

// Packet::pos - Derzeitige Position in unserem Paket
// Packet::PacketCount - Anzahl der Pakete

struct PacketTransmission
{
	unsigned char 	data[MAX_PACKET_SIZE];	// Daten an sich
	PacketTransmission *nextPacket;			// Naechstes Paket

	bool HasNext(); 
};
struct PacketBase
{
	unsigned short op_code;		// Verwendeter Anfragecode
	unsigned int filename_length;	// Laenge des Dateinnamen
	std::string filename;		// Dateiname
	PacketTransmission *pData;	// Pointer zu unseren eigentlichen Daten
};

// Liest eine Datei in ein Paket ein
bool Packet::FileToPacket()
{
	// Datei oeffnen und jedes Zeichen auslesen und in das Paket eintragen
	std::ifstream file(pb.filename, std::ios::in | std::ios::binary);

	char buffer[MAX_PACKET_SIZE];
	// Solange durchgehen bis wie
	while(!file.eof())
	{
		file.read(buffer, MAX_PACKET_SIZE);
		this-&gt;AddString(buffer);
	}

	file.close();

	return true;
}

// Ein Byte zum Paket hinzufuegen
bool Packet::AddByte(unsigned char byte)
{
	// Wenn das aktuelle Paket voll ist, erstellen wir das naechste und verknuepfen es
	if(pos &gt;= MAX_PACKET_SIZE)
	{
		pos = 0;					// Wieder am Anfang setzen
		PacketCount++;				// Wir haben ein Paket mehr

		PacketTransmission *ptrans = new PacketTransmission;
		ptrans = pb.pData;
		// Solange durchgehen bis wir ein neues Paket frei haben
		while(ptrans-&gt;HasNext())
			ptrans = ptrans-&gt;nextPacket;

		PacketTransmission *newPacket = new PacketTransmission;
		newPacket-&gt;data[pos++] = (unsigned char)byte;
		newPacket-&gt;nextPacket = NULL;

		ptrans-&gt;nextPacket = newPacket;
	}
	// Wir haben noch Platz
	else
	{
		PacketTransmission *ptrans = new PacketTransmission;

		if(pb.pData != NULL)
		{
			ptrans = pb.pData;
			while(ptrans-&gt;HasNext())
				ptrans = ptrans-&gt;nextPacket;

			ptrans-&gt;data[pos++] = (unsigned char)byte;
		}
		else
		{
			pb.pData = new PacketTransmission();
			pb.pData-&gt;data[pos++] = (unsigned char)byte;
		}
	}
	return true;
}

// Ein String hinzufuegen
void Packet::AddString(const char *str)
{
	// Gueltiger String
	if(str == NULL || strlen(str) == 0) return;

	// Alle Elemente eintragen (per AddByte)
	for(int i = 0; i &lt; MAX_PACKET_SIZE; i++)
		AddByte(str[i]);
}
</code></pre>
<p>Vielen Dank im Voraus!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/305109/datei-einlesen-in-eine-verkettete-liste</link><generator>RSS for Node</generator><lastBuildDate>Sat, 27 Jun 2026 06:22:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/305109.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 21 Jun 2012 10:17:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Datei einlesen in eine verkettete Liste on Thu, 21 Jun 2012 10:36:07 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein kleines, eig. sogar 2 Probleme:<br />
Ich versuche eine Datei einzulesen (binär) und diese in eine verkettete Liste zu speichern um sie später über ein Socket an einen Client oder Server zu senden.</p>
<p>Probleme:<br />
i) Das ganze läuft sehr unperformant. Es dauert schon einiges an Zeit bei &gt;1MB<br />
ii)Teilweise wird nicht die ganze Datei reingeladen</p>
<p>Im folgenden Codeabschnitt ist eig. die ganze Logik des dargestellten Problemes:</p>
<pre><code class="language-cpp">#define MAX_PACKET_SIZE	1024		// Maximale Packetgroesse (in Byte)

// Packet::pos - Derzeitige Position in unserem Paket
// Packet::PacketCount - Anzahl der Pakete

struct PacketTransmission
{
	unsigned char 	data[MAX_PACKET_SIZE];	// Daten an sich
	PacketTransmission *nextPacket;			// Naechstes Paket

	bool HasNext(); 
};
struct PacketBase
{
	unsigned short op_code;		// Verwendeter Anfragecode
	unsigned int filename_length;	// Laenge des Dateinnamen
	std::string filename;		// Dateiname
	PacketTransmission *pData;	// Pointer zu unseren eigentlichen Daten
};

// Liest eine Datei in ein Paket ein
bool Packet::FileToPacket()
{
	// Datei oeffnen und jedes Zeichen auslesen und in das Paket eintragen
	std::ifstream file(pb.filename, std::ios::in | std::ios::binary);

	char buffer[MAX_PACKET_SIZE];
	// Solange durchgehen bis wie
	while(!file.eof())
	{
		file.read(buffer, MAX_PACKET_SIZE);
		this-&gt;AddString(buffer);
	}

	file.close();

	return true;
}

// Ein Byte zum Paket hinzufuegen
bool Packet::AddByte(unsigned char byte)
{
	// Wenn das aktuelle Paket voll ist, erstellen wir das naechste und verknuepfen es
	if(pos &gt;= MAX_PACKET_SIZE)
	{
		pos = 0;					// Wieder am Anfang setzen
		PacketCount++;				// Wir haben ein Paket mehr

		PacketTransmission *ptrans = new PacketTransmission;
		ptrans = pb.pData;
		// Solange durchgehen bis wir ein neues Paket frei haben
		while(ptrans-&gt;HasNext())
			ptrans = ptrans-&gt;nextPacket;

		PacketTransmission *newPacket = new PacketTransmission;
		newPacket-&gt;data[pos++] = (unsigned char)byte;
		newPacket-&gt;nextPacket = NULL;

		ptrans-&gt;nextPacket = newPacket;
	}
	// Wir haben noch Platz
	else
	{
		PacketTransmission *ptrans = new PacketTransmission;

		if(pb.pData != NULL)
		{
			ptrans = pb.pData;
			while(ptrans-&gt;HasNext())
				ptrans = ptrans-&gt;nextPacket;

			ptrans-&gt;data[pos++] = (unsigned char)byte;
		}
		else
		{
			pb.pData = new PacketTransmission();
			pb.pData-&gt;data[pos++] = (unsigned char)byte;
		}
	}
	return true;
}

// Ein String hinzufuegen
void Packet::AddString(const char *str)
{
	// Gueltiger String
	if(str == NULL || strlen(str) == 0) return;

	// Alle Elemente eintragen (per AddByte)
	for(int i = 0; i &lt; MAX_PACKET_SIZE; i++)
		AddByte(str[i]);
}
</code></pre>
<p>Vielen Dank im Voraus!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2225718</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2225718</guid><dc:creator><![CDATA[build]]></dc:creator><pubDate>Thu, 21 Jun 2012 10:36:07 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen in eine verkettete Liste on Thu, 21 Jun 2012 11:13:39 GMT]]></title><description><![CDATA[<p>Hallo build,</p>
<p>Willkommen im C++-Forum.</p>
<p>Dein Programm ist deshalb so langsam, weil Du beim Abspeichern jedes einzelnen Bytes die komplette Liste von vorne bis hinten durchläufst, um zum letzten Element <code>PacketTransmission</code> zu gelangen. Und weil Du mit jedem Byte ca. 1k Speicher allokierst ohne ihn freizugeben!</p>
<p>Tipp: lege Dir vor(!) dem Lesen (vor Zeile 31) bereits eine Instanz von <code>PacketTransmission</code> an und lese direkt in den Buffer( <code>data</code> ) dieser Instanz. Hänge sie anschließend an das Ende Deiner Liste (dann darfst Du sie auch ganz durchlaufen). Das dürfte um etliche Größenordnungen schneller sein.</p>
<p>Ansonsten gibt es noch ganz viel zu Deinem Programmcode zu sagen, aber vielleicht später. Z.B.: schaue Dir mal <a href="http://www.cplusplus.com/reference/iostream/istream/gcount/" rel="nofollow">gcount</a> an und ersetze in den Zeilen 49 und 64</p>
<pre><code class="language-cpp">PacketTransmission *ptrans = new PacketTransmission;
</code></pre>
<p>durch</p>
<pre><code class="language-cpp">PacketTransmission *ptrans = 0;
</code></pre>
<p>Dein Programm wird dann bereits etwas schneller laufen als vorher.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2225732</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2225732</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 21 Jun 2012 11:13:39 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen in eine verkettete Liste on Thu, 21 Jun 2012 12:01:01 GMT]]></title><description><![CDATA[<p>Das klingt auf jeden Fall schon einmal sinnvoll. Danke dafür.<br />
Zudem sorgt ein <strong>new</strong> bei jeder Iteration wohl für sehr große Speicherlecks.</p>
<p>Ich habe mich daher für die Lösung entschieden, welche leider Exceptions wirft.<br />
Allerdings sehe ich den Fehler gerade selbst nicht.</p>
<pre><code class="language-cpp">void Packet::AppendData(unsigned char data[MAX_PACKET_SIZE])
{
	if(pb.pData == NULL)
        {
		AddString((const char*)data);
                return;
        }

	PacketTransmission *pt		= new PacketTransmission;
	PacketTransmission *next	= 0;

	next = pb.pData;
	memcpy(pt-&gt;data, data, MAX_PACKET_SIZE);

	while(next-&gt;HasNext())
		next = next-&gt;nextPacket; // Hier kommt nach ein paar Iterationen die Exception

	next-&gt;nextPacket = pt;
	PacketCount++;

}

bool Packet::PacketTransmission::HasNext()
{
	if(this == NULL)
		return false;

	else
	{
		if(nextPacket == NULL)
			return false;
	}

	return true;
}
</code></pre>
<p>EDIT:<br />
Problem gelöst:<br />
ein <em>pt.nextPacket = NULL</em> hat gefehlt</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2225746</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2225746</guid><dc:creator><![CDATA[build]]></dc:creator><pubDate>Thu, 21 Jun 2012 12:01:01 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen in eine verkettete Liste on Thu, 21 Jun 2012 12:28:55 GMT]]></title><description><![CDATA[<p>Die Performanceprobleme wären gelöst.<br />
Das Problem mit den fehlenden Bytes leider nicht. Es liegt nicht am recv / send der Sockets. Das Problem entsteht beim reinladen und verknüpfen.<br />
Bei einer 150KB Datei fehlten 5KB. Bei einer kleinen 2KB Datei fehlten nur 7-8 Zeichen am Ende der Datei.</p>
<p>Der Tipp mit gcount würde es natürlich dynamischer, aber eig. müsste es ja auch mit 1KiB-Blöcken funktionieren. Eher passiert es doch, dass am Ende ein paar Byte zuviel statt zuwenig sind!?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2225759</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2225759</guid><dc:creator><![CDATA[build]]></dc:creator><pubDate>Thu, 21 Jun 2012 12:28:55 GMT</pubDate></item></channel></rss>