I am receiving an InputStream from HttpUrlConnection (connection.getInputStream()), and I am parsing the input stream using DocumentBuilder (documenbtBuilder.parse(inputStream)). Before parsing, I want to write the received data to log file. When I do that, I get org.xml.sax.SAXParseException: Unexpected end of document Exception in the parse method. My code works fine if I don't write to file, but I need to log the data received.
Please find the code that writes to file below :
final InputStream input = connection.getInputStream();
writeLogInfo(input);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
//Method that writes tito log file.
private void writeLogInfo(InputStream input){
OutputStream os = new FileOutputStream("mylogfile.txt");
byte[] buffer = new byte[1024];
int byteRead;
while((byteRead = input.read(buffer)) != -1){
os.write(buffer,0,byteRead);
}
os.flush();
os.close();
}
I suspect it is because of multiple use of InputStream, since the code works when I don't invode writeLogInfo(). I am not closing the inputstream anywhere in my code. What am I doing wrong here ?
When you are writing the content to a file, you are reaching the end of the inputstream.
So after that, when you are trying to parse, you get the exception.
You need to use mark and reset methods on the inputstream before passing it to documentbuilder.
Also, first you need to check if the input stream supports mark.
Here is the javadoc, for your reference
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html
Are you sure the size of the file is under 1024 bytes. If not why don't you put your "inputstream" to BufferredInputstream, and create the byte array..
BufferedInputStream bin= new BufferedInputStream(new DataInputStream(input));
byte[] buffer= new byte[bin.available()];
bin.read(buffer);
os.write(buffer);
......
......
bin.close();
......
Related
I need to save a pdf document, generated by aspose.pdf for java library to memory (without using temporary file)
I was looking at the documentation and didn't find the save method with the appropriate signature. (I was looking for some kind of outputstream, or at least byte array).
Is it possible? If it is, how can I manage that?
Thanks
Aspose.Pdf for Java supports saving output to both file and stream. Please check following code snippet, It will help you to accomplish the task.
byte[] input = getBytesFromFile(new File("C:/data/HelloWorld.pdf"));
ByteArrayOutputStream output = new ByteArrayOutputStream();
com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(new ByteArrayInputStream(input));
pdfDocument.save(output);
//If you want to read the result into a Document object again, in Java you need to get the
//data bytes and wrap into an input stream.
InputStream inputStream=new ByteArrayInputStream(output.toByteArray());
I am Tilal Ahmad, developer evangelist at Aspose.
I did similar thing.
Here is method to write data to byte:
public byte[] toBytes() {
//create byte array output stream object
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
//create new data output stream object
DataOutputStream outStream = new DataOutputStream(byteOutStream);
try {//write data to bytes stream
if (data != null) {
outStream.write(data);//write data
}//return array of bytes
return byteOutStream.toByteArray();
}
Then you do something like
yourFileName.toBytes;
//Reading a image file from #drawable res folder and writing to a file on external sd card
//below one works no doubt but I want to imrpove it:
OutputStream os = new FileOutputStream(file); //File file.........
InputStream is =getResources().openRawResource(R.drawable.an_image);
byte[] b = new byte[is.available()];
is.read(b);
os.write(b);
is.close();
os.close();
In above code I am using basic io classes to read and write. My question is what can I do in order to able to use wrapper classes like say DataInputStream/ BufferedReaderd or PrintStream / BufferedWriter /PrintWriter.
As openRawResources(int id ) returns InputStream ;
to read a file from res I either need to typecast like this:
DataInputStream is = (DataInputStream) getResources().openRawResource(R.drawble.an_image));
or I can link the stream directly like this:
DataInputStream is = new DataInputStream(getResources().openRawResource(R.drawable.greenball));
and then I may do this to write it to a file on sd card:
PrintStream ps =new PrintStream (new FileOutputStream(file));
while(s=is.readLine()!=null){
ps.print(s);
}
So is that correct approach ? which one is better? Is there a better way?better practice..convention?
Thanks!!!
If openRawResource() is documented to return an InputStream then you cannot rely on that result to be any more specific kind of InputStream, and in particular, you cannot rely on it to be a DataInputStream. Casting does not change that; it just gives you the chance to experience interesting and exciting exceptions. If you want a DataInputStream wrapping the the result of openRawResource() then you must obtain it via the DataInputStream constructor. Similarly for any other wrapper stream.
HOWEVER, do note that DataInputStream likely is not the class you want. It is appropriate for reading back data that were originally written via a DataOutputStream, but it is inappropriate (or at least offers no advantages over any other InputStream) for reading general data.
Furthermore, your use of InputStream.available() is incorrect. That method returns the number of bytes that can currently be read from the stream without blocking, which has only a weak relationship with the total number of bytes that could be read from the stream before it is exhausted (if indeed it ever is).
Moreover, your code is also on shaky ground where it assumes that InputStream.read(byte[]) will read enough bytes to fill the array. It probably will, since that many bytes were reported available, but that's not guaranteed. To copy from one stream to another, you should instead use code along these lines:
private final static int BUFFER_SIZE = 2048;
void copyStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int nread;
while ( (nread = in.read(buffer) != 0 ) do {
out.write(buffer, 0, nread);
}
}
I have a FileOutputStream in java that is reading the contents of UDP packets and saving them to a file. At the end of reading them, I sometimes want to convert the encoding of the file. The problem is that currently when doing this, it just ends up doubling all the contents of the file. The only workaround that I could think to do would be to create a temp file with the new encoding and then save it as the original file, but this seems too hacky.
I must be just overlooking something in my code:
if(mode.equals("netascii")){
byte[] convert = new byte[(int)file.length()];
FileInputStream input = new FileInputStream(file);
input.read(convert);
String temp = new String(convert);
convert = Charset.forName("US-ASCII").encode(temp).array();
fos.write(convert);
}
JOptionPane.showMessageDialog(frame, "Read Successful!");
fos.close();
}
Is there anything suspect?
Thanks in advance for any help!
The problem is the array of bytes you've read from the InputStream will be converted as if its ascii chars, which I'm assuming its not. Specify the InputStream encoding when converting its bytes to String and you'll get a standard Java string.
I've assumed UTF-16 as the InputStream's encoding here:
byte[] convert = new byte[(int)file.length()];
FileInputStream input = new FileInputStream(file);
// read file bytes until EOF
int r = input.read(convert);
while(r!=-1) r = input.read(convert,r,convert.length);
String temp = new String(convert, Charset.forName("UTF-16"));
I know that there are some similar questions in the site, but they could not provide me a helpful answer. What is the best/most efficient way to read a .bin file in Java line by line? Which classes and methods should someone use to open it and get the data? Could Bufferedreader do the job or is it only for text files;
Binary file don't have lines, but you must know the format of the file to know what structure exists (headers, structs,etc) and write a parser.
You can use BufferedInputStream, see the following:
http://www.javapractices.com/topic/TopicAction.do?Id=245
Read structured data from binary file -?
This should do it.
public byte[] readFromStream(InputStream inputStream) throws Exception
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
byte[] data = new byte[4096];
int count = inputStream.read(data);
while(count != -1)
{
dos.write(data, 0, count);
count = inputStream.read(data);
}
return baos.toByteArray();
}
if I have this code, how could I keep the filename of the original file or reassign it to the new one?:
InputStream input= assetInfo.openStream();
File t = new File("");
OutputStream out = new FileOutputStream(t);
int read=0;
byte[] bytes = new byte[1024];
while((read = input.read(bytes))!= -1){
out.write(bytes, 0, read);
}
An input stream can be created to read from a file or from any other source of data. Therefore it makes no sense to have a filename attached to an input stream. Look in assetInfo to see if that class exposes that data (you can even look inside the class using reflection). Note that the creator or assetInfo made a design mistake not exposing this information, OR you are trying to make one now.