2013-03-27 30 views
0

我有以下代碼通過套接字傳輸文件。我如何發送文件名?如何使用Java中的套接字發送帶有文件的文件名?

Socket socket = new Socket("localhost", port);//machine name, port number 
File file = new File(fileName); 
// Get the size of the file 
long length = file.length(); 
if (length > Integer.MAX_VALUE) 
{ 
    System.out.println("File is too large."); 
} 
byte[] bytes = new byte[(int) length]; 
FileInputStream fis = new FileInputStream(file); 
BufferedInputStream bis = new BufferedInputStream(fis); 
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 

int count; 

while ((count = bis.read(bytes)) > 0) 
{ 
    out.write(bytes, 0, count); 
} 

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

如何與發送文件的文件名?如果我正確使用'File.getName()' – Geros 2013-03-27 00:34:59

+3

我認爲OP正在尋找一個協議定義,以便接收端可以知道在哪裏存儲文件。這需要記錄結束標記等 - 爲什麼不使用像FTP這樣的完善協議? – 2013-03-27 00:37:20

+1

@RonDahlgren由於FTP對於這個目的來說有點太可怕了,而且我不確定Java的支持有什麼用處?對於從發送者A到文件系統形式的接收者B的簡單文件上傳,HTTP會更好。 – millimoose 2013-03-27 00:44:51

回答

2

使用一個字符,不能在一個文件名 - 如空(0x00\0,無論你怎麼稱呼它)。然後發送一個64位整數,指出文件的長度(以字節爲單位)(確保不會遇到緩衝區溢出,小端/大端問題等等,只測試所有邊緣情況)。然後發送文件數據。然後,結束套接字將知道哪個部分是文件名,文件長度和文件數據,並且如果要發送另一個文件名,甚至可以爲下一個文件名準備好。

(如果文件名可以是任意字符,包括控制字符,哎喲!也許發送一個64位整數長度的文件名,文件名,一個64位整數長度的文件數據,文件數據,重複無限? )

編輯:要通過套接字發送64位整數,請按特定順序發送其組成字節,並確保發送方和接收方在訂單上達成一致。如何做到這一點的一個例子是How to convert a Java Long to byte[] for Cassandra?

+0

只需確保在字節級別指定將如何發送一個64位整數。 – 2013-03-27 00:46:26

+0

你能舉個例子嗎?謝謝 – sap 2013-03-27 01:22:44

+0

@sap我從來沒有做過Java套接字編程,對不起:( – Patashu 2013-03-27 01:30:20

5

您可以發明自己的協議爲您的套接字。如果你需要的是一個文件名和數據,DataOutputStream.writeUTF是最容易:

BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 
try (DataOutputStream d = new DataOutputStream(out)) { 
    d.writeUTF(fileName); 
    Files.copy(file.toPath(), d); 
} 

對端必須使用相同的協議,當然是:

BufferedInputStream in = new BufferedInputStream(socket.getInputStream()); 
try (DataInputStream d = new DataInputStream(in)) { 
    String fileName = d.readUTF(); 
    Files.copy(d, Paths.get(fileName)); 
} 
1

我想換一個緩衝其原因MalfuctionUTF並把它試穿與資源關閉強調流套接字,並導致連接復位異常
下面的代碼爲我工作

客戶

DataOutputStream d = new DataOutputStream(out); 
     d.writeUTF(filename); 
     d.writeLong(length); 

服務器

DataInputStream d = new DataInputStream(in); 
filename = d.readUTF(); 
fileLength = d.readLong();