У меня есть клиент для планшета Android, который отправляет и получает несколько файлов между ним и java-сервером, работающим на Windows 7. Все работает отлично, за исключением одной странной проблемы. один из файлов, в этом примере, transfer.pdf, который получен от клиентского планшета Android, не может быть открыт и показывает размер 0. когда я пытаюсь открыть этот файл, я получаю сообщение об ошибке от Adobe Reader «этот файл уже открыт или используется другим приложением».
единственный способ решить эту проблему - использовать System.exit(0) для закрытия всего приложения, если я сделаю это, файл покажет правильный размер и откроется без проблем. однако я бы предпочел не использовать System.exit(0). Я пробовал все, и ничего больше не работало.
блок finally используется для закрытия всех входных и выходных сокетов, и после закрытия я устанавливаю переменные файла и сокет в нуль.
у кого-нибудь еще была эта проблема и как я могу заставить ее работать без использования System.exit(0)?
код для сервера
public class MultiThreader implements Runnable {
Socket socket;
File fileDirectory;
File file;
public int fileSizeFromClient;
FileOutputStream fos = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
DataInputStream dis = null;
DataOutputStream dos = null;
long length;
public MultiThreader(Socket socket){
System.out.println("print out from multithreader class");
this.socket = socket;
} // multiThreader
@Override
public void run() {
System.out.println("multi threader started");
//================================================================================================
//==== action #1 read in transfer.pdf file from client ===========================================
int bufferSize = 0;
try {
bis = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(bis);
fileSizeFromClient = dis.readInt();
System.out.println("file size for transfer.pdf from client is " + fileSizeFromClient);
fileDirectory = new File("C:/DOWNLOAD/");
if (!fileDirectory.exists()) {
fileDirectory.mkdir();
}
file = new File("C:/DOWNLOAD/transfer.pdf");
file.createNewFile();
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
dos = new DataOutputStream(bos);
byte[] buffer = new byte[fileSizeFromClient];
int totalBytesRead = 0;
while(totalBytesRead < fileSizeFromClient){
int bytesRemaining = fileSizeFromClient - totalBytesRead;
int bytesRead = dis.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining));
if(bytesRead == -1) {
break;
} else {
dos.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
} // while
// =====================================================================================================
// === action #2 send transfer2.pdf file to client =====================================================
file = new File("C:/DOWNLOAD/transfer2.pdf");
file.createNewFile();
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
bos = new BufferedOutputStream(socket.getOutputStream());
dos = new DataOutputStream(bos);
length = file.length();
System.out.println("file size for transfer2.pdf sent to client is " + length);
dos.writeInt((int) length);
int count = 0;
buffer = new byte[(int)length];
while((count = bis.read(buffer)) > 0){
bos.write(buffer, 0, count);
}
//=====================================================================================
//=== action #3 read in transferImage.jpg from client =================================
bufferSize = 0;
bis = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(bis);
fileSizeFromClient = dis.readInt();
System.out.println("file size for transferImage.jpg from client is " + fileSizeFromClient);
file = new File("C:/DOWNLOAD/transferImage.jpg");
file.createNewFile();
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
dos = new DataOutputStream(bos);
buffer = new byte[fileSizeFromClient];
totalBytesRead = 0;
while(totalBytesRead < fileSizeFromClient){
int bytesRemaining = fileSizeFromClient - totalBytesRead;
int bytesRead = dis.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining));
if(bytesRead == -1) {
break;
} else {
dos.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
} // while
//=====================================================================================
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
bis.close();
fis.close();
dis.close();
fos.flush();
fos.close();
bos.flush();
bos.close();
dos.flush();
dos.close();
socket.close();
file = null;
fileDirectory = null;
// System.exit(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} // run
} // MultiThreader
public class Server {
ServerSocket serverSocket;
Socket socket;
boolean runner = true;
Server() throws IOException{
serverRunner();
System.out.println("server constructor started");
} // Server constructor
public void serverRunner() throws IOException {
System.out.println("serverrunner started");
try {
serverSocket = new ServerSocket(6789, 100);
runner = true;
while (runner) {
socket = serverSocket.accept();
MultiThreader multi = new MultiThreader(socket);
Thread t = new Thread(multi);
t.start();
} // while runner
} catch (IOException ex) {
}
} // serverRunner
} // class Server
BufferedOutputStream
? - person Elliott Frisch   schedule 07.01.2014BufferedOutputStream
уже выполняет буферизацию... просто записывайте по одному байту за раз и дайте ему разобраться с этим. - person Elliott Frisch   schedule 07.01.2014write(byte[], int, int).
. Я согласен, что в данном случае это не обязательно должен бытьBufferedOutputStream
, но записывать побайтно во что-либо никогда не бывает хорошей идеей. - person user207421   schedule 07.01.2014