文件上傳案例
文件上傳分析圖解
- 【客戶端】輸入流,從硬盤讀取文件數(shù)據(jù)到程序中刊棕。
- 【客戶端】輸出流,寫出文件數(shù)據(jù)到服務(wù)端待逞。
- 【服務(wù)端】輸入流甥角,讀取文件數(shù)據(jù)到服務(wù)端程序。
- 【服務(wù)端】輸出流识樱,寫出文件數(shù)據(jù)到服務(wù)器硬盤中嗤无。
客戶端
/*
文件上傳案例的客戶端:讀取本地文件,上傳到服務(wù)器,讀取服務(wù)器回寫的數(shù)據(jù)
明確:
數(shù)據(jù)源:c:\\1.jpg
目的地:服務(wù)器
實(shí)現(xiàn)步驟:
1.創(chuàng)建一個(gè)本地字節(jié)輸入流FileInputStream對(duì)象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
2.創(chuàng)建一個(gè)客戶端Socket對(duì)象,構(gòu)造方法中綁定服務(wù)器的IP地址和端口號(hào)
3.使用Socket中的方法getOutputStream,獲取網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
4.使用本地字節(jié)輸入流FileInputStream對(duì)象中的方法read,讀取本地文件
5.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,把讀取到的文件上傳到服務(wù)器
6.使用Socket中的方法getInputStream,獲取網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
7.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read讀取服務(wù)回寫的數(shù)據(jù)
8.釋放資源(FileInputStream,Socket)
*/
public class TCPClient {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建一個(gè)本地字節(jié)輸入流FileInputStream對(duì)象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
FileInputStream fis = new FileInputStream("c:\\1.jpg");
//2.創(chuàng)建一個(gè)客戶端Socket對(duì)象,構(gòu)造方法中綁定服務(wù)器的IP地址和端口號(hào)
Socket socket = new Socket("127.0.0.1",8888);
//3.使用Socket中的方法getOutputStream,獲取網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
OutputStream os = socket.getOutputStream();
//4.使用本地字節(jié)輸入流FileInputStream對(duì)象中的方法read,讀取本地文件
int len = 0;
byte[] bytes = new byte[1024];
while((len = fis.read(bytes))!=-1){
//5.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,把讀取到的文件上傳到服務(wù)器
os.write(bytes,0,len);
}
/*
解決:上傳完文件,給服務(wù)器寫一個(gè)結(jié)束標(biāo)記
void shutdownOutput() 禁用此套接字的輸出流震束。
對(duì)于 TCP 套接字,任何以前寫入的數(shù)據(jù)都將被發(fā)送当犯,并且后跟 TCP 的正常連接終止序列垢村。
*/
socket.shutdownOutput();
//6.使用Socket中的方法getInputStream,獲取網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
InputStream is = socket.getInputStream();
System.out.println("333333333333333333333");
//7.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read讀取服務(wù)回寫的數(shù)據(jù)
while((len = is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
System.out.println("444444444444444444 while死循環(huán)打印不到");
//8.釋放資源(FileInputStream,Socket)
fis.close();
socket.close();
}
}
服務(wù)器端
/*
文件上傳案例服務(wù)器端:讀取客戶端上傳的文件,保存到服務(wù)器的硬盤,給客戶端回寫"上傳成功"
明確:
數(shù)據(jù)源:客戶端上傳的文件
目的地:服務(wù)器的硬盤 d:\\upload\\1.jpg
實(shí)現(xiàn)步驟:
1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
10.釋放資源(FileOutputStream,Socket,ServerSocket)
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
ServerSocket server = new ServerSocket(8888);
//2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
Socket socket = server.accept();
//3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
InputStream is = socket.getInputStream();
//4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
File file = new File("d:\\upload");
if(!file.exists()){
file.mkdirs();
}
//5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");
//6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
System.out.println("11111111111111111111");
int len =0;
byte[] bytes = new byte[1024];
while((len = is.read(bytes))!=-1){
//7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
fos.write(bytes,0,len);
}
System.out.println("22222222222222222222222 while死循環(huán)打印不到");
//8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
//9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
socket.getOutputStream().write("上傳成功".getBytes());
//10.釋放資源(FileOutputStream,Socket,ServerSocket)
fos.close();
socket.close();
server.close();
}
}
寫完之后兩個(gè)都沒(méi)有stop,原因分析及解決辦法:
結(jié)束完以后嚎卫,給服務(wù)器寫一個(gè)結(jié)束標(biāo)記就可以了-------代碼寫入上述代碼中
服務(wù)器端代碼優(yōu)化以后的:
/*
文件上傳案例服務(wù)器端:讀取客戶端上傳的文件,保存到服務(wù)器的硬盤,給客戶端回寫"上傳成功"
明確:
數(shù)據(jù)源:客戶端上傳的文件
目的地:服務(wù)器的硬盤 d:\\upload\\1.jpg
實(shí)現(xiàn)步驟:
1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
10.釋放資源(FileOutputStream,Socket,ServerSocket)
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
ServerSocket server = new ServerSocket(8888);
//2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
/*
讓服務(wù)器一直處于監(jiān)聽(tīng)狀態(tài)(死循環(huán)accept方法)
有一個(gè)客戶端上傳文件嘉栓,就保存一個(gè)文件
*/
while(true){
Socket socket = server.accept();
/*使用多線程技術(shù),提高程序的效率
有一個(gè)客戶端上傳文件拓诸,就開(kāi)啟一個(gè)線程侵佃,完成文件的上傳
*/
new Thread(new Runnable() {
//完成文件的上傳
@Override
public void run() {
try {
//3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
InputStream is = socket.getInputStream();
//4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
File file = new File("d:\\upload");
if(!file.exists()){
file.mkdirs();
}
/*自定義一個(gè)文件的命名規(guī)則。防止同名的文件被覆蓋
規(guī)則:域名+毫秒值+隨機(jī)數(shù)
*/
String fileName = "itcast"+System.currentTimeMillis()+new Random().nextInt(99999)+".jpg"
//5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
FileOutputStream fos = new FileOutputStream(file+"\\"+fileName);
//6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
int len =0;
byte[] bytes = new byte[1024];
while((len = is.read(bytes))!=-1){
//7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
fos.write(bytes,0,len);
}
//8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
//9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
socket.getOutputStream().write("上傳成功".getBytes());
//10.釋放資源(FileOutputStream,Socket,ServerSocket)
fos.close();
socket.close();
}catch (IOException e){
System.out.println(e);
}
}
}).start();
//server.close();
}
}