EOFExcpetion while deserialization by byte array - java

I've got a EOFException while decompress and deserialization a byte array.
Stacktrace:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2324)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2793)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:799)
at java.io.ObjectInputStream.(ObjectInputStream.java:299)
at com.chuck.pack.ResourcePacket.load(ResourcePacket.java:44)
// Functions related to load
public static ResourcePacket load(String packetName) {
try {
byte[] bytes = uncompress(fileToByteArray(new File(packetName)));
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
ObjectInputStream objIn = new ObjectInputStream(in); // Error occured here
return (ResourcePacket) objIn.readObject();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static byte[] uncompress(byte[] bytes) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Inflater ifl = new Inflater();
ifl.setInput(bytes);
byte[] buffer = new byte[4*1024];
while(ifl.finished()) {
int size = ifl.inflate(buffer);
out.write(buffer, 0, size);
}
out.close();
return out.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Error while load");
}
return null;
}
private static byte[] fileToByteArray(File file) {
byte[] bytes = new byte[(int) file.length()];
try {
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(bytes);
fileInputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return bytes;
}
// Functions related to save
public void save() {
try {
byte[] bytes = compress(toByteArray());
//byte[] bytes = toByteArray();
FileOutputStream fileOutputStream = new FileOutputStream(packetName);
fileOutputStream.write(bytes);
fileOutputStream.close();
System.out.println("Packet saved (" + resourceFiles.length + " Files)");
} catch (IOException ex) {
ex.printStackTrace();
System.exit(-1);
}
}
private byte[] compress(byte[] bytes) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Deflater dfl = new Deflater();
dfl.setLevel(Deflater.BEST_SPEED);
dfl.setInput(bytes);
dfl.finish();
byte[] tmp = new byte[4*1024];
while(!dfl.finished()) {
int size = dfl.deflate(tmp);
out.write(tmp, 0, size);
}
out.close();
return out.toByteArray();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Error while save");
}
System.exit(-1);
return null;
}
private byte[] toByteArray() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(this);
byte[] bytes = bos.toByteArray();
return bytes;
} catch(IOException ex) {
ex.printStackTrace();
System.out.println("Error while create byte array");
}
System.exit(-1);
return null;
}
Someone an idee to fix this?

In the uncompress(..) method the while loop:
while(ifl.finished()) {
int size = ifl.inflate(buffer);
out.write(buffer, 0, size);
}
should be
while(!ifl.finished()) {
int size = ifl.inflate(buffer);
out.write(buffer, 0, size);
}
Otherwise the result of uncompress(..) is an empty byte array if the method terminates.

Related

Get progress of readBytes in android

