потеря данных при передаче файла - JAVA? - PullRequest
3 голосов
/ 15 января 2012

У меня есть FileServer и FileClient, сервер отправляет файл, когда клиент подключается.Это простая программа, просто чтобы понять концепцию, лежащую в основе.

Я могу отправить файл с сервера на клиент с буфером 1024. Проблема в том, что полученный файл всегда примерно на 0,01 МБ меньшечем исходный файл. Эти mp3-файлы теряют некоторую информацию, а видеофайлы просто не воспроизводятся.

Я поместил некоторые операторы prinln в циклы while как на сервере, так и на клиенте.я обнаружил, что мой сервер не отправляет весь файл.

  //Server
  byte [] mybytearray  = new byte [1024];    
  FileInputStream fis = new FileInputStream(myFile);
  BufferedInputStream bis = new BufferedInputStream(fis);
  bis.read(mybytearray,0,mybytearray.length);
  OutputStream os = sock.getOutputStream();
  System.out.println("Sending...\n mybytearray length:"+mybytearray.length+"file   length:"+(int)myFile.length());
  int read, readTotal=0;
  while ((read = fis.read(mybytearray,0,mybytearray.length)) != -1) { 

      os.write(mybytearray, 0, read);
      System.out.println("File REad:"+read+"readtotal:"+readTotal); //*
      readTotal += read;
}
  System.out.println("Final File Read:"+read+" Final readtotal:"+readTotal);
  os.flush();
  sock.close();
  } 

Выходные данные оператора Println:

Sending...
mybytearray length:1024file length:12767554
File REad:1024readtotal:0
File REad:1024readtotal:1024
.............and a lot of it...and then
File REad:1024readtotal:12756992
File REad:1024readtotal:12758016
File REad:322readtotal:12759040
Final File Read:-1 Final readtotal:12759362

Длина файла: 12767554 & Last readTotal: 12759362 shud будет равным.я не понимаю, почему последнее значение чтения ниже [322], хотя оно может иметь 1024.

Любая помощь будет оценена по достоинству.Спасибо.

[РЕДАКТИРОВАТЬ]

//Client
int read;
int totalRead = 0;

while ((read = is.read(mybytearray,0,mybytearray.length)) != -1) {
        bos.write(mybytearray, 0 , read);

        totalRead += read;
        System.out.println("\nread:"+read+"\ntotalread: "+totalRead);
}
System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead);
bos.write(mybytearray, 0 , read);  //57 Line in FileClient.java
bos.flush();

Я снова попытался отправить файл.Текст на этот раз.это вывод моего сервера

Sending...
mybytearray length:1024file length:1232
File REad:1024readtotal:0
File REad:208readtotal:1024
Final File Read:-1 Final readtotal:1232

и этот на клиенте

read:208
totalread: 1232
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
   Final File Read:-1     Final readtotal:1232

at java.lang.System.arraycopy(Native Method)
at java.io.BufferedOutputStream.write(Unknown Source)
at FileClient.main(FileClient.java:57)

readtotal значения одинаковы, но иногда я получаю эту ошибку, иногда нет.

[БОЛЬШОЕ РЕДАКТИРОВАНИЕ - ПОЛНЫЙ КОД КЛИЕНТА]

public class FileClient{
 public static void main (String [] args ) throws IOException {

long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
final JFrame f = new JFrame("Sample");
f.getContentPane().setLayout(new FlowLayout());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(590,490);
f.setVisible(true);
// localhost for testing
Socket sock = new Socket("localhost",13267);
System.out.println("Connecting...");
File f1=new File(RecieveObject(sock));


// receive file
byte [] mybytearray  = new byte [1024];
InputStream is = sock.getInputStream();


FileOutputStream fos = new FileOutputStream(f1);
ProgressMonitorInputStream nn= new ProgressMonitorInputStream(f,"reading",is);
BufferedOutputStream bos = new BufferedOutputStream(fos);
 /*   bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;


do {
   bytesRead =
      is.read(mybytearray, current, (mybytearray.length-current));
   System.out.println("mybytesarray length: "+mybytearray.length+"\ncurrent:"+current+"\nbytesread: "+bytesRead);
   if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);

bos.write(mybytearray, 0 , current);
bos.flush();
 */
int read;
int totalRead = 0;
//InputStream clientInputStream = clientSocket.getInputStream();
while ((read = is.read(mybytearray,0,mybytearray.length)) != -1) {
        bos.write(mybytearray, 0 , read);

        totalRead += read;
        System.out.println("\nread:"+read+"\ntotalread: "+totalRead);
}
System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead);
 //   bos.write(mybytearray, 0 , read);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
sock.close();

}
public static  String RecieveObject(Socket s) {
    String str = null;
    try{
    ObjectInputStream is = new ObjectInputStream(s.getInputStream());



            str =(String)is.readUTF();


    }
    catch(IOException ex){}
    return str;
}   

}

Ответы [ 2 ]

6 голосов
/ 15 января 2012

Вам не хватает начала файла (до первых 1024 байт) из-за вашей 5-й строки (включая комментарий). Вы читаете из ввода и продвигаете его, не отправляя его клиенту. Удалить это:

bis.read(mybytearray,0,mybytearray.length);

Кроме того, вы не используете BufferedInputStream в цикле. Либо используйте bis.read здесь вместо fis.read (если вы все еще хотите буферизованные чтения) - либо удалите BufferedInputStream все вместе.

Другая ваша проблема в том, что вы читаете последние байты на клиенте, затем снова входите в цикл. is.read снова вызывается. Вместо возврата -1 он выдает IOException, поскольку другая сторона сокета закрыта. Таким образом, bos.flush () и bos.close () не вызываются, и ваши последние байты никогда не записываются на диск. Чтобы помочь с этим, попробуйте позвонить sock.shutdownOutput перед его закрытием. Независимо от этого, вы захотите добавить некоторую правильную обработку исключений вокруг этого.

1 голос
/ 15 января 2012
byte [] mybytearray  = new byte [1024];    
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...\n mybytearray length:"+mybytearray.length+"filelength:"+(int)myFile.length());
int read, readTotal=0;
while ((read = bis.read(mybytearray,0,mybytearray.length)) != -1) { 
    os.write(mybytearray, 0, read);
    System.out.println("File REad:"+read+"readtotal:"+readTotal); //*
    readTotal += read;
}
System.out.println("Final File Read:"+read+" Final readtotal:"+readTotal);
os.flush();
sock.close();
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...