How to properly close a BufferedInputStream - inputstream

I create a BufferedInputStream from an InputStream. I can close the BufferedInputStream by calling its close() method. Should I also close the InputStream from which it was created, or does that happen sutomatically?

Closing BufferedInputStream is sufficient since it closes the underlying stream as well.
This can also be seen in the implementation: https://github.com/openjdk/jdk/blob/9a7209ef346e4f78b6153e998ecdfac72edc5580/src/java.base/share/classes/java/io/BufferedInputStream.java#L482

Related

Exit for loop inside using keyword [duplicate]

I've the following code
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
The dispose() method is called at the end of using statement braces } right? Since I return before the end of the using statement, will the MemoryStream object be disposed properly? What happens here?
Yes, Dispose will be called. It's called as soon as the execution leaves the scope of the using block, regardless of what means it took to leave the block, be it the end of execution of the block, a return statement, or an exception.
As #Noldorin correctly points out, using a using block in code gets compiled into try/finally, with Dispose being called in the finally block. For example the following code:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
effectively becomes:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
So, because finally is guaranteed to execute after the try block has finished execution, regardless of its execution path, Dispose is guaranteed to be called, no matter what.
For more information, see this MSDN article.
Addendum:
Just a little caveat to add: because Dispose is guaranteed to be called, it's almost always a good idea to ensure that Dispose never throws an exception when you implement IDisposable. Unfortunately, there are some classes in the core library that do throw in certain circumstances when Dispose is called -- I'm looking at you, WCF Service Reference / Client Proxy! -- and when that happens it can be very difficult to track down the original exception if Dispose was called during an exception stack unwind, since the original exception gets swallowed in favor of the new exception generated by the Dispose call. It can be maddeningly frustrating. Or is that frustratingly maddening? One of the two. Maybe both.
using statements behave exactly like try ... finally blocks, so will always execute on any code exit paths. However, I believe they are subject to the very few and rare situations in which finally blocks are not called. One example that I can remember is if the foreground thread exits while background threads are active: all threads apart from the GC are paused, meaning finally blocks are not run.
Obvious edit: they behave the same apart from the logic that lets them handle IDisposable objects, d'oh.
Bonus content: they can be stacked (where types differ):
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
And also comma-delimited (where types are the same):
using (SqlCommand comm = new SqlCommand("", conn),
comm2 = new SqlCommand("", conn))
{
}
Your MemoryStream object will be disposed properly, no need to worry about that.
With the using statement, the object will be disposed of regardless of the completion path.
Further reading...
http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
http://csharpfeeds.com/post/8451/Return_Within_a_Csharp_Using_Statement.aspx
Take a look at your code in reflector after you compile it. You'll find that the compiler refactors the code to ensure that dispose is called on the stream.

Progress while deserializing JSON

I'm deserializing a huge JSON (1.4 GB) via a stream, because I don't want to load the whole content into memory in advance just for parsing. That's working fine, but it takes ~80 seconds, so I want to display a progress.
public JObject DeserializeViaStream(string filename)
{
object obj;
var serializer = new JsonSerializer();
using (var sr = new StreamReader(new FileStream(filename, FileMode.Open)))
{
using (var jsonTextReader = new JsonTextReader(sr))
{
obj = serializer.Deserialize(jsonTextReader);
}
}
return (JObject) obj;
}
I have not yet tried but only one idea: I could implement my own stream reader which keep track of the bytes being read and comparing that to the file length.
Is there a built-in option or easier way to do this?
I ended up using the idea I had. Luckily there's already a ProgressStream available by Mel Green (archive.org). The original URL is no longer available.
Please note:
this approach may not work for all situations and with all libraries forever. This is due to the fact that the Seek() operation provides random access, and someone could read the file multiple times.
I can't post the source code here, because it was released under an unclear license.

How to view contents of HTMLTextWriter?

I have an HtmlTextWriter object (theWriter) being passed into a method. This method is in the middle tier. I'd like to read the contents of the theWriter in debug mode. The method is:
protected override void Render (HtmlTextWriter theWriter) {...}
which inherits from Panel:WebControl.
I've tried
theWriter.Flush();
theWriter.InnerWriter.ToString();
but that only outputs the object type: "System.Web.HttpWriter". I've seen some examples use methods on the Response object. But I don't have access to Response in this layer. Any ideas?
The InnerWriter is a TextWriter-derived class, which writes to a stream. You will have to open that stream and read data from it. Whether you can open and read from that stream is an open question, and depends very much on what type of stream it is.
So to use your example, theWriter.InnerWriter is an object derived from TextWriter. But you don't know what kind, and TextWriter itself doesn't expose the underlying stream.
Now, if InnerWriter is a StreamWriter, then you might be able to write:
var sWriter = theWriter.InnerWriter as StreamWriter;
var stream = sWriter.BaseStream;
var savePosition = stream.Position;
stream.Position = 0;
// now, you can read the stream
// when you're done reading the stream, be sure to reset its position
stream.Position = savePosition;
You have to be very careful, though. If you get the base stream and then open it with a StreamReader, closing the StreamReaderwill close the underlying stream. Then your HtmlTextWriter will throw an exception the next time you try to write to it.
It's also possible that you won't be able to read the stream. If the base stream is a NetworkStream, for example, you can't read it. Or it could be a FileStream that was open for write only. There's no good general way to do this, as it entirely depends not only on the specific TextWriter-derived class, but also on the stream that the TextWriter is writing to.
For example, the HtmlTextWriter could be writing to a StreamWriter, which is connected to a BufferedStream connected to a GZipStream, which finally writes to a MemoryStream.
So, in general, I'd recommend that you look for some other solution to your problem. Unless you know for sure what the underlying stream is, and that you can read it ... and that things won't change on you unexpectedly.

