Data from one stream to another

7

7elephants

I have the following piece of code to take data from one stream and put
it into another...


Int32 bufferSize = 100;
Int32.TryParse(ConfigurationManager.AppSettings["bufferLimit"].ToString(),
out bufferSize);

byte[] buffer = new byte[bufferSize];

//make sure stream is at the beginning
inputStream.Position = 0;

while (true) {
//read input stream
int bytesRead = inputStream.Read(buffer, offset,
bufferSize);

if (bytesRead > 0) {
//write to output stream
outputStream.Write(buffer, offset, bytesRead);
offset += bytesRead;
} else {
break;
}
}
+--------------------------------------------------------------+

When I run the code above, I get a System.ArgumentException with the
following message "Offset and length were out of bounds for the array
or count is greater than the number of elements from index to the end
of the source collection." In the test file I am using, all the data
is read in the first read, but I can't be guaranteed that when in
PRODUCTION mode. I also can't be guaranteed that the input stream is
text-based (or else I would use readers and writers).

So, my two questions are 1) Can anybody tell me when I am getting this
error? and 2) Is there a better way for me to do this?

In my research before posting I found
http://www.geocities.com/firepower_50ae/CodeNote/dot-Net-Error-FileSystem-Read.html,
but I don't necessary understand how to correct the problem.

Thanks for any help in advance.
 
B

Barry Kelly

7elephants said:
I have the following piece of code to take data from one stream and put
it into another... [snip]
Int32.TryParse(ConfigurationManager.AppSettings["bufferLimit"].ToString(),
out bufferSize); [snip]
inputStream.Position = 0; [snip]
int bytesRead = inputStream.Read(buffer, offset,
bufferSize); [snip]
outputStream.Write(buffer, offset, bytesRead);
offset += bytesRead;

This offset parameter to both Stream.Read and Stream.Write indicate to
these methods at what index in the buffer to read or write. The slice of
the array, buffer[offset..offset+count-1] inclusive, needs to be valid.

You're increasing the offset, but you're never decreasing it. Eventually
this slice runs off the end of your buffer.
So, my two questions are 1) Can anybody tell me when I am getting this
error? and 2) Is there a better way for me to do this?

Here's a copy routine I wrote a long time ago:

---8<---
public static void CopyStream(Stream source, Stream dest)
{
byte[] buffer = new byte[65536];
int read;
do
{
read = source.Read(buffer, 0, buffer.Length);
dest.Write(buffer, 0, read);
} while (read != 0);
}
--->8---

Setting the Position to 0 might not be desirable; for one thing, the
stream might not be seekable (Stream.CanSeek will tell you). I have an
overloaded CopyStream that can specify an 'int count' argument to limit
the number of bytes copied.

I'm not sure you gain a lot by making the buffer configurable; depending
on the stream backing store, it can make sense to make the buffer
relatively large (for example, the stream might be a NetworkStream over
a TCP socket which has the Nagle algorithm turned off (NoDelay = true)),
but not large enough to land in the large object heap (80 KB or so), so
that it's still cheap to GC.

-- Barry
 
7

7elephants

That was it. Thanks.


Barry said:
7elephants said:
I have the following piece of code to take data from one stream and put
it into another... [snip]
Int32.TryParse(ConfigurationManager.AppSettings["bufferLimit"].ToString(),
out bufferSize); [snip]
inputStream.Position = 0; [snip]
int bytesRead = inputStream.Read(buffer, offset,
bufferSize); [snip]
outputStream.Write(buffer, offset, bytesRead);
offset += bytesRead;

This offset parameter to both Stream.Read and Stream.Write indicate to
these methods at what index in the buffer to read or write. The slice of
the array, buffer[offset..offset+count-1] inclusive, needs to be valid.

You're increasing the offset, but you're never decreasing it. Eventually
this slice runs off the end of your buffer.
So, my two questions are 1) Can anybody tell me when I am getting this
error? and 2) Is there a better way for me to do this?

Here's a copy routine I wrote a long time ago:

---8<---
public static void CopyStream(Stream source, Stream dest)
{
byte[] buffer = new byte[65536];
int read;
do
{
read = source.Read(buffer, 0, buffer.Length);
dest.Write(buffer, 0, read);
} while (read != 0);
}
--->8---

Setting the Position to 0 might not be desirable; for one thing, the
stream might not be seekable (Stream.CanSeek will tell you). I have an
overloaded CopyStream that can specify an 'int count' argument to limit
the number of bytes copied.

I'm not sure you gain a lot by making the buffer configurable; depending
on the stream backing store, it can make sense to make the buffer
relatively large (for example, the stream might be a NetworkStream over
a TCP socket which has the Nagle algorithm turned off (NoDelay = true)),
but not large enough to land in the large object heap (80 KB or so), so
that it's still cheap to GC.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top