Java TCP文件上傳案例

文件上傳分析

  1. 【客戶端】輸入流,從硬盤讀取文件數據到程序中。
  2. 【客戶端】輸出流,寫出文件數據到服務端。
  3. 【服務端】輸入流,讀取文件數據到服務端程序。
  4. 【服務端】輸出流,寫出文件數據到服務器硬盤中。

基本實現

服務端實現

public class FileUpload_Server {public static void main(String[] args) throws IOException {System.out.println("服務器 啟動..... ");// 1. 創建服務端ServerSocketServerSocket serverSocket = new ServerSocket(6666);// 2. 建立連接 Socket accept = serverSocket.accept();// 3. 創建流對象// 3.1 獲取輸入流,讀取文件數據BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());// 3.2 創建輸出流,保存到本地 .BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg"));// 4. 讀寫數據byte[] b = new byte[1024 * 8];int len;while ((len = bis.read(b)) != -1) {bos.write(b, 0, len);}//5. 關閉 資源bos.close();bis.close();accept.close();System.out.println("文件上傳已保存");}
}

客戶端實現

public class FileUPload_Client {public static void main(String[] args) throws IOException {// 1.創建流對象// 1.1 創建輸入流,讀取本地文件  BufferedInputStream bis  = new BufferedInputStream(new FileInputStream("test.jpg"));// 1.2 創建輸出流,寫到服務端 Socket socket = new Socket("localhost", 6666);BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());//2.寫出數據. byte[] b  = new byte[1024 * 8];int len ; while ((len = bis.read(b)) != -1) {bos.write(b, 0, len);bos.flush();}System.out.println("文件發送完畢");// 3.釋放資源bos.close(); socket.close();bis.close(); System.out.println("文件上傳完畢 ");}
}

文件上傳優化

文件名稱寫死的問題

服務端保存文件的名稱如果寫死,最終導致服務器硬盤遇到相同文件名的文件時只會保留一個文件,建議使用系統時間優化,保證文件名稱唯一,代碼如下:

FileOutputStream fis = new FileOutputStream(System.currentTimeMillis()+".jpg") // 文件名稱
BufferedOutputStream bos = new BufferedOutputStream(fis);
// 自定義命名例如:域名+毫秒值+隨機數+文件后綴

循環接收的問題

服務端只保存一個文件就關閉了,之后用戶無法再上傳,這是不符合實際的,使用循環改進,可以不斷的接收不同用戶的文件,代碼如下:

// 每次接收新的連接,創建一個Socket
whiletrue{Socket accept = serverSocket.accept();// ......
}

效率問題

服務端在接收大文件時,可能耗費幾秒鐘的時間,此時不能接收其他用戶上傳,可以使用多線程技術優化,代碼如下:

while(true) {Socket accept = serverSocket.accept();// accept 交給子線程處理.new Thread(() -> {// ......InputStream bis = accept.getInputStream();// ......}).start();
}

最終實現

public class FileUpload_Server {public static void main(String[] args) throws IOException {System.out.println("服務器 啟動..... ");// 1. 創建服務端ServerSocketServerSocket serverSocket = new ServerSocket(6666);// 2. 循環接收,建立連接while (true) {Socket accept = serverSocket.accept();/* 3. socket對象交給子線程處理,進行讀寫操作Runnable接口中,只有一個run方法,使用lambda表達式簡化格式*/new Thread(() -> {try (//3.1 獲取輸入流對象BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());//3.2 創建輸出流對象, 保存到本地 .FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() + ".jpg");BufferedOutputStream bos = new BufferedOutputStream(fis);) {// 3.3 讀寫數據byte[] b = new byte[1024 * 8];int len;while ((len = bis.read(b)) != -1) {bos.write(b, 0, len);}//4. 關閉 資源bos.close();bis.close();accept.close();System.out.println("文件上傳已保存");} catch (IOException e) {e.printStackTrace();}}).start();}}
}

信息回寫

前四步與基本文件上傳一致

