binary data socket over android and java - java

I am using this code to get my image from facebook server.
String imageURL = "http://graph.facebook.com/"+id+"/picture?type=large";
InputStream inputStream = new URL(imageURL).openConnection().getInputStream();
DataInputStream dataStream = new DataInputStream(inputStream);
byte[] dataBuffer = new byte[4096];
ByteArrayOutputStream dataHolder = new ByteArrayOutputStream();
int n;
while ( (n=dataStream.read(dataBuffer))!=-1 ){
dataHolder.write(dataBuffer, 0, n);
}
and using the same way to get my image from my server:
FileInputStream inputStream = new FileInputSTream("/image.jpg");
DataOutputStream dataStream = new DataOutputStream(socket.getOutpustStream());
byte[] dataBuffer = new byte[4096];
int n;
while ( (n=inpuStream.read(dataBuffer))!=-1 ){
dataStream.write(dataBuffer, 0, n);
}//get -1 perfectly
and getting them on android app like this:
DataInputStream dataStream = new DataInputStream(socket.getInputStream());
byte[] dataBuffer = new byte[4096];
ByteArrayOutputStream dataHolder = new ByteArrayOutputStream();
int n;
while ( (n=dataStream.read(dataBuffer))!=-1 ){
dataHolder.write(dataBuffer, 0, n);
}//-1 ??????????????
but the android app cant get the right file and it cant go out form while loop,exactly can not get -1 but yesterday I accidently got -1 from some changes I did,really can not understand why I can not get -1 in my android app however I can get it from the servers while loop

You can directly convert the inputstream to a bitmap instead of reading bytes.
Bitmap myBitmap = BitmapFactory.decodeStream(inputStream);

Here is just some glassball guessing: Did you close the stream on the server side?
Put a dataStream.close(); after your writing loop.

Related

Java InputStream Downloading Slowly

I am using this code to download an encrypted file:
InputStream frame = new URL(url).openStream();
ByteArrayOutputStream data = new ByteArrayOutputStream();
int count;
byte[] buff = new byte[10000];
while((count = frame.read(buff)) > 0){
data.write(buff, 0, count);
System.out.println(count);
}
This code works great sometimes, but others it can take up to a minute for a ~36 kilobyte file. Is there a better way of doing this or is the problem simply the connection to the download server?

avoiding garbage data while reading data using a byte buffer

I am trying to write a program to transfer a file between client and server using java tcp sockets I am using buffer size of 64K but The problem I am facing is that when when the tcp sometimes fail to send the whole 64K it sends the remaing part for example 32K in anther go
There for A garbage data of some Spaces or so is being taken by the buffer at reading side to make 64K complete and thus unnecessary data is making the file useless at receiving side.
Is there any solution to overcome this problem ???
I am using TCP protocol this code is using to send data to client
Server-side code
File transferFile = new File ("Document.txt");
byte [] bytearray = new byte [1024];
int byRead=0;
FileInputStream fin = new FileInputStream(transferFile);
BufferedInputStream bin = new BufferedInputStream(fin);
OutputStream os = socket.getOutputStream();
while(byRead>-1) {
byRead=bin.read(bytearray,0,bytearray.length);
os.write(bytearray,0,bytearray.length);
os.flush();
}
Client-side code
byte [] bytearray = new byte [1024];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("C:\\Users\\NetBeansProjects\\"+filename);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray,0,bytearray.length);
currentTot = bytesRead; System.out.println("Data is being read ...");
do {
bytesRead = is.read(bytearray, 0, (bytearray.length));
if(bytesRead == 0) continue;
if(bytesRead >= 0) currentTot += bytesRead;
bos.write(bytearray,0,bytearray.length);
} while(bytesRead > -1);
here I tried to skip the loop if the byte is empty by continue; statement but it is not
working.
bos.write(bytearray,0,bytearray.length);
This should be
bos.write(bytearray,0,bytesRead);
The region after 'bytesRead' in the buffer is undisturbed by the read. It isn't 'garbage'. It's just whatever was there before.
use CLIENT Side Code as below to get the total write bytes without garbage
int availableByte = socket.available();
if (availableByte > 0) {
byte[] buffer = new byte[availableByte];
int bytesRead = socketInputStream.read(buffer);
FileOutputStream fileOutputStream = new FileOutputStream(FilePath, true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
bufferedWriter.write(buffer.toString());
bufferedWriter.close();
}

getting negative byte array length or large amount of byte array length at client side in java

I am transmitting image from server to client. Server capture the screen and convert it to byte array and client receive byte array and convert back it to image. but transmission happens only for few frame and then error occurred.
Receiver side:
while(true) {
DataInputStream dis = new DataInputStream(csocket.getInputStream());
int len = dis.readInt();
System.out.println(len);
byte data[] = null;
data = new byte[len];
dis.read(data);
ByteArrayInputStream in = new ByteArrayInputStream(data);
BufferedImage image1=ImageIO.read(in);
ImageIcon imageIcon= new ImageIcon(image1);
Image image = imageIcon.getImage();
image = image.getScaledInstance(cPanel.getWidth(),cPanel.getHeight(),Image.SCALE_FAST);
//Draw the recieved screenshot
Graphics graphics = cPanel.getGraphics();
graphics.drawImage(image, 0, 0, cPanel.getWidth(),cPanel.getHeight(),cPanel);
}
Sender Side:
while(continueLoop) {
try {
BufferedImage image = robot.createScreenCapture(rectangle);
byte[] imageInByte;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image,"jpg", baos);
baos.flush();
imageInByte = baos.toByteArray();
baos.close();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//PrintWriter out = new PrintWriter(socket.getOutputStream());
//out.flush();
dos.writeInt(imageInByte.length);
System.out.println(imageInByte.length);
dos.write(imageInByte);
Thread.sleep(1000);
dos.flush();
}
catch(Exception e) {
}
}
Output of Receiver:
1177222283
-297418067
1228900861
-412483840
189486847
10536391
-33405441
12898815
740182
-16736067
-805436987
-16726825
258150991
2137853087
1917408603
512024791
-1227886373
-1034512766
1772271848
157387
Exception in thread "Thread-3" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(ImageIcon.java:228)
at remoteclient.ClientScreenReciever.run(ClientScreenReciever.java:65)
Please help me..what to do for continuous transmission of image from server to client over socket in faster way in java.
You are using
DataInputStream#read(byte[])
which (check its Javadoc) does not guarantee that a full arrays-worth of data will be read. This method is used for buffered reading and not to fully read the requested amount of bytes.
Instead you must call
DataInputStream#readFully(byte[])
which has a contract suiting your purpose (again check the Javadoc).

