Клиент-сервер не отправляет весь файл
Когда я запускаю свой клиентский сервер - который подключается и пытаюсь отправить файл, он не отправляет весь файл, который вызывает ошибки, где-то еще, он проходит примерно на полпути и постоянно останавливается на одной и той же части. Эта настройка работает при запуске сервера-клиента на той же машине, поэтому я полностью запутался
Сервер --->
// output (a DataOutputstream) is set up elsewhere and messages are sent and received properly
output.writeInt((int)file.length());
// send file
byte [] mybytearray = new byte [(int)file.length()];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
System.out.println("Sending " + file + "(" + mybytearray.length + " bytes)");
output.write(mybytearray,0,mybytearray.length);
output.flush();
System.out.println("Done.");
Клиент --->
// input (a DataInputstream) is set up elsewhere and messages are sent and received properly
String FILE_TO_RECEIVED = "Load_From.xml";
File file = new File(FILE_TO_RECEIVED);
int FILE_SIZE = input.readInt();
if(FILE_SIZE!=0){
// receive file
System.out.println("received file size : " + FILE_SIZE);
byte [] mybytearray = new byte [FILE_SIZE];
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = input.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
2 ответа
Вы читаете только часть данных, как при чтении файла, так и при чтении сокета. read
Метод возвращает количество прочитанных байтов, и вам нужен цикл, чтобы прочитать все. Например,
int read = 0, offset = 0;
while ((read = bis.read(mybytearray, offset, mybytearray.length - offset) != -1) {
offset += read;
}
Или вы можете использовать классы из стандартной библиотеки, например DataInputStream
имеет readFully
метод.
DataInputStream dis = new DataInputStream(fis);
dis.readFully(mybytearray);
Пожалуйста, смотрите документацию read()
по адресу: http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html.
Особенно:
Предпринята попытка прочитать столько же, сколько и байтов, но можно прочитать меньшее число. Количество фактически прочитанных байтов возвращается как целое число.
Это означает, что если возвращенная длина не соответствует ожидаемой и вы еще не встретили конец файла, вам следует снова вызвать read() (в цикле).