Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast controlled copy from istream to ostream

I have to copy several bytes from a istream to a ostream, there are 2 ways that I know to perform this copy.

myostream << myistream.rdbuf();

and

copy( istreambuf_iterator<char>(myistream),
      istreambuf_iterator<char>(),
      ostreambuf_iterator<char>(myostream)
);

I've found that rdbuf version is at least twice as fast as the copy.
I haven't found yet the way of copying just, say 100 bytes, but as the size to be copied will probably be quite big I would like to be able to use the rdbuf version if posible.

How to limit those copies to a given number of bytes?

like image 765
Arkaitz Jimenez Avatar asked Oct 31 '10 16:10

Arkaitz Jimenez


People also ask

How do you copy the remainder of a stream in istream?

If IStream::CopyTo returns successfully, the actual number of bytes read and written are the same. To copy the remainder of the source from the current seek pointer, specify the maximum large integer value for the cb parameter. If the seek pointer is the beginning of the stream, this operation copies the entire stream.

How do I read and write data from one stream to another?

This method is equivalent to reading cb bytes into memory using ISequentialStream::Read and then immediately writing them to the destination stream using ISequentialStream::Write, although IStream::CopyTo will be more efficient. The destination stream can be a clone of the source stream created by calling the IStream::Clone method.

Why is my Stream not being copied?

The stream is not copied because there is no space left on the storage device. The object has been invalidated by a revert operation above it in the transaction tree. The CopyTo method copies the specified bytes from one stream to another. It can also be used to copy a stream to itself.

Are C++ iostreams part of STL?

C++ IOStreams are not part of the STL, you mean the C++ standardlibrary. The ios_base::out and the ios_base::trunc are the defaults already. The ios_base::in is default, too. // TODO: errorhandling for 'in' and 'out'! way, std::copy? istream iteration ? solution. The point is that the streams still have to filter each byte


1 Answers

Can you use 0x? If so, then you can use copy_n:

copy_n( istreambuf_iterator<char>(myistream),
        100,
        ostreambuf_iterator<char>(myostream)
);

EDIT 1:

I know you're probably looking for a library solution, and you could probably have figured this out on your own. But in case you haven't thought of something like this, here's what I would do(if I didn't have copy_n):

void stream_copy_n(std::istream & in, std::size_t count, std::ostream & out)
{
    const std::size_t buffer_size = 4096;
    char buffer[buffer_size];
    while(count > buffer_size)
    {
        in.read(buffer, buffer_size);
        out.write(buffer, buffer_size);
        count -= buffer_size;
    }

    in.read(buffer, count);
    out.write(buffer, count);
}
like image 117
Benjamin Lindley Avatar answered Oct 08 '22 07:10

Benjamin Lindley