<?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[Binär und Random Access Datei IO]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich gebe einige Ergebniswerte (alles ints) in eine Datei aus, im moment einfach mit operator&lt;&lt; als text und mit komma getrennt.<br />
Die Datei kann mehrere hundert MB oder noch mehr groß werden.</p>
<p>Im Moment speichere ich alles zwischen in einem Buffer und schreibe am Ende alles in die Datei, weil die Ergebniosse nicht in der richtigen Reihenfolge verfügbar sind.</p>
<p>Jetzt habe ich den plan, eine random-access datei zu verwenden und dann direkt an die richtige stelle zu schreiben. Dabei wollte ich das ganze dann auch binär machen, um 1. Platz zu sparen und 2. sicherzustellen, dass jeder int-wert die selbe länge hat, sodass ich auch beim einlesen einen random access nutzen kann. Wenn ich das mit text machen würde, müsste ich z.B. festlegen, das jede zahl genau 10 Stellen hat oder so.</p>
<p>Das mit random access habe ich gerade ausprobiert und scheint eigentlich ganz einfach zu sein mit ofstream::seekp. Jetzt gehts es noch um das binäre schreiben in die Datei. Wie es ausieht schreibt fstream auch im ios_base::binary modus die zahlen als text in die datei.</p>
<p>Muss ich das dann ungefähr so machen?:</p>
<pre><code class="language-cpp">int toWrite = 42;
int bigEndianVal = ToBigEndian(toWrite);
char * val = reinterpret_cast&lt;char*&gt;(&amp;bigEndianVal);
ofs.write(val, sizeof(int));
</code></pre>
<p>Oder gibt es da etwas fertiges zu?<br />
Und dann ist da noch die sache mit dem ToBigEndian, muss ich das dann auch selbst schreiben?</p>
<p>Meine Idee dazu wär das hier:</p>
<pre><code class="language-cpp">bool IsBigEndian()
{
   int test = 1;
   char * ptr = reinterpret_cast&lt;char*&gt;(&amp;test);
   return ptr[3] == 1;
}

