2017-02-10 5 views
0

클라이언트에서 서버 tcp로 파일을 업로드 할 때 다음 코드를 사용하지만 파일을 수동으로 열려고하면 파일이 비어있는 이유는 무엇입니까? stackoverflow에서 게시물이 많이 보이지만 아무것도 변경되지 않습니다. (내 나쁜 영어 죄송합니다) 들으
서버 :BufferedOuputStream 만들기 공백 파일

확장 ThreadServer

공용 클래스 스레드 {

private Socket soc; 
private FileOutputStream fos; 
private BufferedOutputStream bos; 
private InputStream in; 

public ThreadServer (Socket soc) { 
    this.soc = soc; 
} 

public void run(){ 
    try { 
     fos = new FileOutputStream("C:/Users/erwan/workspace/Word/server/text.txt"); 
    } catch (FileNotFoundException e1) { 
     e1.printStackTrace(); 
    } 
    bos = new BufferedOutputStream(fos); 
    byte[] buffer = new byte[1024]; 
    try { 
     in = soc.getInputStream(); 
     int count = 0; 
     while((count= in.read(buffer, 0 , buffer.length)) != -1) { 
      System.out.println(count+" octets received...");     
      bos.write(buffer); 
     } 
     bos.flush(); 
     bos.close(); 
     in.close(); 
     soc.close(); 
     System.out.println("File sent succesfully!"); 
    }catch(IOException e){ 
     e.printStackTrace(); 
     System.out.println("Une erreur est survenu"); 
    } 
} 

}

클라이언트 :

public class Client { 
private static Socket as; 
private static FileInputStream fis; 
private static BufferedInputStream bis; 
private static OutputStream out; 
public static void main(String[] args){ 
    as = null; 
    try{ 
     as = new Socket(InetAddress.getLocalHost(),4020); 

     File f = new File (args[0]); 
     byte [] buffer = new byte [(int) f.length()]; 
     fis = new FileInputStream(f); 
     setBis(new BufferedInputStream(fis)); 
     out = as.getOutputStream(); 
     System.out.println("uploading..."); 
     out.write(buffer,0,buffer.length); 
     out.flush(); 
     out.close(); 
     System.out.println("the file is uploaded."); 
     as.close(); 
    }catch(IOException e){ 
     e.printStackTrace(); 
    } 

}

답변

0

클라이언트의 버퍼는 데이터로 채워하지 않는 것. 파일의 길이를 가지는 바이트의 배열로서 초기화됩니다 만, 입력 스트림로 read 메소드 호출은 행해지 지 않습니다. 테스트를 위해 fis.read (버퍼)는 버퍼에 데이터를 빠르게 가져옵니다. 읽기가 버퍼의 전체 길이를 채우는 것은 보장되지 않는다는 것을 명심하십시오. 따라서 특히 파일에 0이 있으면 클라이언트의 버퍼로 실제 데이터를 읽지 못하는 것이 원인 일 가능성이 큽니다.

서버 코드는 read 메소드가 버퍼를 완전히 채우는 것으로 가정하므로 write 메소드 호출은 길이 (개수)를 지정해야합니다. 따라서 bos.write (buffer)를 bos.write (bos, 0, count)로 변경하십시오. 파일의 끝 부분이 이전 청크의 일부 데이터가 반복 될 수 있기 때문에 파일 끝에 (파일의 길이가 1024 바이트 이상인 경우) 분명하게 나타납니다.

+0

나는 왜 fis.read (buffer, 0, buffer.lenght)가 문제를 해결했는지 정말로 이해하지 못한다. 그러나 정말로 당신에게 대답 해 주었다. thx –

+0

예. 정말로 그렇게 복잡한 것은 아닙니다. 새 바이트 [(int) f.length()]를 수행했습니다. 그게 f.length() 바이트를 저장하기위한 메모리 영역을 할당하는 것입니다. 이 메모리 바이트에는 데이터가 저장되지 않습니다. 대부분의 경우 배열은 jvm에 의해 0 바이트 (바이너리 0, 그래서 종종 편집기에서 이상한 문자로 나타납니다)로 초기화됩니다. 실제로 입력 파일의 데이터를 새로 생성 된 배열에 넣으려면 fis.read를 수행해야합니다. –