I'm trying to send files in chunks from a client to server via byte arrays. I'm using ObjectInputStream. The write works and the filesize matches but when I open the file, I only get a blank textfile(which when opened in a IDE, shows NUL,NUL,NUL...).
Server code:
try(
FileOutputStream fileOut = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
){
byte[] arr = new byte[chunkSize];
try {
int len = 0;
long bytesRead = 0;
byte[] bytes = new byte[chunkSize];
int chunkNo = 1;
while(true)
{
len = in.read(bytes,0, chunkSize);
System.out.println();
if(len < 0)
break;
fileOut.write(arr, 0, len);
bytesRead += len;
out.writeObject(Server.CHUNK_ACKNOWLEDGE_MSG);
String ackReply = (String) in.readObject();
if(ackReply.equalsIgnoreCase((Server.UPLOAD_ACKNOWLEDGE_RECEIVE_TIMEOUT_MSG))){
if(Server.DEBUG)
System.out.println(fileName + " send timeout.");
deleteFile();
break;
}else if (ackReply.equalsIgnoreCase(Server.UPLOAD_COMPLETE_MSG)){
if(bytesRead != fileSize){
System.out.println(fileName + " File size mismatch");
deleteFile();
break;
}else{
System.out.println( fileName + " File written");
break;
}
}
}
}catch (IOException ioe){
if(Server.DEBUG)
ioe.printStackTrace();
}
Client code:
try(
FileInputStream fileInput = new FileInputStream(file);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
){
byte[] arr = new byte[chunkSize];
try {
int len = 0;
int bytesRead = 0;
int chunkCount = 1;
while((len = fileInput.read(arr, 0, chunkSize)) != -1)
{
out.write(arr, 0, len);
out.flush();
bytesRead += len;
}
try {
System.out.println("wait ack");
socket.setSoTimeout(timeout);
String ack = (String) in.readObject();
System.out.println(ack);
if(bytesRead >= fileSize){
out.writeObject(Server.UPLOAD_COMPLETE_MSG);
System.out.println(Server.UPLOAD_COMPLETE_MSG);
break;
}else{
out.writeObject(Server.CHUNK_ACKNOWLEDGE_MSG);
}
}catch (SocketTimeoutException e){
out.writeObject(Server.UPLOAD_ACKNOWLEDGE_RECEIVE_TIMEOUT_MSG);
System.out.println(Server.UPLOAD_ACKNOWLEDGE_RECEIVE_TIMEOUT_MSG);
break;
}finally {
socket.setSoTimeout(0);
}
}
}
}catch (IOException ioe){
ioe.printStackTrace();
}
}catch (FileNotFoundException fnfe){
System.out.println("No such file: " + fileName);
}catch (Exception e){
e.printStackTrace();
}
finally {
try {
socket.close();
}catch (Exception ex){
ex.printStackTrace();
}
}
I tried writing the byte array to another file on the client side and the copy was identical. So the problem must be during sending data over socket.
The Server.X_MSG is just a constant string. I don't know if mixing readobject() and read(bytearray) on the same ObjectInputStream causes any issues though.
Maybe it's because fileOut.write(arr, 0, len); use arr and len = in.read(bytes,0, chunkSize); use bytes? They are not the same array.
Related
I am reading a .jpg file over InputStream using this code but I am receiving NULNUL...n stream after some text. Ii am reading this file link to file and link of file that I received , link is Written File link.
while ((ret = input.read(imageCharArray)) != -1) {
packet.append(new String(imageCharArray, 0, ret));
totRead += ret;
imageCharArray = new char[4096];
}
file = new File(
Environment.getExternalStorageDirectory()
+ "/FileName_/"
+ m_httpParser.filename + ".jpg");
PrintWriter printWriter = new PrintWriter(file);
// outputStream = new FileOutputStream(file); //also Used FileoutputStream for writting
// outputStream.write(packet.toString().getBytes());//
// ,
printWriter.write(packet.toString());
// outputStream.close();
printWriter.close();
}
I have also tried FileoutputStream but hardlucj for this too as commented in my code.
Edit
I have used this also. I have a content length field upto which i am reading and writing
byte[] bytes = new byte[1024];
int totalReadLength = 0;
// read untill we have bytes
while ((read = inputStream.read(bytes)) != -1
&& contentLength >= (totalReadLength)) {
outputStream.write(bytes, 0, read);
totalReadLength += read;
System.out.println(" read size ======= "
+ read + " totalReadLength = "
+ totalReadLength);
}
String is not a container for binary data, and PrintWriter isn't a way to write it. Get rid of all, all, the conversions between bytes and String and vice versa, and just transfer the bytes with input and output streams:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
If you need to constrain the number of bytes read from the input, you have to do that before calling read(), and you also have to constrain the read() correctly:
while (total < length && (count = in.read(buffer, 0, length-total > buffer.length ? buffer.length: (int)(length-total))) > 0)
{
total += count;
out.write(buffer, 0, count);
}
I tested it in my Nexus4 and it's working for me. Here is the snippet of code what I tried :
public void saveImage(String urlPath)throws Exception{
String fileName = "kumar.jpg";
File folder = new File("/sdcard/MyImages/");
// have the object build the directory structure, if needed.
folder.mkdirs();
final File output = new File(folder,
fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
// InputStreamReader reader = new InputStreamReader(stream);
DataInputStream dis = new DataInputStream(url.openConnection().getInputStream());
byte[] fileData = new byte[url.openConnection().getContentLength()];
for (int x = 0; x < fileData.length; x++) { // fill byte array with bytes from the data input stream
fileData[x] = dis.readByte();
}
dis.close();
fos = new FileOutputStream(output.getPath());
fos.write(fileData);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Just Call the above function in a background thread and pass your url. It'll work for sure. Let me know if it helps.
You can check below code.
destinationFile = new File(
Environment.getExternalStorageDirectory()
+ "/FileName_/"
+ m_httpParser.filename + ".jpg");
BufferedOutputStream buffer = new BufferedOutputStream(new FileOutputStream(destinationFile));
byte byt[] = new byte[1024];
int i;
for (long l = 0L; (i = input.read(byt)) != -1; l += i ) {
buffer.write(byt, 0, i);
}
buffer.close();
I have a TCP server that accepts data and saves it to a text file. It then uses that text file to create an image and sends it back to the client. Every couple of hours I will get a NullPointerException that gets thrown to every client that connects after that. I am not sure how to go about debugging this as I cannot replicate it on my own.
Does anyone have any debugging practices to help me figure out why this is becoming a problem?
The server running is running Ubuntu 12.04 i386 with 2 gigs of RAM. My initial suspicion is that something is not getting closed properly and creating issues but everything should be getting closed as far as I can tell.
ServerSocket echoServer = null;
Socket clientSocket = null;
try {
echoServer = new ServerSocket(xxx);
} catch (IOException e) {
System.out.println(e);
}
while(true)
{
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream out = null;
try {
//Receieve text file
is = null;
fos = null;
bos = null;
bufferSize = 0;
String uid = createUid();
try {
clientSocket = echoServer.accept();
clientSocket.setKeepAlive(true);
clientSocket.setSoTimeout(10000);
System.out.println("Client accepted from: " + clientSocket.getInetAddress());
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
is = clientSocket.getInputStream();
bufferSize = clientSocket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
fos = new FileOutputStream("/my/diretory/" + uid + ".txt");
bos = new BufferedOutputStream(fos);
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
System.out.println("Receiving... " + count);
}
System.out.println("Done receiving text file");
bos.flush();
bos.close();
fos.close();
//image
String[] command = new String[3];
command[0] = "python";
command[1] = "imagecreationfile.py";
command[2] = uid;
System.out.println("Starting python script");
Boolean success = startScript(command);
if(success)
{
System.out.println("Script completed successfully");
//Send image here
String image = "/my/directory/" + uid + ".png";
File imageFile = new File(image);
long length = imageFile.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
bytes = new byte[(int) length];
fis = new FileInputStream(imageFile);
bis = new BufferedInputStream(fis);
out = new BufferedOutputStream(clientSocket.getOutputStream());
count = 0;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
System.out.println("Writing... " + count);
}
out.flush();
out.close();
fis.close();
bis.close();
}
else
{
System.out.println("Script failed");
}
System.out.println("Closing connection");
is.close();
clientSocket.close();
} catch (Exception e) {
System.out.println(e); //This is where the exception is being caught
}
if(!clientSocket.isClosed())
{
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
if(is != null)
is.close();
if(fos != null)
fos.close();
if(bos != null)
bos.close();
if(fis != null)
fis.close();
if(bis != null)
bis.close();
if(out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Maybe exception was thrown in one of your try-catch scope.
And the next try-catch scope found null variables.
for example
//Receieve text file
is = null;
fos = null;
bos = null;
bufferSize = 0;
String uid = createUid();
try {
clientSocket = echoServer.accept();
clientSocket.setKeepAlive(true);
clientSocket.setSoTimeout(10000);
System.out.println("Client accepted from: " + clientSocket.getInetAddress());
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
is = clientSocket.getInputStream();
bufferSize = clientSocket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
if IOException was thrown in "clientSocket = echoServer.accept();" , it will print "Can't accept client connection. ".
When, "is = clientSocket.getInputStream();" executed, it will throw NullPointer because "clientSocket" was not initialized properly.
My suggestion, dont break a sequenced statement in different try-catch scope until it necessary.
Below is my code to convert a PDF file to byte array
public class ByteArrayExample{
public static void main(String[] args) {
try{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter File name: ");
String str = bf.readLine();
File file = new File(str);
//File length
int size = (int)file.length();
if (size > Integer.MAX_VALUE){
System.out.println("File is to larger");
}
byte[] bytes = new byte[size];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
int read = 0;
int numRead = 0;
while (read < bytes.length && (numRead=dis.read(bytes, read,
bytes.length-read)) >= 0) {
read = read + numRead;
}
System.out.println("File size: " + read);
// Ensure all the bytes have been read in
if (read < bytes.length) {
System.out.println("Could not completely read: "+file.getName());
}
}
catch (Exception e){
e.getMessage();
}
}
}
Issue is this actually converts the file name into the byte array not the actual PDF file.Can anyone please help me with this.
I added this to the end to check it and it copied the PDF file. Your code is working fine
dis.close();
DataOutputStream out = new DataOutputStream(new FileOutputStream(new File("c:\\out.pdf")));
out.write(bytes);
out.close();
System.out.println("File size: " + read);
// Ensure all the bytes have been read in
if (read < bytes.length) {
System.out.println("Could not completely read: "+file.getName());
}
edit: here is my entire code, its just copied from yours. I ran it in IDE (eclipse) and entered "c:\mypdf.pdf" for the input and it copied it to out.pdf. Identical Copys. Do note that I did close both streams which I noticed you forgot to do in your code.
public class Main {
public static void main(String[] args) {
try {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter File name: ");
String str = bf.readLine();
File file = new File(str);
//File length
int size = (int) file.length();
if (size > Integer.MAX_VALUE) {
System.out.println("File is to larger");
}
byte[] bytes = new byte[size];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
int read = 0;
int numRead = 0;
while (read < bytes.length && (numRead = dis.read(bytes, read,
bytes.length - read)) >= 0) {
read = read + numRead;
}
dis.close();
DataOutputStream out = new DataOutputStream(new FileOutputStream(new File("c:\\out.pdf")));
out.write(bytes);
out.close();
System.out.println("File size: " + read);
// Ensure all the bytes have been read in
if (read < bytes.length) {
System.out.println("Could not completely read: " + file.getName());
}
} catch (Exception e) {
e.getMessage();
}
}
}
Im try to pass audio between sockets but it pass one time in client than clients stops working.
I think the way im writing and sending may be wrong please help me regarding this code
Following is my server code :
public void run(){
try{
SetInitialSettings();
int bufferSize = (int) format.getSampleRate() * (int) format.getFrameSize();
System.out.println("length :" +bufferSize);
out = new ByteArrayOutputStream();
readagain=true;
while(record){
int count=0;
for(int i=0;i<1000;i++)
{
if(buffer==null){
buffer = new byte[bufferSize];
}
count = line.read(buffer, 0, buffer.length);
if (count > 0) {
//out.write(buffer, 0, count);
//readagain=false;
for (int j=0;i<ser.clientReceiver.audioSender.size();j++){
ser.clientReceiver.audioSender.get(i).cliOut.write("Audio".getBytes());
ser.clientReceiver.audioSender.get(i).cliOut.write('\n');
ser.clientReceiver.audioSender.get(i).cliOut.flush();
ser.clientReceiver.audioSender.get(i).cliOut.write(buffer,0,count);
ser.clientReceiver.audioSender.get(i).cliOut.flush();
Thread.sleep(2000);
}
}
}
}
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
}
and following is my client code :
public void run(){
try{
//audioReceiver = new TAudioReceiver(cli);
//audioReceiver.start();
while(true){
//Thread.sleep(1000);
System.out.println("reading token");
cmd= cli.BufferedReader().readLine();
System.out.println("token :" +cmd);
switch (cmd) {
case "Msg":
message = cli.BufferedReader().readLine();
cmd="None";
break;
case "File":
GetFile();
break;
case "Audio":
PlayAudio();
break;
}
}
//reading msgs here
}
catch(Exception ex)
{
//throw new InterruptedException(ex.getMessage());
}
}
this is the function need to run when "audio" msg received from server to client
public void PlayAudio()throws Exception{
try{
cli.ServerInputStream().read(buffer);
audio = buffer;
audioIn = new ByteArrayInputStream(audio);
AudioFormat f = new AudioFormat(8000, 8, 1,true, true);
ain= new AudioInputStream(audioIn,f, audio.length/f.getFrameSize());
DataLine.Info info = new DataLine.Info(SourceDataLine.class, f);
try (SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info)) {
int bufferSize = (int) f.getSampleRate()* f.getFrameSize();
buffer= new byte[bufferSize];
int count;
while ((count = ain.read(buffer, 0, buffer.length)) != -1) {
if (count > 0) {
line.write(buffer, 0, count);
}
}
line.drain();
}
}
catch(Exception ex)
{
System.out.println("file" + ex.getMessage());
}
}
Your original code was better. You must write(buffer, 0, count), not write(buffer). Otherwise you are writing junk at the end of each buffer that wasn't read by the last read. Your second piece of code ignores the result of read().
I was trying to save a image from a link in a website I have written this code but this does not work ..plz help me to do this
public void imageshow(String linkText) {
try {
URL url = new URL(linkText);
InputStream in = new BufferedInputStream(url.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[4 * 1024];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
FileOutputStream fos = new FileOutputStream("C://chart.gif");
fos.write(response);
fos.close();
} catch (Exception e) {
}
}
Taken from here
import java.net.*;
import java.io.*;
public class DownloadFile
{
public static void main(String[] args)
{
try
{
/*
* Get a connection to the URL and start up
* a buffered reader.
*/
long startTime = System.currentTimeMillis();
System.out.println("Connecting to Mura site...\n");
URL url = new URL("http://www.getmura.com/currentversion/");
url.openConnection();
InputStream reader = url.openStream();
/*
* Setup a buffered file writer to write
* out what we read from the website.
*/
FileOutputStream writer = new FileOutputStream("C:/mura-newest.zip");
byte[] buffer = new byte[153600];
int totalBytesRead = 0;
int bytesRead = 0;
System.out.println("Reading ZIP file 150KB blocks at a time.\n");
while ((bytesRead = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, bytesRead);
buffer = new byte[153600];
totalBytesRead += bytesRead;
}
long endTime = System.currentTimeMillis();
System.out.println("Done. " + (new Integer(totalBytesRead).toString()) + " bytes read (" + (new Long(endTime - startTime).toString()) + " millseconds).\n");
writer.close();
reader.close();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}