Клиент-сервер не отправляет весь файл

Когда я запускаю свой клиентский сервер - который подключается и пытаюсь отправить файл, он не отправляет весь файл, который вызывает ошибки, где-то еще, он проходит примерно на полпути и постоянно останавливается на одной и той же части. Эта настройка работает при запуске сервера-клиента на той же машине, поэтому я полностью запутался

Сервер --->

    // 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() (в цикле).

Другие вопросы по тегам