In my case the out put stream is basically FileOutputStream. Hence for this code:
ByteArrayOutputStream bos = (ByteArrayOutputStream) streamToEncrypt;
(Where streamToEncrypt is OutputStream) is getting this exception:
java.lang.ClassCastException: java.io.FileOutputStream cannot be cast to java.io.ByteArrayOutputStream
All I need to do is to get the byte array out of this outputstream.
I do NOT have access to the file at this level. All I have is this output stream that I have to encrypt before pushing it to the file
That simply doesn't make any sense.
A ByteArrayOutputStream takes the data you push into it ... and stores them within a byte array that you can retrieve later on.
A FileOutputStream takes data ... and pushes it into a file.
Those are two completely different classes; you simply can't cast one into the other! Thats like you trying to cast a String into an Integer; or turning an Apple into a Banana by saying "you apple, now be a banana". Simply wont work!
So, the real "answer" here: you should step back and clarify what exactly you intend to do with your data; and then you use that stream(s) matching that requirement(s).
You don't get bytes out of an OutputStream. You get them out of an InputStream. You put bytes into an OutputStream.
If bytes have already been written to the OutputStream, it's too late. Opening the file again and reading from it is the only way for you to access those data.
If you want to encrypt an output stream, you should construct the stream and pass it to the code that writes to the stream.
Cipher enc = Cipher.getInstance("...");
enc.init(...);
try (OutputStream fos = Files.newOutputStream(path);
OutputStream os = new CipherOutputStream(fos, enc)) {
writingObject.write(os);
}
Related
I want to serialize a big object structure to store it to a sql database.
Object tree = getTree();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(tree);
String objectString = Base64.getEncoder().encodeToString(baos.toByteArray());
The problem is that the generated byte array by baos.toByteArray() is to large. It throws java.lang.OutOfMemoryError and it is to big to transfer it to the database at once. I'm looking for an option to get the generated byte array block by block from outputstream to work it off in a loop step by step.
Write the initial OutputStream to a temporary file (using FileOutputStream). also, make sure you close the ObjectOutputStream or it will be a malformed stream. Lastly, open your temp file as a FileInputStream and use that to stream into your database.
Forget about the base64-encoding and write the object directly to the Blob's output stream.
I was trying to read from file and then write to other file. I use code bellow to do so.
byte[] bytes = Files.readAllBytes(file1);
Writer Writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2), "UTF-8"));
for(int i=0;i<bytes.length;i++)
Writer.write(bytes[i]);
Writer.close();
But when I change file1 to picture.png and file2 to picture2.png, this method doesn't work and I can't open picture2.png using image viewer.
What have I done wrong?
Writers are for writing text, possibly in different formats (ie utf-8 / 16, etc). For writing raw bytes, don't use writers. Just use (File)OutputStreams.
It is truly as simple as
byte[] bytes = ...;
FileOutputStream fos = ...;
fos.write(bytes);
The other answers explain why what you have potentially fails.
I'm curious why you're already using one Java NIO method, but not others? The library already has methods to do this for you.
byte[] bytes = Files.readAllBytes(file1);
Files.write(file2, bytes, StandardOpenOption.CREATE_NEW); // or relevant OpenOptions
or
FileOutputStream out = new FileOutputStream(file2); // or buffered
Files.copy(file1, out);
out.close();
or
Files.copy(file1, file2, options);
The problem is that Writer.write() doesn't take a byte. It takes a char, which is variable size, and often bigger than one byte.
But once you've got the whole thing read in as a byte[], you can just use Files.write() to send the whole array to a file in much the same way that you read it in:
Files.write(filename, bytes);
This is the more modern NIO idiom, rather than using an OutputStream.
It's worth reading the tutorial.
I'm using two libraries in an android app I'm trying to make. New to android. The app is for connecting to serial devices and controlling their console via a terminal.
One library is for setting up a serial connection, setting baud rate etc. and can also write read/data over serial.. The other is for creating a terminal session. My problem lies in incorporating both of these together to have a terminal that is connected to a serial device.
In the terminal library I need to supply an InputStream and OutputStream to provide input and output to the terminal. So I have to call setTermIn(java.io.InputStream) and setTermOut(java.io.OutputStream) to connect the input and output streams to the emulator.
In the serial library however there are two methods for sending and receiving and these deal with arrays of bytes.
sendData(byte[] data) for sending data and a dataListener for receiving data. I have to implement this and code the method onDataReceived(int id, byte[] data) with id being the name of the device.
I don't have source code for the function that sends an array of bytes over serial, so how do I make the array of bytes into a stream to send to my terminal?
EDIT:
I think this should override it and that is what I want?
Private USB2SerialAdapter mSelectedAdapter;
...
public void sendData(byte[] data)
{
//this should echo what I send to the terminal in the correct format
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
bos.write(data, 0, data.length);
setTermOut(bos);
//send data over serial using original sendData() method
mSelectedAdapter.sendData(data);
}
These two snippets should give you enough information to find a solution to your problem.
reading:
byte[] source = ...;
ByteArrayInputStream bis = new ByteArrayInputStream(source);
// read bytes from bis ...
writing
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// write bytes to bos ...
byte[] sink = bos.toByteArray();
This should do it: ByteArrayInputStream, ByteArrayOutputStream
Just look at the docs in those cases.
I need to send image from android app to java app. Basically, I need a byte array from the image to send to rf module which transmits.Another rf module receives and sends the byte array to java app which must make the image .
Android code:
FileInputStream fis = new FileInputStream(myFile);
byte[] b=new byte[(int)myFile.length()];
fis.read(b);server.send(b);
Java code:
FileOutputStream fwrite = new FileOutputStream(new File("my_xml"),true);
fwrite.write(bb);//bb is a byte from rf using input stream as soon as a byte comes it is read to file. This is necessary for some other reasons
fwrite.flush();
fwrite.close();
After getting full file:
FileInputStream fir=new FileInputStream("my_xml");
final BufferedImage bufferedImage = ImageIO.read(fir);
ImageIO.write(bufferedImage, "bmp", new File("image.bmp"));
fir.close();
I am getting error javax.imageio.IIOException: Bogus Huffman table definition
The rf is working fine because text file is being sent perfectly.Please help.Even without ImageIo code is not giving image even after changing extension to jpeg
The error means that the image file cant be read because the format is wrong.That is some bytes are missing or wrong or out of proper position and therefore file cant be decoded. My rf transfer does not have protocols like tcp/ip therefore some bytes are lost due to error in communication channel and hence the error.
You don't need to use ImageIO just to copy a file. Just read and write the bytes.
Your code has other problems:
You are assuming that read(byte[]) fills the buffer. It doesn't. Check the Javadoc.
You are also assuming that the file length fits into an int. If it does, fine. If it doesn't, you are hosed.
You appear to be opening and closing the FileOutputStream on every byte received. This could not be more inefficient. Open it once, write everything, close it.
flush() before close() is redundant.
You are storing the image in a file called 'my_xml'. This is only going to cause confusion, if it hasn't already.
You don't even need the file. Just load the image directly from the input stream.
Consider these two functions:
Function A takes inputStream as parameter.
public void processStream(InputStream stream)
{
//Do process routine
}
Function B loads a file content to pass it to Function A as InputStream.
pulic void loadFile()
{
File file =new File("c:\\file.txt");
//Pass file as InputStream
}
How can I pass file from Function B to Function A as InputStream without reading it on first hand?
I did something like this:
File file = new File("c:\\file.txt");
DataInputStream stream= new DataInputStream(new FileInputStream(file));
This generated the exception below:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.io.DataInputStream
EDIT:
loadFile() is passing the InputStream as RMI response.
The following should work just fine
processStream(new FileInputStream(file));
You should only not attempt to serialize an InputStream instance by ObjectOutputStream like as
objectOutputStream.writeObject(inputStream);
which you're apparently doing in processStream() method. That's namely exactly what the exception is trying to tell you. How to solve it properly depends on the sole functional requirement which you omitted from the question.
Update as per the comment
I am passing the InputStream as an RMI response.
There's the problem. You cannot pass non-serializable objects around as RMI response, let alone unread streams. You need to read the InputStream into a ByteArrayOutputStream the usual IO way and then use its toByteArray() to get a byte[] out of it and pass that instead. Something like:
InputStream input = new FileInputStream(file);
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
byte[] bytes = output.toByteArray(); // Pass that instead to RMI response.
Be careful with large files though. Every byte of a byte[] eats one byte of JVM's memory.
That exception seems to indicate that you are calling the processStream method on a remote object using something like RMI? if that is the case, you will need to re-visit what you are doing. sending streams of data over RMI is not an easy thing to do. if you are guaranteed to be using small files, you could copy the file data to a byte[] and pass that to the remote method call. if you need to process larger files, however, that will most likely cause memory issues on the client and/or server. in that case, you should use something like rmiio, which provides utilities for streaming data over RMI.
You could just pass the FileInputStream ?
processStream(new FileInputStream(yourFile));
The reason you are getting the exception is because DataInputStream is intended to read primitive Java types