Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How can we read or use the contents of outputstream.
In my case, I am using a method having signature.
public static OutputStream decryptAsStream(InputStream inputStream,
String encryptionKey)
This method return OutputStream. I want get OutputStream to String.
Is it possible to pipe the output from an java.io.OutputStream to a String in Java?
How can we read or use the contents of outputstream.
In general you can't. An OutputStream is an object that you write bytes to. The general API doesn't provide any way to get the bytes back.
There are specific kinds of output stream that would allow you to get the bytes back. For instance:
A ByteArrayOutputStream has a method for getting the byte array contents.
A PipeOutputStream has a corresponding PipeInputStream that you can read from.
If you use a FileOutputStream to write to file, you can typically open a FileInputStream to read the file contents ... provided you know the file pathname.
Looking at that method, it strikes me that the method signature is wrong for what you are trying to do. If the purpose is to provide an encrypter for a stream, then the method should return an InputStream. If the purpose is to write the encrypted data somewhere, then the method should return void and take an extra parameter that is the OutputStream that the method should write to. (And then the caller can use an OutputStream subclass to capture the encrypted data ... if that is what is desired.)
Another alternative that would "work" is to change the method's signature to make the return type ByteArrayOutputStream (or a file name). But that is not a good solution because it takes away the caller's ability to decide where the encrypted output should be sent.
UPDATE
Regarding your solution
OutputStream os = AESHelper.decryptAsStream(sourceFile, encryptionKey);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) os;
byte[] imageBytes = baos.toByteArray();
response.setContentType("image/jpeg");
response.setContentLength(imageBytes.length);
OutputStream outs = response.getOutputStream();
outs.write(imageBytes);
That could work, but it is poor code:
If AESHelper.decryptAsStream is a method that you wrote (and it looks like it is!), then you should declare it as returning a ByteArrayOutputStream.
If it is already declared as returning a ByteArrayOutputStream you should assign it directly to baos.
Either way, you should NOT initialize baos to a newly created ByteArrayOutputStream instance that immediately gets thrown away.
It is also worth noting that the Content-Type is incorrect. If you sent that response to a browser, it would attempt to interpret the encrypted data as an image ... and fail. In theory you could set a Content-Encoding header ... but there isn't one that is going to work. So the best solution is to send the Content-Type as "application/octet-stream".
You can do something like following :
OutputStream output = new OutputStream()
{
private StringBuilder string = new StringBuilder();
#Override
public void write(int x) throws IOException {
this.string.append((char) x );
}
public String toString(){
return this.string.toString();
}
};
Mainly you can use outputstreams to send the file contents as #The New Idiot mentioned. .pdf files, zip file, image files etc.
In such scenarios, get the output stream of your servlet and to that write the contentes
OutputStream outStream = response.getOutputStream();
FileInputSteram fis = new FileInputStream(new File("abc.pdf));
byte[] buf = new byte[4096];
int len = -1;
while ((len = fis.read(buf)) != -1) {
outStream .write(buf, 0, len);
}
response.setContentType("application/octect");(if type is binary) else
response.setContentType("text/html");
outStream .flush();
outStream.close();
If you got the OutputStream from the response , you can write the contents of the OutputStream to the response which will be sent back to the browser . Sample code :
OutputStream outStream = response.getOutputStream();
response..setHeader("Content-Disposition", "attachment; filename=datafile.xls");
response.setContentType("application/vnd.ms-excel");
byte[] buf = new byte[4096];
int len = -1;
while ((len = inStream.read(buf)) != -1) {
outStream.write(buf, 0, len);
}
outStream.flush();
outStream.close();
Read this : Content-Disposition:What are the differences between “inline” and “attachment”?
In your case the method definition is :
public static OutputStream decryptAsStream(InputStream inputStream,
String encryptionKey)
So you can get the OutputStream from that method as :
OutputStream os = ClassName.decryptAsStream(inputStream,encryptionKey);
And then use the os .
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 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();
}
I want to read a file into a byte array. So, I am reading it using:
int len1 = (int)(new File(filename).length());
FileInputStream fis1 = new FileInputStream(filename);
byte buf1[] = new byte[len1];
fis1.read(buf1);
However, it is realy very slow. Can anyone inform me a very fast approach (possibly best one) to read a file into byte array. I can use java library also if needed.
Edit: Is there any benchmark which one is faster (including library approach).
It is not very slow, at least there is not way to make it faster. BUT it is wrong. If file is big enough the method read() will not return all bytes from fist call. This method returns number of bytes it managed to read as return value.
The right way is to call this method in loop:
public static void copy(InputStream input,
OutputStream output,
int bufferSize)
throws IOException {
byte[] buf = new byte[bufferSize];
int bytesRead = input.read(buf);
while (bytesRead != -1) {
output.write(buf, 0, bytesRead);
bytesRead = input.read(buf);
}
output.flush();
}
call this as following:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
copy(new FileInputStream(myfile), baos);
byte[] bytes = baos.toByteArray();
Something like this is implemented in a lot of packages, e.g. FileUtils.readFileToByteArray() mentioned by #Andrey Borisov (+1)
EDIT
I think that reason for slowness in your case is the fact that you create so huge array. Are you sure you really need it? Try to re-think your design. I believe that you do not have to read this file into array and can process data incrementally.
apache commons-io FileUtils.readFileToByteArray
I'm having quite a problem here, and I think it is because I don't understand very much how I should use the API provided by Java.
I need to write an int and a byte[] into a byte[].
I thought of using a DataOutputStream to solve the data writing with writeInt(int i) and write(byte[] b), and to be able to put that into a byte array, I should use ByteArrayOutputStream method toByteArray().
I understand that this classes use the Wrapper pattern, so I had two options:
DataOutputStream w = new DataOutputStream(new ByteArrayOutputStream());
or
ByteArrayOutputStream w = new ByteArrayOutputStream(new DataOutputStream());
but in both cases, I "loose" a method. in the first case, I can't access the toByteArray() method, and in the second, I can't access the writeInt() method.
How should I use this classes together?
Like this:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream w = new DataOutputStream(baos);
w.writeInt(100);
w.write(byteArray);
w.flush();
byte[] result = baos.toByteArray();
Actually your second version will not work at all. DataOutputStream requires an actual target stream in which to write the data. You can't do new DataOutputStream(). There isn't actually any constructor like that.
Could you make a variable to hold on to the ByteArrayOutputStream and pass it into the DataOutputStream.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(1);
byte[] result = dos.toByteArray();
Use the former case - wrap DataOutputStream around the ByteArrayOutputStream. Just make sure you save the reference to the ByteArrayOutputStream. When you are finished, close() or at least flush() the DataOutputStream and then use the toByteArray method of the ByteArrayOutputStream.
You could use a stream approach if you connect your outputstream to an inputstream through a PipedInputStream/PipetOutputStream. Then you will consume the data from the inputstream.
Anyway if what you need to do is simple and doesn't not require a stream approach I would use a java.nio.ByteBuffer on which you have
put(byte[] src) for your byte[]
putInt(int value)
and byte[] array() to get the content
You don´t need more like this
Example exampleExample = method(example);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); marshaller.marshal(exampleExample , baos);
Message message = MessageBuilder.withBody(baos.toByteArray()).build();
The Integer class has a method to get the byte value of an int.
Integer.byteValue()