  1. 【服務端】獲取輸出流,回寫數據。
  2. 【客戶端】獲取輸入流,解析回寫數據。

服務端實現

public class FileUpload_Server {public static void main(String[] args) throws IOException {System.out.println("服務器 啟動..... ");// 1. 創建服務端ServerSocketServerSocket serverSocket = new ServerSocket(6666);// 2. 循環接收,建立連接while (true) {Socket accept = serverSocket.accept();/*3. socket對象交給子線程處理,進行讀寫操作Runnable接口中,只有一個run方法,使用lambda表達式簡化格式*/new Thread(() -> {try (//3.1 獲取輸入流對象BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());//3.2 創建輸出流對象, 保存到本地 .FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() + ".jpg");BufferedOutputStream bos = new BufferedOutputStream(fis);) {// 3.3 讀寫數據byte[] b = new byte[1024 * 8];int len;while ((len = bis.read(b)) != -1) {bos.write(b, 0, len);}// 4.=======信息回寫===========================System.out.println("back ........");OutputStream out = accept.getOutputStream();out.write("上傳成功".getBytes());out.close();//================================//5. 關閉 資源bos.close();bis.close();accept.close();System.out.println("文件上傳已保存");} catch (IOException e) {e.printStackTrace();}}).start();}}
}

客戶端實現

public class FileUpload_Client {public static void main(String[] args) throws IOException {// 1.創建流對象// 1.1 創建輸入流,讀取本地文件BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"));// 1.2 創建輸出流,寫到服務端Socket socket = new Socket("localhost", 6666);BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());//2.寫出數據.byte[] b  = new byte[1024 * 8 ];int len ;while (( len  = bis.read(b))!=-1) {bos.write(b, 0, len);}// 關閉輸出流,通知服務端,寫出數據完畢socket.shutdownOutput();System.out.println("文件發送完畢");// 3. =====解析回寫============InputStream in = socket.getInputStream();byte[] back = new byte[20];in.read(back);System.out.println(new String(back));in.close();// ============================// 4.釋放資源socket.close();bis.close();}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/710956.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/710956.shtml
英文地址,請注明出處:http://en.pswp.cn/news/710956.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【二分查找】樸素二分查找

二分查找 題目描述 給定一個 n 個元素有序的(升序)整型數組 nums 和一個目標值 target ,寫一個函數搜索 nums 中的 target,如果目標值存在返回下標,否則返回 -1。 示例 1: 輸入: nums [-1,0,3,5,9,12], target 9…

網絡編程:基于TCP和UDP的服務器、客戶端

1.基于TCP通信服務器 程序代碼&#xff1a; 1 #include<myhead.h>2 #define SER_IP "192.168.126.121"//服務器IP3 #define SER_PORT 8888//服務器端口號4 int main(int argc, const char *argv[])5 {6 //1.創建用于監聽的套接字7 int sfd-1;8 sf…

MYSQL C++鏈接接口編程

使用MYSQL 提供的C接口來訪問數據庫,官網比較零碎,又不想全部精讀一下,百度CSDN都是亂七八糟的,大部分不可用 官網教程地址 https://dev.mysql.com/doc/connector-cpp/1.1/en/connector-cpp-examples-connecting.html 網上之所以亂七八糟,主要是MYSQL提供了3個接口兩個包,使用…

C++ //練習 10.9 實現你自己的elimDups。測試你的程序,分別在讀取輸入后、調用unique后以及調用erase后打印vector的內容。

C Primer&#xff08;第5版&#xff09; 練習 10.9 練習 10.9 實現你自己的elimDups。測試你的程序&#xff0c;分別在讀取輸入后、調用unique后以及調用erase后打印vector的內容。 環境&#xff1a;Linux Ubuntu&#xff08;云服務器&#xff09; 工具&#xff1a;vim 代碼…

Flask g對象和插件

四、Flask進階 1. Flask插件 I. flask-caching 安裝 pip install flask-caching初始化 from flask_cache import Cache cache Cache(config(CACHE_TYPE:"simple" )) cache.init_app(appapp)使用 在視圖函數上添加緩存 blue.route("/") cache.cached(tim…

django5生產級部署和并發測試(開發者服務器和uvicorn服務器)

目錄 1. 創建django項目2. 安裝壓力測試工具3. 安裝生產級服務器uvicorn4. 多進程部署 1. 創建django項目 在桌面創建一個名為django_test的項目&#xff1a; django-admin startproject django_test然后使用cd命令進入django_test文件夾內&#xff0c;使用開發者服務器運行項…

前端架構: 腳手架包管理工具之lerna的全流程開發教程

Lerna 1 &#xff09;文檔 Lerna 文檔 https://www.npmjs.com/package/lernahttps://lerna.js.org [請直達這個鏈接] 使用 Lerna 幫助我們做包管理&#xff0c;并不復雜&#xff0c;中間常用的命令并不是很多這里是命令直達&#xff1a;https://lerna.js.org/docs/api-referen…

掌匯云 | FBIF個性化票務系統,展會活動數據好沉淀

“把票全賣光&#xff01;賣到一票難求&#xff0c;現場座無虛席。” 賣票人和買票人可能永遠不在一個頻道上。 2022年辦活動&#xff0c;就是一個字&#xff0c;搏&#xff01;和“黑天鵝”趕時間&#xff0c;能不能辦不由主辦方說了算。這種情況在2023年得到了改善&#xff…

【字典樹】【KMP】【C++算法】3045統計前后綴下標對 II

作者推薦 動態規劃的時間復雜度優化 本文涉及知識點 字符串 字典樹 KMP 前后綴 LeetCode:3045統計前后綴下標對 II 給你一個下標從 0 開始的字符串數組 words 。 定義一個 布爾 函數 isPrefixAndSuffix &#xff0c;它接受兩個字符串參數 str1 和 str2 &#xff1a; 當 st…

C++——內存管理(new和delete)詳解

目錄 C/C內存管理 案例&#xff1a;變量在內存中到底會在哪&#xff1f; New和delete Operator new和operator delete函數 New和delete的原理 對內置類型 對自定義類型 定位new New/delete和malloc/free的區別 C/C內存管理 C/C內存管理分布圖&#xff1a;&#xff08;從…

項目案例:圖像分類技術在直播電商中的應用與實踐

一、引言 在數字化浪潮的推動下&#xff0c;電商行業迎來了一場革命性的變革。直播電商&#xff0c;作為一種新興的購物模式&#xff0c;正以其獨特的互動性和娛樂性&#xff0c;重塑著消費者的購物習慣。通過實時的直播展示&#xff0c;商品的細節得以清晰呈現&#xff0c;而互…

matlab:涉及復雜函數圖像的交點求解

matlab&#xff1a;涉及復雜函數圖像的交點求解 在MATLAB中求解兩個圖像的交點是一個常見的需求。本文將通過一個示例&#xff0c;展示如何求解兩個圖像的交點&#xff0c;并提供相應的MATLAB代碼。 畫出圖像 首先&#xff0c;我們需要繪制兩個圖像&#xff0c;以便直觀地看…

【JavaEE】_HttpServletResponse類

目錄 1. 核心方法 2. 關于setStatus(400)與sendError 2.1 setStatus(400) 2.2 sendError 3. setHeader方法 4. 構造重定向響應 4.1 使用setHeader和setStatus實現重定向 4.2 使用sendRedirect實現重定向 本專欄已有文章介紹HttpServlet和HttpServletRequest類&#…

仿真科普|CAE技術賦能無人機 低空經濟蓄勢起飛

喝一杯無人機送來的現磨熱咖啡&#xff1b;在擁堵的早高峰打個“空中的士”上班&#xff1b;乘坐水陸兩棲飛機來一場“陸海空”立體式觀光……曾經只出現在科幻片里的5D城市魔幻場景&#xff0c;正逐漸走進現實。而推動上述場景實現的&#xff0c;就是近年來越來越熱的“低空經…

前端開發——ElementUI組件的使用

文章目錄 1. Tabs標簽頁2. 單選框 el-radio3. 復選框 el-checkbox4. 下拉框 el-select5. 表格 el-table6. 對話框 el-dialog7. 文字提示 el-tooltip8. 抽屜 el-drawer 1. Tabs標簽頁 <template><el-tabs v-model"activeName" tab-click"handleClick&q…

python學生成績管理系統(期末課程作業)

功能介紹 平臺采用B/S結構&#xff0c;后端采用主流的Python語言進行開發&#xff0c;前端采用主流的Vue.js進行開發。本學期的期末作業。開發了1周 功能包括&#xff1a;成績管理、學生管理、課程管理、班級管理、用戶管理、日志管理、系統信息模塊。 源碼地址 https://gi…

c語言求簡單交錯序列前N項和

本題要求編寫程序,計算序列 1 - 1/4 1/7 - 1/10 ... 的前N項之和。 輸入格式: 輸入在一行中給出一個正整數N。 輸出格式: 在一行中按照“sum S”的格式輸出部分和的值S&#xff0c;精確到小數點后三位。題目保證計算結果不超過雙精度范圍。 輸入樣例: 10輸出樣例: su…

如何實現WordPress后臺顯示文章、分類目錄、標簽等的ID?

我們平時在使用WordPress的過程中&#xff0c;偶爾需要用到文章的ID&#xff0c;或分類目錄ID&#xff0c;或標簽ID&#xff0c;或媒體庫ID&#xff0c;或評論ID&#xff0c;或用戶ID等&#xff0c;但是WordPress后臺默認是不顯示它們的ID的。 今天boke112百科就跟大家分享如何…

聚觀早報 | 愛奇藝2023年Q4財報;蘋果將加大AI投入

聚觀早報每日整理最值得關注的行業重點事件&#xff0c;幫助大家及時了解最新行業動態&#xff0c;每日讀報&#xff0c;就讀聚觀365資訊簡報。 整理丨Cutie 3月1日消息 愛奇藝2023年Q4財報 蘋果將加大AI投入 意大利正與多家車企談判 多家企業與百度達成合作 比亞迪宋PL…

Cesium 視頻貼圖

一、創作靈感 a、在cesium中視頻或者圖像在矩形或者圓形中顯示 b、在不使用entity模式下,使用Primitive進行視頻或者圖像渲染 c、在使用Primitive的前提下,需要進行視頻或者圖像貼地 d、不貼地,請跳轉到我的另外一份日志紋理貼圖 二、創建步驟 1、創建圓形或者矩形 創建圓…