My ByteBuffer is not placing it's bytes into a bytes array properly

Here is the code
byte data[] = new byte[1024];
fout = new FileOutputStream(fileLocation);
ByteBuffer bb = ByteBuffer.allocate(i+i); // i is size of download
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
while( (dat = rbc.read(bb)) != -1 )
{
bb.get(data);
fout.write(data, 0, 1024); // write the data to the file
speed.setText(String.valueOf(dat));
}
In this code I try to download a file from a given URL, but the file doesn't complete all it's way.
I don't know what error happened, is it the ReadableByteChannel's fault? Or I didn't put my bytes from the ByteBuffer into the Byte[] properly.
When you read into a ByteBuffer, the offset of the buffer is changed. Which means, after the read, you need to rewind the ByteBuffer:
while ((dat = rbc.read(bb)) != -1) {
fout.write(bb.array(), 0, bb.position());
bb.rewind(); // prepare the byte buffer for another read
}
But in your case, you don't really need a ByteBuffer anyway, just using a plain byte array is enough -- and it is shorter:
final InputStream in = url.openStream();
final byte[] buf = new byte[16384];
while ((dat = in.read(buf)) != -1)
fout.write(buf, 0, dat);
Note that in Java 1.7, you can use that:
Files.copy(url.openStream(), Paths.get(fileLocation));

How do I get the InputStream of decompressed data from an InputStream of GZIPed data?

I call a service which returns a gzipped file. I have the data as an InputStream (courtesy of javax.activation.DataHandler.getInputStream();) from the response.
What I would like to do is, without writing anything to disk, get an InputStream of the decompressed data in the file that is in the archive. The compressed file in this case is an xml document that I am trying to unmarshal using javax.xml.bind.Unmarshaller which takes an InputStream.
I'm currently trying to write the InputStream to an OutputStream (decompressing the data) and then I'll need to write it back to an InputStream. It's not working yet so I thought I would see if there was a better (I would hope so) approach.
I can write the initial InputStream to disk and get a gz file, and then read that file, get the compressed file out of it and go from there but I'd rather keep it all in memory is possible.
Update 1: Here is my current (not working - get a "Not in GZIP format" exception):
ByteArrayInputStream xmlInput = null;
try {
InputStream in = dh.getInputStream(); //dh is a javax.activation.DataHandler
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int bytes_read = 0;
byte[] dataBuf = new byte[4096];
while ((bytes_read = bis.read(dataBuf)) != -1) {
bo.write(dataBuf, 0, bytes_read);
}
ByteArrayInputStream bin = new ByteArrayInputStream(bo.toByteArray());
GZIPInputStream gzipInput = new GZIPInputStream(bin);
ByteArrayOutputStream out = new ByteArrayOutputStream();
dataBuf = new byte[4096];;
bytes_read = 0;
while ((bytes_read = gzipInput.read(dataBuf)) > 0) {
out.write(dataBuf, 0, bytes_read);
}
xmlInput = new ByteArrayInputStream(out.toByteArray());
If instead of writing to a ByteArrayOutputStream I write to a FileOutputStream the first time around I get a compressed file (which I can manually open to get the xml file within) and the service (eBay) says it should be a gzip file so I'm not sure why I get a "Not in GZIP format" error.
Update 2: I tried something a little different - same error ("Not in GZIP format"). Wow, I just tried to end that parenthesis with a semi-colon. Anyways, here is my second attempt, which still does not work:
ByteArrayInputStream xmlInput = null;
try {
GZIPInputStream gzipInput = new GZIPInputStream(dh.getInputStream());
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int bytes_read = 0;
byte[] dataBuf = new byte[4096];
while ((bytes_read = gzipInput.read(dataBuf)) != -1) {
bo.write(dataBuf, 0, bytes_read);
}
xmlInput = new ByteArrayInputStream(bo.toByteArray());
Decorate the input stream with a GZIPInputStream.
InputStream decompressed = new GZIPInputStream(compressed);
The following code should work. Keep in mind you'll have to handle exceptions properly.
OutputStream out = null;
InputStream in = null;
try {
out = /* some output stream */;
in = new java.util.GZIPInputStream(/*some stream*/);
byte[] buffer = new byte[4096];
int c = 0;
while (( c = in.read(buffer, 0, 4096)) > 0) {
out.write(buffer, 0, c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
Take a look at GZIPInputStream. Here's an example; the class handles this very transparently, it's almost no work to use.

Categories

Resources