int ToBigEndian(int val);
{
   if(!IsBigEndian)
   {
       char * ptr = reinterpret_cast&lt;char*&gt;(val);
       std::reverse(ptr, ptr + sizeof(int));
   }
   return val;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/301041/binär-und-random-access-datei-io</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 08:35:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/301041.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 17 Mar 2012 18:56:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sat, 17 Mar 2012 18:57:04 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich gebe einige Ergebniswerte (alles ints) in eine Datei aus, im moment einfach mit operator&lt;&lt; als text und mit komma getrennt.<br />
Die Datei kann mehrere hundert MB oder noch mehr groß werden.</p>
<p>Im Moment speichere ich alles zwischen in einem Buffer und schreibe am Ende alles in die Datei, weil die Ergebniosse nicht in der richtigen Reihenfolge verfügbar sind.</p>
<p>Jetzt habe ich den plan, eine random-access datei zu verwenden und dann direkt an die richtige stelle zu schreiben. Dabei wollte ich das ganze dann auch binär machen, um 1. Platz zu sparen und 2. sicherzustellen, dass jeder int-wert die selbe länge hat, sodass ich auch beim einlesen einen random access nutzen kann. Wenn ich das mit text machen würde, müsste ich z.B. festlegen, das jede zahl genau 10 Stellen hat oder so.</p>
<p>Das mit random access habe ich gerade ausprobiert und scheint eigentlich ganz einfach zu sein mit ofstream::seekp. Jetzt gehts es noch um das binäre schreiben in die Datei. Wie es ausieht schreibt fstream auch im ios_base::binary modus die zahlen als text in die datei.</p>
<p>Muss ich das dann ungefähr so machen?:</p>
<pre><code class="language-cpp">int toWrite = 42;
int bigEndianVal = ToBigEndian(toWrite);
char * val = reinterpret_cast&lt;char*&gt;(&amp;bigEndianVal);
ofs.write(val, sizeof(int));
</code></pre>
<p>Oder gibt es da etwas fertiges zu?<br />
Und dann ist da noch die sache mit dem ToBigEndian, muss ich das dann auch selbst schreiben?</p>
<p>Meine Idee dazu wär das hier:</p>
<pre><code class="language-cpp">bool IsBigEndian()
{
   int test = 1;
   char * ptr = reinterpret_cast&lt;char*&gt;(&amp;test);
   return ptr[3] == 1;
}

int ToBigEndian(int val);
{
   if(!IsBigEndian)
   {
       char * ptr = reinterpret_cast&lt;char*&gt;(val);
       std::reverse(ptr, ptr + sizeof(int));
   }
   return val;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2192447</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192447</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Sat, 17 Mar 2012 18:57:04 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sat, 17 Mar 2012 20:17:10 GMT]]></title><description><![CDATA[<p>Sowohl beim binären Schreiben als auch beim Endianessumrechnen bist du schon auf dem richtigen Weg. Eleganter geht's höchstens mit externen Bibliotheken, die dann aber im Endeffekt das gleiche machen wie dein Code. Mit der Standardbibliothek alleine geht's nicht schöner.</p>
<p>Bist du sicher, dass du das mit der Endianess brauchst? Mich wundert sehr, dass du zwar davon ausgehst, dass int auf allen deinen Zielsystemen die gleiche Größe hat, aber nicht die gleiche Endianess.</p>
<p>Ein anderer Ansatz wäre, alles selber umzurechnen und dann zeichenweise auszugeben. Also fast so wie du es jetzt schon tust, bloß dass du beim Umrechnen der Endianess nicht den Wert der Zahl änderst (was ich ohnehin für sehr zweifelhaften Stil halte), sondern direkt das Ergebnis als chars (oder als Hexzahl - die wäre auch immer gleich groß, wenn du mit Nullen auffüllst. Braucht zwar etwas mehr Platz, aber ist dann wenigstens menschenlesbar) rausschreibst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192453</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192453</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sat, 17 Mar 2012 20:17:10 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sat, 17 Mar 2012 20:42:56 GMT]]></title><description><![CDATA[<p>Und wrappe das auch lieber gleich in eine Klasse, die das Zeugs dann notfalls wieder im RAM cachen kann, das dürfte nämlich wesentlich flotter gehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192455</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192455</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 17 Mar 2012 20:42:56 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sat, 17 Mar 2012 22:20:03 GMT]]></title><description><![CDATA[<p>kennt dein compiler schon constexpr?<br />
wieso nutzt du nicht die größe (des integers)?</p>
<pre><code class="language-cpp">constexpr bool IsBigEndian()
{ 
   int test = 1; 
   char * ptr = reinterpret_cast&lt;char*&gt;(&amp;test); 
   return ptr[sizeof(int)-1] == 1; 
}
</code></pre>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192469</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192469</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Sat, 17 Mar 2012 22:20:03 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sat, 17 Mar 2012 22:54:10 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p>kennt dein compiler schon constexpr?<br />
wieso nutzt du nicht die größe (des integers)?</p>
<pre><code class="language-cpp">constexpr bool IsBigEndian()
{ 
   int test = 1; 
   char * ptr = reinterpret_cast&lt;char*&gt;(&amp;test); 
   return ptr[sizeof(int)-1] == 1; 
}
</code></pre>
<p>bb</p>
</blockquote>
<p>Dummerweise muss eine constexpr-Funktion aus einem einzigen return-Statement bestehen (außer evtl. static_aserts, using-Direktiven oder -deklarationen, typedefs oder alias-Deklarationen oder null-Statements, also Zeugs, das das Verhalten des Programmes nicht direkt beeinflussen kann). Und ein reinterpret_cast-Ausdruck ist niemals ein konstanter Ausdruck...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192473</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192473</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sat, 17 Mar 2012 22:54:10 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sat, 17 Mar 2012 23:21:04 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Und ein reinterpret_cast-Ausdruck ist niemals ein konstanter Ausdruck...</p>
</blockquote>
<p>stimmt^^</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192478</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192478</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Sat, 17 Mar 2012 23:21:04 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sun, 18 Mar 2012 10:46:12 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Und wrappe das auch lieber gleich in eine Klasse, die das Zeugs dann notfalls wieder im RAM cachen kann, das dürfte nämlich wesentlich flotter gehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Mein Ziel war es ja gerade, mit möglichst wenig RAM auszukommen.<br />
Wenn ich später mal eine 8GB Ausgabedatei haben will, wird es schwierig 8GB zu cachen, da soviel speicher wahrscheinlich gar nicht vorhanden ist.<br />
Außerdem will ich das ganze auf einem Cluster ausführen. Da muss ich am Anfang den maximalen Speicherbedarf angeben, wird dieser überschritten, wird das programm gekillt. Je mehr speicher ich angebe, desto länger dauert es, bis das Programm gestartet wird (das gilt übrigens auch für die Laufzeit).</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>wieso nutzt du nicht die größe (des integers)?</p>
</blockquote>
<p>War ein Flüchtigkeitsfehler, danke.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192502</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192502</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Sun, 18 Mar 2012 10:46:12 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sun, 18 Mar 2012 20:12:49 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18065">@Q</a><br />
Ist dein Ergebnis &quot;sparse&quot;, also nur ein paar wenige Ergebnisse innerhalb des 8 GB Blocks?<br />
Falls nicht, wenn du also 2 Milliarden ints mit Random IOs in eine Datei schreiben willst, dann könnte das 2 Milliarden Random IOs bedeuten (je nachdem wie zufällig das Muster wirklich ist) - und das dauert dann.</p>
<p>Wenn wir 10ms pro IO annehmen, dann wären das 20 Milliarden ms = 20 Millionen Sekunden = 5555.55 Stunden = 231 Tage.<br />
(Wenn es nicht eine einzelne Platte sondern mehrere in einem RAID Verbund sind, dann entsprechend weniger)</p>
<p>Nachdem das jetzt relativ lange ist...</p>
<p>Man könnte z.B. das Programm mehrfach hintereinander laufen lassen.<br />
Sagen wir du hast 1 GB RAM, und das Ergebnis wird 8 GB gross. Dann lässt du das Programm einfach 8x laufen. Einmal für das erste GB des Ausgabefiles, einmal für das 2. GB und so weiter. Und verwirfst dabei immer alle Ergebnisse die du im aktuellen Durchlauf grad nicht brauchen kannst.</p>
<p>Falls die Berechnung der Werte deutlich länger als das lineare Lesen aus einer Datei braucht könntest du auch die Ergebnisse erstmal so wie sie anfallen in eine Datei schreiben. Dann musst du nur noch diese Datei 8x lesen um das fertige Output-File zusammenzubauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192630</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192630</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 18 Mar 2012 20:12:49 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sun, 18 Mar 2012 20:32:33 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<p>Mein Ziel war es ja gerade, mit möglichst wenig RAM auszukommen.<br />
Wenn ich später mal eine 8GB Ausgabedatei haben will, wird es schwierig 8GB zu cachen, da soviel speicher wahrscheinlich gar nicht vorhanden ist.</p>
</blockquote>
<p>Dann limitiere die Cachegröße. Wenn er voll ist, wird das Ergebnis auf die Platte geschrieben. Dann hast du zumindest nur seeks in eine Richtung und kürzere Sprünge.</p>
<p>Aber eventuell brauchst du gar keinen echten Random Access? Dann reicht es vielleicht, die Operationen blockweise durchzuführen.<br />
Ich stelle mir das so vor, dass du deine Datei in einzelne Teile a xKB aufteilst. Wenn ein Block voll ist, wird er in die Datei geschrieben. Wenn deine Daten irgendeine Struktur haben, sollte auch die Cachegröße relativ klein bleiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192634</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192634</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 18 Mar 2012 20:32:33 GMT</pubDate></item><item><title><![CDATA[Reply to Binär und Random Access Datei IO on Sun, 18 Mar 2012 21:10:52 GMT]]></title><description><![CDATA[<p>Mit random access hab ich mich falsch ausgedrückt. Ich habe Blöcke von daten und für jeden block muss ich vorher an eine stelle in der datei springen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192642</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192642</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Sun, 18 Mar 2012 21:10:52 GMT</pubDate></item></channel></rss>