0

Я отправляю файлы между двумя устройствами, поэтому я установил связь сокетов. Прямо сейчас, я просто пытаюсь отправить один файл, но в будущем я хочу отправить несколько файлов (выбранных пользователем из gridview).Отправка нескольких файлов - конец каждого файла в буфере []

Проблема заключается в том, что при отправке одного файла на стороне сервера (который получает файл) socket.getInputStream(). Read (buffer) не обнаруживает конца файла. Он просто ждет «больше» данных для отправки.

После некоторого поиска этой проблемы я достиг некоторых тем, которые дали мне некоторые варианты, но я все еще не удовлетворен этим, потому что я не знаю, будут ли эти параметры эффективными для отправки нескольких файлов. Это пример: How to identify end of InputStream in java

Я могу закрыть сокет или объекты потока после отправки файла, но если я хочу отправить много файлов, было бы неэффективно всегда закрывать и открывать сокеты.

Код на приемнике:

File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/testeReceiveServerComm.apk"); 
    byte[] buffer = new byte [8192]; 
    FileOutputStream fos=new FileOutputStream(apkReceived); 
    int count=0; 
    int total=0;//so apra ir vendo quanto recebi. 
    while((count = in.read(buffer)) != -1){ 
     fos.write(buffer,0,count); 
     total+=count; 
     System.out.println("Server Comm receive thread - already received this ammount : "+total); 

    } 

код на клиента (отправителя):

File apkToSend=new File(filePath); 
    byte[] buffer = new byte [8192]; 
    BufferedInputStream bis=new BufferedInputStream(new FileInputStream(apkToSend)); 
    int count; 
    int total=0; 
    while((count=bis.read(buffer))!=-1){ 
     out.write(buffer,0,count); 
     total+=count; 
     out.reset(); 
     System.out.println("send thread - already sent this ammount : "+total); 
      } 

      out.flush(); 
      bis.close(); 
+0

Не полагайтесь на конец потока. Это намного проще. Просто отправьте размер файла в первую очередь. Вы можете поместить размер в целочисленную переменную, а затем отправить четыре байта целого числа. Приемник сначала считывает четыре байта и знает размер. Затем он будет читать точно размер байтов из потока. Когда это делается, он снова считывает четыре байта для размера следующего файла. Когда все четыре байта равны нулю, больше нет файлов. – greenapps

+0

проще всего использовать, например, [буферы протокола] (https://developers.google.com/protocol-buffers/), чтобы 1) написать файл «дескриптор» (путь, имя файла, описание, размер файла и т. Д.) И основанный на 'filesize' пишет точное количество байтов, затем переходите к 1), читатель делает то же самое в своем потоке ввода – pskink

+0

Спасибо вам обоим. Подход Greenapps похож на ответ, который написал Riyaz Parasara, поэтому я реализовал нечто подобное. Psink большое спасибо за ваш ответ, обязательно проверит буферы протокола, может быть, это будет более эффективно (я бы читал только 1 раз, чтобы иметь размер и файл?). Еще раз спасибо вам за ваши ответы –

ответ

1

Вы читаете сокет до чтения() возвращает -1. Это условие конца потока (EOS). EOS происходит, когда партнер завершает соединение. Не когда он заканчивает писать один файл.

Необходимо передать размер файла перед каждым файлом. Вы уже делаете подобное с количеством файлов. Затем убедитесь, что вы читали точно, что много байт для этого файла:

И этот пример кода

String filename = dis.readUTF(); 
long fileSize = dis.readLong(); 
FileOutputStream fos = new FileOutputStream(filename); 
while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize)) != -1) 
{ 
    fos.write(buf,0,n); 
    fileSize -= n; 
} 
fos.close(); 

Вы можете заключить все это в цикле, который заканчивается, когда readUTF() бросает EOFException. Наоборот, перед отправкой данных вы должны вызвать writeUTF (имя файла) и writeLong (filesize) у отправителя.

+0

Спасибо за ваш ответ. О цикле я всегда слышал, что я должен поместить его через некоторое время (! ServerSocket.isClosed()) ... но недавно здесь, в stackoverflow, кто-то сказал мне, что это плохо. Думаете, это плохо? Еще раз спасибо ! –

+0

Нет, это не плохо, технически и теоретически правильно мой ответ –

Смежные вопросы