Отправка файлов (большая) с использованием Socket Programming - PullRequest
3 голосов
/ 02 ноября 2011

Мне было интересно, смогу ли я получить какое-нибудь руководство по решению моей проблемы ...

Видите ли, я пытаюсь разобраться в программировании сокетов; Мне удалось создать клиент и сервер; сервер пишет клиенту без проблем; Мне даже удается отправить файлы, используя

byte [] mybytearray  = new byte [(int)myFile.length()];
  FileInputStream fis = new FileInputStream(myFile);

Это на стороне сервера. На стороне клиента

byte [] mybytearray  = new byte [filesize];
InputStream is = sock.getInputStream();
FileOutputStream fileos = new FileOutputStream("Filename.dat");
BufferedOutputStream bufferos = new BufferedOutputStream(fileos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;


do {
   bytesRead =
      is.read(mybytearray, current, (mybytearray.length-current));
   if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);

bufferos.write(mybytearray, 0 , current);
bufferos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bufferos.close();

У меня вопрос: я не могу отправлять большие файлы; Я продолжаю получать "Исключение в потоке" main "java.lang.OutOfMemoryError: пространство кучи Java"

Есть какие-нибудь мысли или указания, как мне управлять отправкой больших файлов клиенту с сервера? Я имею в виду размеры скажем 600 МБ или около того .... есть мысли? Высоко ценится ... спасибо

Ответы [ 4 ]

5 голосов
/ 02 ноября 2011

Что ж, ваша куча в настоящее время пытается удержать 'mybytearray', который является размером файла, который вы пытаетесь получить (предположительно).Вам нужно переместить операцию bos.write () в цикл и сделать «mybytearray» фиксированным размером.Вот пример копирования одного потока в другой, который на самом деле не заботится о размере потоковых данных:

    public static void stream(InputStream in, OutputStream out)
        throws IOException {
    byte[] buf = new byte[1024];
    int bytesRead = 0;

    try {

        while (-1 != (bytesRead = in.read(buf, 0, buf.length))) {
            out.write(buf, 0, bytesRead);
        }

    } catch (IOException e) {
        log.error("Error with streaming op: " + e.getMessage());
        throw (e);
    } finally {
                    try{
           in.close();
           out.flush();
           out.close();
                    } catch (Exception e){}//Ignore
    }
}
4 голосов
/ 02 ноября 2011

Недостаточно памяти, потому что вы выделяете mybytearray для длины filesize. Одним из возможных решений является вызов JVM с большей кучей; например -Xmx1G.

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

3 голосов
/ 02 ноября 2011

Не считывайте файл целиком в ОЗУ, чтобы отправить, но отправьте файл по частям.

byte [] mybytearray  = new byte [(int)myFile.length()];

плохо, если (int)myFile.length() больше, чем умещается в памяти.

Вместо этого используйте

byte [] buffer= new byte[4096];

или около того и создайте цикл, читая из файла и отправляя в сокет.

0 голосов
/ 02 ноября 2011

Это означает, что JVM не хватило памяти .. Так что вам следует увеличить пространство кучи JVM .. Поэтому я думаю, что проблема не в отправке больших файлов ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...