Dispose a stream in a BizTalk pipeline component?

I'm fairly new to BizTalk and creating a custom pipeline component. I have seen code in examples that are similar to the following:
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
Stream originalDataStream = pInMsg.BodyPart.GetOriginalDataStream();
StreamReader strReader = new StreamReader(originalDataStream);
string strOriginalData = strReader.ReadToEnd();
byte[] bufferOriginalMessage = new byte[strOriginalData.Length];
bufferOriginalMessage = ASCIIEncoding.Default.GetBytes(strOriginalData);
Stream ms = new MemoryStream();
ms.Write(bufferOriginalMessage, 0, strOriginalD
//other stuff here
ms.Seek(0, SeekOrigin.Begin);
pInMsg.BodyPart.Data = ms;
}
But nowhere in the method is the StreamReader being closed or disposed. The method simply exits.
Normally when using StreamReader and other classes, it is best practice to use a using statement so that the stream is automatically disposed.
Is there a particular reason (perhaps in BizTalk) why you wouldn't dispose this StreamReader?
I have not found any information on this point. Can anyone help?
In general, yes, it's a good practice to close readers and streams you don't need anymore. That said, there might not necessarily be 100% required everytime. For example, closing the reader would close the underlying stream normally, but chances are, something else is probably already aware of the stream and will close it at the right time on it's own.
What is good practice, however, is to add any streams you use in a pipeline component with a lifetime matching that of the message to the resource tracker, so that BizTalk can dispose them automatically when the pipeline execution finishes and the message has been processed.

Issue using SocketConnection with a Blackberry using MDS

I am currently writing an app on the Blackberry to do a simple send and receive of some raw data to another TCP based device on my network. I am having the same problem in the Blackberry simulator w/ an MDS simulator running and using a physical phone talking to my company's MDS server. Note this problem does not happen when using wifi directly and not via MDS.
The problem is that the available() function on the InputStream returns zero unless I call read() first. If I call read first (knowing there is some data available .. thank you wireshark) the data comes back, and the subsequent call to available() indicates what data is left that I did not read. The problem is that I am not always going to be guaranteed that data will be there and so I could block. Is anyone aware of this, and is this a problem or something that is by design?
Is anyone aware of a way to test if the read() method(s) will block before calling them aside from available?
Here is basically what I am doing:
SocketConnection s = (SocketConnection)Connector.open("socket://1.2.3.4:port;deviceside=false", Connector.READ_WRITE);
OutputStream o = ((StreamConnection)s).openOutputStream();
InputStream i = ((StreamConnection)s).openInputStream();
o.write("hello");
Thread.sleep(sometime);
if (i.available() > 0) {
byte[] data = new data[10];
int bytesRead = i.read(data);
System.out.println("Read [" + new String(data) + "] (bytes = " + bytesRead + ")");
}
I have to comment out the if conditional for this to work.
The general contract of the InputStream.available() method is that it "Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream." Hence in most implementations, it is no guarantee that it will return the Content Length of the stream that is being read. Hence it is better to read it in the following way
byte[] readFromStream(InputStream is) throws IOException
{
byte[] data = new byte[4096];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
int count = is.read(data, 0, data.length);
while (count != -1)
{
dos.write(data, 0, count);
count = is.read(data, 0, data.length);
}
data = baos.toByteArray();
return data;
}
You call the readFromStream() method and get the byte[] returned.
As I indicated in a comment above, I needed a way to determine if a device I am connecting to is not there, and I do that by seeing if our 'ping' returns any data. If the device is not there it will block. I cannot rely on that behavior. Another issue that crept up while solving this is that the read(...) methods of the RIM InputStream class block if you provide a buffer bigger than the data you want back. But how am I supposed to know how much data is there if available() returns 0? Reading byte-by-byte is about the only way to do this, but it still blocks if there is no data.
To address this I followed the theme of the 1st answer, but I put this method on its own thread and had it write to a separate byte buffer. I created a class that extended InputStream and implemented available() and read(...). Available returns how many bytes are in the byte buffer, and read only gives back however much is in the buffer or however much the caller requests, whichever is less.
This setup lets me use an InputStream interface, but behind the scenes it is just a continuously running reader thread that is alive until the connection is dropped. At that time the read, if blocked, will throw an exception to indicate the connection closed. This behavior is fine as it can be easily handled.
Thanks to all above who helped with this issue. Your thoughts help move towards the solution.

Resources