I am implementing a reliable data transfer protocol. I need to pass the checksum which is long value to a receiver. I am not allowed to use java.nio.
I know how to convert long to byte array as show below:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(someLong);
dos.close();
byte[] longBytes = baos.toByteArray();
But how do I convert byte array to long without using java.nio?
You can do like this
ByteArrayInputStream bais = new ByteArrayInputStream(longBytes);
DataInputStream dis = new DataInputStream(bais);
someLong = dis.readLong();
Related
I want to send images through sockets but I have not been able to do it in android, could someone help me?
System.out.println("iniciooooo");
//converting image to bytes with base64
Bitmap b = BitmapFactory.decodeFile("/sdcard/ajeffer.jpg");
ByteArrayOutputStream byte2= new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG,70,byte2);
byte[] enbytes = byte2.toByteArray();
String bb = Base64.encodeToString(enbytes,Base64.DEFAULT);
System.out.println(Base64.encodeToString(enbytes,Base64.DEFAULT));
data.writeUTF(bb);
FileOutputStream file;
//receiving the image in bytes to convert it into an image
DataInputStream dain = new DataInputStream(s.getInputStream());
msg = dain.readUTF();
File ff = new File("/sdcard/a2jeffer.jpg");
byte[] deco = Base64.decode(dain.readUTF(),Base64.DEFAULT);
Bitmap bit = BitmapFactory.decodeByteArray(deco,0,deco.length);
file = new FileOutputStream(ff);
bit.compress(Bitmap.CompressFormat.JPEG,70,file);
//the image is not created
I realized that my code did not work because I had to put this android: requestLegacyExternalStorage =" true " in the manifest, also I see that you are right about writeUTF () since in order to send images I must drastically lower the quality but it works If you have an idea on how to improve this, let me know, thank you very much.
You were right, this works great for sending and receiving any file.
Send file
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = new FileInputStream(file);
byte[] datita = new byte[16*1024];
int count;
while((count = inputStream.read(datita))>0){
outputStream.write(datita,0,count);
}
outputStream.close();
inputStream.close();
Receive file
OutputStream outputStream = new FileOutputStream(file);
InputStream inputStream = s.getInputStream();
byte[] datita = new byte[16*1024];
int count;
while((count = inputStream.read(datita))>0){
outputStream.write(datita,0,count);
}
outputStream.close();
inputStream.close();
I'm trying to write a byte array to file and then to read it again. The problem is that the byte array that I Read is different from that I wrote.
The output of the code below is:
[B#21a06946 (Original byte array written)
[B#2fc14f68 (byte array read )
byte[] encryptedKey = rsaCipher.encrypt(AESKey, publicKeyPathName, transformation, encoding);
System.out.println(encryptedKey);
List<byte[]> list = new ArrayList<byte[]>();
list.add(encryptedKey);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("encryptedKey"));
out.writeObject(list);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("encryptedKey"));
List<byte[]> byteList = (List<byte[]>) in.readObject();
in.close();
byte[] encryptedKey2 = byteList.get(0);
System.out.println(encryptedKey2);
Arrays do not have a proper String representation. To see the content, use the below instead
System.out.println(java.util.Arrays.toString(encryptedKey));
System.out.println(java.util.Arrays.toString(encryptedKey2));
I've the necessity to share a streaming of data between two instances as below:
// get EClasses which should be connected
final uk.man.xman.xcore.Parameter source = getParameter(sourceAnchor);
final uk.man.xman.xcore.Parameter target = getParameter(targetAnchor);
// Set data channels
//Output stream
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(outputStream));
source.setOutputStream(dataOutputStream);
//Input stream
DataInputStream inpuDataStream = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray())));
target.setInputStream(inpuDataStream);
Everything works ok if I write, during those lines of code. Strangely, when I need to use the data channel to write something in another class, like here:
DataOutputStream dataOutputStream = (DataOutputStream) inputParameter.getOutputStream();
System.out.println("WRITE:" + attributes.getValue("value"));
dataOutputStream.writeUTF(attributes.getValue("value"));
dataOutputStream.flush();
I am not able to read, and I really do not know why. Am I missing something?
Thanks for your time
Not sure if that's what you're asking, but you're creating an InputStream that reads from an empty byte array. That doesn't make much sense:
// create an Output stream that will write in memory
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
...
// transform what has been written to the output stream into a byte array.
// Since othing has been written yet, outputStream.toByteArray() returns
// an empty array
DataInputStream inpuDataStream = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray())));
I read this post but I am not following. I have seen this but have not seen a proper example of converting a ByteArrayInputStream to String using a ByteArrayOutputStream.
To retrieve the contents of a ByteArrayInputStream as a String, is using a ByteArrayOutputstream recommended or is there a more preferable way?
I was considering this example and extend ByteArrayInputStream and utilize a Decorator to increase functionality at run time. Any interest in this being a better solution to employing a ByteArrayOutputStream?
A ByteArrayOutputStream can read from any InputStream and at the end yield a byte[].
However with a ByteArrayInputStream it is simpler:
int n = in.available();
byte[] bytes = new byte[n];
in.read(bytes, 0, n);
String s = new String(bytes, StandardCharsets.UTF_8); // Or any encoding.
For a ByteArrayInputStream available() yields the total number of bytes.
Addendum 2021-11-16
Since java 9 you can use the shorter readAllBytes.
byte[] bytes = in.readAllBytes();
Answer to comment: using ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
for (;;) {
int nread = in.read(buf, 0, buf.length);
if (nread <= 0) {
break;
}
baos.write(buf, 0, nread);
}
in.close();
baos.close();
byte[] bytes = baos.toByteArray();
Here in may be any InputStream.
Since java 10 there also is a ByteArrayOutputStream#toString(Charset).
String s = baos.toString(StandardCharsets.UTF_8);
Why nobody mentioned org.apache.commons.io.IOUtils?
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
String result = IOUtils.toString(in, StandardCharsets.UTF_8);
Just one line of code.
Java 9+ solution:
new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
Use Scanner and pass to it's constructor the ByteArrayInputStream then read the data from your Scanner , check this example :
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(new byte[] { 65, 80 });
Scanner scanner = new Scanner(arrayInputStream);
scanner.useDelimiter("\\Z");//To read all scanner content in one String
String data = "";
if (scanner.hasNext())
data = scanner.next();
System.out.println(data);
Use Base64 encoding
Assuming you got your ByteArrayOutputStream :
ByteArrayOutputStream baos =...
String s = new String(Base64.Encoder.encode(baos.toByteArray()));
See http://docs.oracle.com/javase/8/docs/api/java/util/Base64.Encoder.html
Here is the code but got error:
bin = new ByteArrayInputStream(socket.getInputStream());
Is it possible to receive byte[] using ByteArrayInputStream from a socket?
No. You use ByteArrayInputStream when you have an array of bytes, and you want to read from the array as if it were a file. If you just want to read arrays of bytes from the socket, do this:
InputStream stream = socket.getInputStream();
byte[] data = new byte[100];
int count = stream.read(data);
The variable count will contain the number of bytes actually read, and the data will of course be in the array data.
You can't get an instance of ByteArrayInputStream by reading directly from socket.
You require to read first and find byte content.
Then use it to create an instance of ByteArrayInputStream.
InputStream inputStream = socket.getInputStream();
// read from the stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] content = new byte[ 2048 ];
int bytesRead = -1;
while( ( bytesRead = inputStream.read( content ) ) != -1 ) {
baos.write( content, 0, bytesRead );
} // while
Now, as you have baos in hand, I don't think you still need a bais instance.
But, to make it complete,
you can generate byte array input stream as below
ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );