<?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[Blockweise Kopie in IO-Streams]]></title><description><![CDATA[<p>Was ist die effizienteste Möglichkeit, Blöcke aus Filestreams zu kopieren? Ich hab momentan einen Puffer, aber glaube, dass der unnötig ist. Ausserdem muss ich so bei grossen Blöcken viel Speicher allokieren, eventuell wäre daher eine schrittweise Kopie besser geeignet. Bieten die IO-Streams schon sowas an?</p>
<p>Mein momentaner Code (noch ohne Fehlerbehandlung):</p>
<pre><code class="language-cpp">void Copy(std::istream&amp; source, std::streampos srcBegin, std::streamoff srcSize,
	std::ostream&amp; dest, std::streampos dstBegin)
{
	std::vector&lt;char&gt; buffer( static_cast&lt;std::size_t&gt;(srcSize) );

	source.seekg(srcBegin);
	source.read(buffer.data(), buffer.size());

	dest.seekp(dstBegin);
	dest.write(buffer.data(), source.gcount());
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/302567/blockweise-kopie-in-io-streams</link><generator>RSS for Node</generator><lastBuildDate>Tue, 11 Aug 2026 07:43:44 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/302567.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 22 Apr 2012 10:01:26 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 10:01:26 GMT]]></title><description><![CDATA[<p>Was ist die effizienteste Möglichkeit, Blöcke aus Filestreams zu kopieren? Ich hab momentan einen Puffer, aber glaube, dass der unnötig ist. Ausserdem muss ich so bei grossen Blöcken viel Speicher allokieren, eventuell wäre daher eine schrittweise Kopie besser geeignet. Bieten die IO-Streams schon sowas an?</p>
<p>Mein momentaner Code (noch ohne Fehlerbehandlung):</p>
<pre><code class="language-cpp">void Copy(std::istream&amp; source, std::streampos srcBegin, std::streamoff srcSize,
	std::ostream&amp; dest, std::streampos dstBegin)
{
	std::vector&lt;char&gt; buffer( static_cast&lt;std::size_t&gt;(srcSize) );

	source.seekg(srcBegin);
	source.read(buffer.data(), buffer.size());

	dest.seekp(dstBegin);
	dest.write(buffer.data(), source.gcount());
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2204380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204380</guid><dc:creator><![CDATA[In Strömen]]></dc:creator><pubDate>Sun, 22 Apr 2012 10:01:26 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 10:54:12 GMT]]></title><description><![CDATA[<p>Stream-Iteratoren könnten helfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204393</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204393</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Sun, 22 Apr 2012 10:54:12 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 11:06:15 GMT]]></title><description><![CDATA[<p>Jodocus schrieb:</p>
<blockquote>
<p>Stream-Iteratoren könnten helfen.</p>
</blockquote>
<p>Nee. Ein istream_iterator nutzt Operator &gt;&gt;, was gar nicht in Frage kommt und ein istreambuf_iterator nutzt streambuf::sgetc() was auch nicht das wahre ist, wenn man doch eigentlich streambuf::sgetn() haben möchte. read ist schon das richtige. Ebenso beim Ausgabestrom.</p>
<p>Das ist schon ganz ok, so wie es ist. Was man noch machen könnte:<br />
- Möchte man gleich alles kopieren, kann man auch direkt den ganzen Streambuf des Eingabestroms in den Ausgabestrom schreiben.<br />
- Du könntest dir den vector sparen und stattdessen mit einer Schleife in Blöcken (vorgeschlagene Blockgröße: 0.5 bis 8 kB, mal ein bisschen experimentieren). Das spart dir einmalig die Speicheranforderung, könnte eventuell sogar schneller sein, falls die Quelle/Ziel der Streams langsam sein sollten, da dann die Eingabe und die Ausgabe gleichzeitig laufen, anstatt erst alles zu lesen und dann alles zu schreiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204400</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204400</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sun, 22 Apr 2012 11:06:15 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 11:31:11 GMT]]></title><description><![CDATA[<p>Also</p>
<pre><code class="language-cpp">#include &lt;fstream&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

using namespace std;

int main()
{
	ifstream i(&quot;Infile&quot;, ios_base::binary);
	noskipws(i);
	ofstream o(&quot;Outfile&quot;, ios_base::trunc | ios_base::binary);
	std::copy(istream_iterator&lt;char&gt;(i), istream_iterator&lt;char&gt;(), ostream_iterator&lt;char&gt;(o));
}
</code></pre>
<p>funktioniert bei mir.</p>
<p>Aber Blockweises read()/write() dürfte um Längen schneller sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204408</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204408</guid><dc:creator><![CDATA[Caligulaminus]]></dc:creator><pubDate>Sun, 22 Apr 2012 11:31:11 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 11:41:03 GMT]]></title><description><![CDATA[<p>Das es funktioniert bestreite ich gar nicht, aber es war ausdrücklich nach Effizienz gefragt. istream_operator ist eine formatierte Leseaktion, da wird ungeheuer viel bei gerechnet und ist entsprechend lahm. Die Funktionen sind nicht so klug, dass sie für den Sonderfall &quot;copy mit einem istream_iterator mit char als Templateargument und auf dem Stream ist noskipws aktiviert&quot; eine effiziente Sonderimplementierung mit read und write anbieten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204413</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204413</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sun, 22 Apr 2012 11:41:03 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 11:51:11 GMT]]></title><description><![CDATA[<blockquote>
<p>Was ist die effizienteste Möglichkeit...?</p>
</blockquote>
<p>Nicht mal das Lesen klappt heute. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Ich geh' wieder ins Bett...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204420</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204420</guid><dc:creator><![CDATA[Caligulaminus]]></dc:creator><pubDate>Sun, 22 Apr 2012 11:51:11 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 14:03:22 GMT]]></title><description><![CDATA[<p>Vielen Dank. Gibt es keine Möglichkeit, Teile direkt aus einem Stream in den anderen zu kopieren (z.B. über den Streambuf)?</p>
<p>Sonst versuch ichs mit der vorgeschlagenen Schleife.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204477</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204477</guid><dc:creator><![CDATA[In Strömen]]></dc:creator><pubDate>Sun, 22 Apr 2012 14:03:22 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 19:48:37 GMT]]></title><description><![CDATA[<p>Was spricht denn gegen den streambuf_iterator? Der liest die chars zwar einzeln aus, aber die werden ja vom Stream gebuffert. Das Buffern zweimal zu machen, kostet da nur Performanz.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204594</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204594</guid><dc:creator><![CDATA[angström]]></dc:creator><pubDate>Sun, 22 Apr 2012 19:48:37 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 22:39:10 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>- Du könntest dir den vector sparen und stattdessen mit einer Schleife in Blöcken (vorgeschlagene Blockgröße: 0.5 bis 8 kB, mal ein bisschen experimentieren).</p>
</blockquote>
<p>Ich würde den Puffer um zwei Grössenordnungen grösser machen.<br />
Also so 64KB bis 1MB.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204660</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 22 Apr 2012 22:39:10 GMT</pubDate></item><item><title><![CDATA[Reply to Blockweise Kopie in IO-Streams on Sun, 22 Apr 2012 23:31:29 GMT]]></title><description><![CDATA[<p>angström schrieb:</p>
<blockquote>
<p>Was spricht denn gegen den streambuf_iterator? Der liest die chars zwar einzeln aus, aber die werden ja vom Stream gebuffert. Das Buffern zweimal zu machen, kostet da nur Performanz.</p>
</blockquote>
<p>Stimmt einfach nicht. Ich habe mal einen Benchmark geschrieben:</p>
<pre><code class="language-cpp">const size_t block_size = 4096;
            size_t num_blocks = heap.size() / block_size;
            size_t rest = heap.size() - num_blocks * block_size;
            for (unsigned i = 0; i &lt; num_blocks; ++i)
              in.read(&amp;heap[i * block_size], block_size);
            in.read(&amp;heap[num_blocks * block_size], rest);
</code></pre>
<p>vs.</p>
<pre><code class="language-cpp">istreambuf_iterator&lt;char&gt; in_it (in.rdbuf());
            copy_n(in_it, heap.size(), heap.begin());
</code></pre>
<p>vs.</p>
<pre><code class="language-cpp">const size_t block_size = 1000000;
            size_t num_blocks = heap.size() / block_size;
            size_t rest = heap.size() - num_blocks * block_size;
            for (unsigned i = 0; i &lt; num_blocks; ++i)
              in.read(&amp;heap[i * block_size], block_size);
            in.read(&amp;heap[num_blocks * block_size], rest);
</code></pre>
<p>Durchschnitt über 20 Durchläufe, jeweils 100000000 Bytes aus einer Datei, die zu der Zeit schon komplett im Festplattenpuffer steckte (Linux, ext4, GCC 4.6 -O3):</p>
<pre><code>Read, 4kB:
User: 0.0425
Sys: 0.0515
Wall: 0.0922621

istreambuf_iterator:
User: 0.4085
Sys: 0.054
Wall: 0.462917

Megabyteweise:
User: 0.0015
Sys: 0.093
Wall: 0.0936295
</code></pre>
<p>Alle Angaben in Sekunden.</p>
<p>hustbaer gewinnt den Thread.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2204666</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2204666</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sun, 22 Apr 2012 23:31:29 GMT</pubDate></item></channel></rss>