Хорошо, при попытке передать указанный каталог файлов через сокет удалите объекты каталога из arraylist, чтобы остались только файлы, и передайте их 1 к 1 через тот же сокет. Список массивов здесь заполнен ТОЛЬКО файлами, никаких каталогов. Вот код приема и отправки для клиента и сервера соответственно. Код работает нормально, без ошибок, за исключением того, что ВСЕ данные записываются в первый файл. Последующие файлы создаются в папке сервера, но их размер составляет 0 байт. Мы будем очень признательны за любой ввод.
ЭТО СЕРВЕРНЫЙ КОД ДЛЯ ПОЛУЧЕНИЯ ФАЙЛОВ
publicvoidreceive(){
try { DataInputStreamdis=newDataInputStream(newBufferedInputStream(socket.getInputStream())); DataOutputStreamdos=newDataOutputStream(newBufferedOutputStream(socket.getOutputStream())); //read the number of files from the client intnumber= dis.readInt(); ArrayList<File>files = newArrayList<File>(number); System.out.println("Number of Files to be received: " +number); //read file names, add files to arraylist for(inti=0; i< number;i++){ Filefile=newFile(dis.readUTF()); files.add(file); } intn=0; byte[]buf = newbyte[4092];
//outer loop, executes one for each file for(inti=0; i < files.size();i++){
System.out.println("Receiving file: " + files.get(i).getName()); //create a new fileoutputstream for each new file FileOutputStreamfos=newFileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName()); //read file while((n = dis.read(buf)) != -1){ fos.write(buf,0,n); fos.flush(); } fos.close(); }
try { DataInputStreamdis=newDataInputStream(newBufferedInputStream(socket.getInputStream())); DataOutputStreamdos=newDataOutputStream(newBufferedOutputStream(socket.getOutputStream())); System.out.println(files.size()); //write the number of files to the server dos.writeInt(files.size()); dos.flush();
//buffer for file writing, to declare inside or outside loop? intn=0; byte[]buf = newbyte[4092]; //outer loop, executes one for each file for(inti=0; i < files.size(); i++){
System.out.println(files.get(i).getName()); //create new fileinputstream for each file FileInputStreamfis=newFileInputStream(files.get(i));
//write file to dos while((n =fis.read(buf)) != -1){ dos.write(buf,0,n); dos.flush();
} //should i close the dataoutputstream here and make a new one each time? } //or is this good? dos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
}
Переведено автоматически
Ответ 1
Вы считываете сокет до тех пор, пока read() не вернет значение -1. Это условие завершения потока (EOS). EOS происходит, когда одноранговый узел закрывает соединение. Не тогда, когда он завершает запись одного файла.
Вам нужно отправлять размер файла перед каждым файлом. Вы уже делаете аналогичную вещь с количеством файлов. Затем убедитесь, что вы прочитали именно столько байт для этого файла:
Вы можете заключить все это в цикл, который завершается при readUTF() запуске EOFException. И наоборот, конечно, вы должны позвонить writeUTF(filename) и writeLong(filesize) отправителю перед отправкой данных.
Ответ 2
Я сделал это следующим образом, это работает отлично, вы можете взглянуть:
Отправить
byte[] done = newbyte[3]; Stringstr="done"; //randomly anything done = str.getBytes(); for (inti=0; i < files.size(); i++) { System.out.println(files.get(i).getName()); FileInputStreamfis=newFileInputStream(files.get(i)); while ((n = fis.read(buf)) != -1) { dos.write(buf, 0, n); System.out.println(n); dos.flush(); } //should i close the dataoutputstream here and make a new one each time? dos.write(done, 0, 3); dos.flush(); } //or is this good? dos.close();
Получить
for (inti=0; i < files.size(); i++) { System.out.println("Receiving file: " + files.get(i).getName()); //create a new fileoutputstream for each new file fos = newFileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" + files.get(i).getName()); //read file while ((n = dis.read(buf)) != -1 && n != 3) { fos.write(buf, 0, n); fos.flush(); } fos.close(); }
Ответ 3
Я создал сервер и клиент. Они устанавливают соединение, и после этого сервер отправляет текстовый файл размером 1 МБ каждую секунду. Код сервера и клиента приведен ниже. Я провел длительное тестирование и увидел, что данные не потеряны. Я немного изменил приведенный выше ответ.