I've already seen
Is it possible to check progress of URLconnection.getInputStream()?
https://stackoverflow.com/a/20120451/5437621
I'm using the following code to download a file from internet:
try {
InputStream is = new URL(pdfUrl).openStream();
byte[] pdfData = readBytes(is);
return pdfData;
} catch (IOException e) {
e.printStackTrace();
return null;
}
public byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
Is there any method I can get the progress of the file being downloaded ?
The answers I have seen are using a while loop but I don't understand how to use it in this case.
EDIT:
I'm using this in AsyncTask:
protected byte[] doInBackground(String... url) {
pdfUrl = url[0];
try {
InputStream is = new URL(pdfUrl).openStream();
DownloadBytes downloadData = readBytes(is);
byte[] pdfData = downloadData.getBytes();
progress = downloadData.getProgress();
return pdfData;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
How can I adjust publishProgress() in this method ?

How to receive file from multiple clients?

I created a program which will send a file to the server or to clients
my problem is I have 2 clients and they both need to send a file to the server
what happens is that the server is able to receive the file only from 1 client(the one who sends the file first)
how can I resolve this problem?
here's my code:
SERVER
private void sendFile(File file)throws IOException
{
Socket socket = null;
String host = "127.0.0.1";
String receiver=txtReceiver.getSelectedItem().toString();
int port=0;
if(receiver=="Client1")
{
host="127.0.0.2";
port=4441;
}
else if(receiver=="Client2")
{
port=4442;
host="127.0.0.3";
}
else if(receiver=="Server")
{
port=4440;
host="127.0.0.1";
}
socket = new Socket(host, port);
//File file = new File("Client.txt");
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
int count;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
}
public static void main(String args[]) throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(4440);
} catch (IOException ex)
{
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
try
{
socket = serverSocket.accept();
} catch (IOException ex)
{
System.out.println("Can't accept client connection. ");
}
try
{
is = socket.getInputStream();
bufferSize = socket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex)
{
System.out.println("Can't get socket input stream. ");
}
try
{
fos = new FileOutputStream("C:\\Users\\Jake_PC\\Documents\\NetBeansProjects\\OJT2\\ServerReceivables\\file.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);
}
bos.flush();
bos.close();
is.close();
socket.close();
serverSocket.close();
CLIENT
public static void main(String args[])throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(4441);
} catch (IOException ex)
{
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
try
{
socket = serverSocket.accept();
} catch (IOException ex)
{
System.out.println("Can't accept client connection. ");
}
try
{
is = socket.getInputStream();
bufferSize = socket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex)
{
System.out.println("Can't get socket input stream. ");
}
//C:\Users\Jake_PC\Documents\NetBeansProjects\OJT2
try
{
fos = new FileOutputStream("C:\\Users\\Jake_PC\\Documents\\NetBeansProjects\\OJT2\\Client1Receivables\\file.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);
}
bos.flush();
bos.close();
is.close();
socket.close();
serverSocket.close();
}
private void sendFile(File file)throws IOException
{
Socket socket = null;
String host = "127.0.0.1";
String receiver=txtReceiver.getSelectedItem().toString();
int port=0;
if(receiver=="Client1")
{
port=4441;
}
else if(receiver=="Client2")
{
port=4442;
}
else if(receiver=="Server")
{
port=4440;
}
socket = new Socket(host, port);
//File file = new File("Client.txt");
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
int count;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
}
You need to start a new thread to handle each accepted socket. Examples abound. See for example the Custom Networking trail in the Java Tutorial.

how to use filechannel as argument to write object

In my homework
writePosting(FileChannel fc, PostingList posting)
It seems to use fc to write contents of a class postingList, where PostingList contain an integer and a List.
But I find fc could only write bytes?....I do not even understand, why we put FileChannel as a parameter rather than a inputStream?
Could it write directly an integter or string? thanks!
You can accomplish that using serialization.
Class PostingList:
public class PostingList<T extends Serializable> implements Serializable{
private static final long serialVersionUID = 6893022784519772456L;
private Integer number;
private List<T> list;
public PostingList(Integer number, List<T> list) {
super();
this.number = number;
this.list = list;
}
#Override
public String toString() {
return "PostingList [number=" + number + ", list=" + list + "]";
}
}
writePosting:
public static void writePosting(FileChannel fc, PostingList<Integer> posting)
throws IOException {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(posting);
oos.flush();
byte[] postingBytes = baos.toByteArray();
System.out.println("Bytes read: " + postingBytes.length);
ByteBuffer buffer = ByteBuffer.allocate(postingBytes.length);
// prepare buffer to fill with data.
buffer.clear();
// write the bytes
buffer.put(postingBytes);
// prepare for writing
buffer.flip();
fc.write(buffer);
} finally {
if (oos != null) {
oos.close();
}
if (baos != null) {
baos.close();
}
}
}
And an extra method, readPosting :
#SuppressWarnings({ "rawtypes", "unchecked" })
private static PostingList<Integer> readPosting(FileChannel fc)
throws IOException, ClassNotFoundException {
// Better to set this to a higher number
byte[] barray = new byte[32];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteBuffer buffer = ByteBuffer.allocate(32);
int bytesRead = 0;
while ((bytesRead = fc.read(buffer)) != -1) {
buffer.flip();
buffer.get(barray, 0, bytesRead);
bos.write(barray, 0, bytesRead);
buffer.clear();
// for testing
System.out.println(bytesRead);
}
// We write the bytes recovered to an object
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
Object obj = null;
try {
bis = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bis);
obj = ois.readObject();
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
return (PostingList) obj;
}
And a little test in the main method:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 5; i++) {
list.add(i);
}
PostingList<Integer> pl = new PostingList<Integer>(100, list);
File f = new File("out.dat");
RandomAccessFile raf = null;
FileChannel fc = null;
try {
raf = new RandomAccessFile(f, "rw");
fc = raf.getChannel();
writePosting(fc, pl);
fc.close();
raf.close();
raf = new RandomAccessFile(f, "r");
fc = raf.getChannel();
System.out.println(readPosting(fc));
fc.close();
raf.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
if (fc!=null) {
try {
fc.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (raf!=null) {
try {
raf.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Basically, this is reading/writing serialized objects into a file, but with FileChannel instead of the classic way.
EDIT:
Output:
Bytes read: 301
32
32
32
32
32
32
32
32
32
13
PostingList [number=100, list=[0, 1, 2, 3, 4]]

GZIP compression to a byte array

I am trying to write a class that can compress data. The below code fails (no exception is thrown, but the target .gz file is empty.)
Besides: I don't want to generate the .gz file directly like it is done in all examples. I only want to get the compressed
data, so that I can e.g. encrypt it before writting the data to a file.
If I write directly to a file everything works fine:
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
GZIPOutputStream zipStream = null;
FileOutputStream fileStream = null;
try
{
fileStream = new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
zipStream = new GZIPOutputStream(fileStream);
zipStream.write(dataToCompress);
fileStream.write(compressedData);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{ zipStream.close(); }
catch(Exception e){ }
try{ fileStream.close(); }
catch(Exception e){ }
}
}
}
But, if I want to 'bypass' it to the byte array stream it does not produce a single byte - compressedData is always empty.
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
byte[] compressedData = null;
GZIPOutputStream zipStream = null;
ByteArrayOutputStream byteStream = null;
FileOutputStream fileStream = null;
try
{
byteStream = new ByteArrayOutputStream(dataToCompress.length);
zipStream = new GZIPOutputStream(byteStream);
zipStream.write(dataToCompress);
compressedData = byteStream.toByteArray();
fileStream = new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
fileStream.write(compressedData);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{ zipStream.close(); }
catch(Exception e){ }
try{ byteStream.close(); }
catch(Exception e){ }
try{ fileStream.close(); }
catch(Exception e){ }
}
}
}
The problem is that you are not closing the GZIPOutputStream. Until you close it the output will be incomplete.
You just need to close it before reading the byte array. You need to reorder the finally blocks to achieve this.
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
try
{
ByteArrayOutputStream byteStream =
new ByteArrayOutputStream(dataToCompress.length);
try
{
GZIPOutputStream zipStream =
new GZIPOutputStream(byteStream);
try
{
zipStream.write(dataToCompress);
}
finally
{
zipStream.close();
}
}
finally
{
byteStream.close();
}
byte[] compressedData = byteStream.toByteArray();
FileOutputStream fileStream =
new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
try
{
fileStream.write(compressedData);
}
finally
{
try{ fileStream.close(); }
catch(Exception e){ /* We should probably delete the file now? */ }
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
I do not recommend inititalizing the stream variables to null, because it means your finally block can also throw a NullPointerException.
Also note that you can declare main to throw IOException (then you would not need the outermost try statement.)
There is little point in swallowing exceptions from zipStream.close();, because if it throws an exception you will not have a valid .gz file (so you should not proceed to write it.)
Also I would not swallow exceptions from byteStream.close(); but for a different reason - they should never be thrown (i.e. there is a bug in your JRE and you would want to know about that.)
I've improved JITHINRAJ's code - used try-with-resources:
private static byte[] gzipCompress(byte[] uncompressedData) {
byte[] result = new byte[]{};
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(uncompressedData.length);
GZIPOutputStream gzipOS = new GZIPOutputStream(bos)) {
gzipOS.write(uncompressedData);
// You need to close it before using bos
gzipOS.close();
result = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
private static byte[] gzipUncompress(byte[] compressedData) {
byte[] result = new byte[]{};
try (ByteArrayInputStream bis = new ByteArrayInputStream(compressedData);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPInputStream gzipIS = new GZIPInputStream(bis)) {
byte[] buffer = new byte[1024];
int len;
while ((len = gzipIS.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
result = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
If you are still looking an answer you can use the below code to get the compressed byte[] using deflater and decompress it using inflater.
public static void main(String[] args) {
//Some string for testing
String sr = new String("fsdfesfsfdddddddsfdsfssdfdsfdsfdsfdsfdsdfggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghghghghggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfsdfesfsfdddddddsfdsfssdfdsfdsfdsfdsfdsdfggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghghghghggggggggggggggggggggggggggggggggggggggggg");
byte[] data = sr.getBytes();
System.out.println("src size "+data.length);
try {
compress(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] compress(byte[] data) throws IOException {
Deflater deflater = new Deflater();
deflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
deflater.finish();
byte[] buffer = new byte[1024];
while (!deflater.finished()) {
int count = deflater.deflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] output = outputStream.toByteArray();
System.out.println("Original: " + data.length );
System.out.println("Compressed: " + output.length );
return output;
}
To compress
private static byte[] compress(byte[] uncompressedData) {
ByteArrayOutputStream bos = null;
GZIPOutputStream gzipOS = null;
try {
bos = new ByteArrayOutputStream(uncompressedData.length);
gzipOS = new GZIPOutputStream(bos);
gzipOS.write(uncompressedData);
gzipOS.close();
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
assert gzipOS != null;
gzipOS.close();
bos.close();
}
catch (Exception ignored) {
}
}
return new byte[]{};
}
To uncompress
private byte[] uncompress(byte[] compressedData) {
ByteArrayInputStream bis = null;
ByteArrayOutputStream bos = null;
GZIPInputStream gzipIS = null;
try {
bis = new ByteArrayInputStream(compressedData);
bos = new ByteArrayOutputStream();
gzipIS = new GZIPInputStream(bis);
byte[] buffer = new byte[1024];
int len;
while((len = gzipIS.read(buffer)) != -1){
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
assert gzipIS != null;
gzipIS.close();
bos.close();
bis.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
return new byte[]{};
}
You can use the below function, it is tested and working fine.
In general, your code has serious problem of ignoring the exceptions! returning null or simply not printing anything in the catch block will make it very difficult to debug
You do not have to write the zip output to a file if you want to process it further (e.g. encrypt it), you can easily modify the code to write the output to in-memory stream
public static String zip(File inFile, File zipFile) throws IOException {
FileInputStream fis = new FileInputStream(inFile);
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fos);
try {
zout.putNextEntry(new ZipEntry(inFile.getName()));
byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = fis.read(buffer)) > 0) {
zout.write(buffer, 0, len);
}
zout.closeEntry();
} catch (Exception ex) {
ex.printStackTrace();
return null;
} finally {
try{zout.close();}catch(Exception ex){ex.printStackTrace();}
try{fis.close();}catch(Exception ex){ex.printStackTrace();}
}
return zipFile.getAbsolutePath();
}
Most of the examples have wrong exception handling.
public static byte[] gzipBytes(byte[] payload) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(baos)) {
gzip.write(payload);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
// note: toByteArray should be called after try-with-resources, not inside
return baos.toByteArray();
}
public static byte[] gunzipBytes(byte[] gzPayload) {
ByteArrayInputStream bais = new ByteArrayInputStream(gzPayload);
try (GZIPInputStream gzip = new GZIPInputStream(bais)) {
// java 9+ required for this method
return gzip.readAllBytes();
} catch (IOException e) {
throw new UncheckedIOException("Error while unpacking gzip content", e);
}
}
Try with this code..
try {
String inputFileName = "test.txt"; //may use your file_Path
String zipFileName = "compressed.zip";
//Create input and output streams
FileInputStream inStream = new FileInputStream(inputFileName);
ZipOutputStream outStream = new ZipOutputStream(new FileOutputStream(zipFileName));
// Add a zip entry to the output stream
outStream.putNextEntry(new ZipEntry(inputFileName));
byte[] buffer = new byte[1024];
int bytesRead;
//Each chunk of data read from the input stream
//is written to the output stream
while ((bytesRead = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, bytesRead);
}
//Close zip entry and file streams
outStream.closeEntry();
outStream.close();
inStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
Also may be helpful this one..
http://www.java-samples.com/java/zip_files_in_a_folder_using_java.htm

Java socket inpustream stuck

I have problem with reading from socket inputStream. But only in one method in class. Here is my code:
server:
private void copyFile(String mainPath, String path) {
outS.println("Sending file!");
outS.println(path);
outS.flush();
BufferedInputStream fis = null;
OutputStream os;
File file = new File(mainPath);
String str;
byte[] buffer = new byte[4096];
long numOfChunks = file.length() / 4096, num = 0, lng;
try {
fis = new BufferedInputStream(new FileInputStream(file));
os = socket.getOutputStream();
outS.println(numOfChunks);
fis.read(buffer, 0, 4096);
os.write(buffer, 0, buffer.length);
os.flush();
num++;
} catch (FileNotFoundException ex) {
System.out.println("<ERROR> Clerk, copyFile: File not found.");
System.out.println(ex);
} catch (IOException ex) {
System.out.println("<ERROR> Clerk, copyFile: Could not write or read file.");
System.out.println(ex);
} finally {
try {
fis.close();
} catch (IOException ex) {
Logger.getLogger(Clerk.class.getName()).log(Level.SEVERE, null, ex);
}
}
waitEnd();
}
client:
private void copyFile(String destination) {
FileOutputStream fos = null;
long numOfChunks, num = 0;
SBuffer sBuffer;
byte[] buffer = new byte[4096];
InputStream is;
try {
fos = new FileOutputStream(new File(destination));
BufferedOutputStream bos = new BufferedOutputStream(fos);
is = socket.getInputStream();
numOfChunks = Long.parseLong(inS.readLine());
System.out.println(num + "/" + numOfChunks);
int bytesRead = is.read(buffer, 0, buffer.length);
bos.write(buffer, 0, bytesRead);
num++;
} catch (FileNotFoundException ex) {
System.out.println("<ERROR> Client, copyFile: File not found.");
System.out.println(ex);
} catch (IOException ex) {
System.out.println("<ERROR> Client, copyFile: Could not write or read file.");
System.out.println(ex);
} finally {
try {
fos.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
outS.println("end");
outS.flush();
}
Let me explain few things. Everythings goes fine, but client on line int bytesRead = is.read(buffer, 0, buffer.length) will stuck, because nothing is in stream (is.available = 0 ). And i don't know why. Although i send it from server many times.
And I can't close stream, because socket will close too.
Method waitEnd() waits for string "end" in socket's input stream.
I have searched many tutorials and things on internet, but no one help.
Code which establish connection:
Server:
public void run() {
try {
ssocket = new ServerSocket(2332);
Socket socket = ssocket.accept();
clerk = new Clerk(socket, mainPath);
(new Thread(clerk)).start();
} catch (IOException ex) {
}
try {
ssocket.close();
} catch (IOException ex) {
}
}
public Clerk(Socket socket, String path) {
this.socket = socket;
mainTree = new FileTree(path);
}
public Client(String address, String[] dirs) {
try {
socket = new Socket(address, 2332);
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
Client and clerk has same method run:
#Override
public void run() {
try {
inS = new BufferedReader(iss);
outS = new PrintWriter(socket.getOutputStream(), true);
oos = new ObjectOutputStream(socket.getOutputStream());
iss = new InputStreamReader(socket.getInputStream());
ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException ex) {
}
msg();
try {
inS.close();
iss.close();
outS.close();
ois.close();
oos.close();
socket.close();
} catch (IOException ex) {
}
}
Resolved. I created second socket for file transfer only.

Categories

Resources