在做tcp傳輸文件實驗時,我一直很糾結一個問題,就是Socket客戶端發送一個文件SocketServer服務端時,SocketServer只能從socket.getInputStream()中得到一個文件流,怎么才能知道這個文件流具體是什么東西,什么文件,大小多少K等信息呢?思來想去今天有了答案,就是在客戶端發送文件時,把文件信息和文件合並后在寫入socket輸出流。
看上面圖,因為SequenceInputStream的參數接收的是InputStream,那怎么把字符串文件信息變成一個讀取流呢?假設我的文件信息就是文件名
byte[] info = new byte[512]; 我們規定合並流的前512字節用來保存文件新,這樣在服務端就可以先讀取前512字節的數據,
byte[] b = filenName.getBytes(); 把文件信息轉成字節數組
for(int i=0; i<b.length; i++){ 循環把文件信息的字節填充到預先定義好的用於保存文件信息的字節數組
info[i] = b[i];
}
ByteArrayInputStream bais = new ByteArrayInputStream(info); 用這個流對象對info字節數組進行讀取
SequenceInputStream sis = new SequenceInputStream(bais,文件讀取流); 合並讀取流
這樣合並流就完成了,接着把這個合並流寫入socket輸出流就行了。
完整的代碼:
FileCilent客戶端
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.SequenceInputStream;
import java.net.Socket;
public class FileClient {
/**
* @param args
*/
public static void main(String[] args) {
try {
Socket s = new Socket("192.168.1.100",8800);
File file = new File("h:/DPP3.9_60D(1).rar");
FileInputStream fs = new FileInputStream(file);
//定義一個256字節的區域來保存文件信息。
byte[] b = file.getName().getBytes();
byte[] info = Arrays.CopyOf(b,256); ByteArrayInputStream bais = new ByteArrayInputStream(info);
//合並流
SequenceInputStream sis = new SequenceInputStream(bais,fs);
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
byte[] buf = new byte[1024];
int len = 0;
while((len = sis.read(buf))!=-1){
bos.write(buf,0,len);
}
bos.close();
sis.close();
fs.close();
bais.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
FileServer服務端
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FileServer {
/**
* @param args
*/
public static void main(String[] args) {
ExecutorService threadpool = Executors.newFixedThreadPool(10);
try {
ServerSocket ss = new ServerSocket(8800);
while (true) {
threadpool.execute(new UploadThread(ss.accept()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class UploadThread implements Runnable {
private Socket s;
UploadThread(Socket s) {
this.s = s;
}
@Override
public void run() {
System.out.println(s.getInetAddress().getHostAddress());
try {
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
byte[] info = new byte[256];
bis.read(info);
String file_name = new String(info).trim();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("f:/"+file_name));
byte[] buf = new byte[1024];
int len = 0;
while ((len = bis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
bos.close();
bis.close();
s.close();
System.out.println(file_name+" 文件傳輸成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}

