解決DataInputStream?read不等于-1,socket文件傳輸只能傳輸一個文件無法傳輸多個問題
被一個朋友問到一個關(guān)于sokcet文件傳輸?shù)膯栴}
他發(fā)現(xiàn)他寫的代碼只能發(fā)送一次文件,沒辦法發(fā)送第二次,或者說發(fā)送第二次的時候服務(wù)端就接收不到了。
部分代碼
// 開始接收文件 byte[] bytes = new byte[1024]; //byte[] bytes = new byte[dis.available()]; int length = 0; while((length = dis.read(bytes, 0, bytes.length)) != -1) { System.out.println(bytes.length); fos.write(bytes, 0, length); fos.flush(); } System.out.println("======== 文件接收成功 [File Name:" + fileName + "] [Size:" + getFormatFileSize(fileLength) + "] ========");
我給他調(diào)試的時候發(fā)現(xiàn)確確實實發(fā)送第一次文件后就就一直阻塞在while循環(huán)里了,出不來。
本來傳輸完第一次的文件后應(yīng)該有打印“======== 文件接收成功 [File。。。。。。”
這些信息,但是實際上沒有,而且也不報錯。
調(diào)試的時候打斷點也是走著走著斷點就不見了,要說他是阻塞也不像是阻塞,因為如果是阻塞的話起碼斷點是會存在的只是無法往下運行了而已,但是他這個調(diào)試就是直接斷點就消失了,我也懵了。
后來查資料才發(fā)現(xiàn)原來只要客戶端的DataOutputStream不close掉,那么服務(wù)端的DataInputStream read就永遠不等于-1。
即使文件的數(shù)據(jù)已經(jīng)傳完了,DataInputStream依舊會等著客戶端DataOutputStream再傳數(shù)據(jù)過來。
最后只能通過判斷文件的的大小來確認(rèn)文件是否已經(jīng)傳輸完成。
解決代碼代碼
//dis就是DataInputStream String fileName = dis.readUTF();//文件名字 long fileLength = dis.readLong();//文件長度 File directory = new File(savepath); if(!directory.exists()) { directory.mkdir(); } File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName); fos = new FileOutputStream(file); // 開始接收文件 byte[] bytes = new byte[1024]; //byte[] bytes = new byte[dis.available()]; int length = 0; while((length = dis.read(bytes, 0, bytes.length)) != -1) { System.out.println(bytes.length); //fos就是FileOutputStream fos.write(bytes, 0, length); fos.flush(); //*************關(guān)鍵的一步**************// if(fileLength == file.length()) break; //***************************// } System.out.println("======== 文件接收成功 [File Name:" + fileName + "] [Size:" + getFormatFileSize(fileLength) + "] ========");
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實現(xiàn)MapReduce對文件進行切分的示例代碼
本文主要介紹了java實現(xiàn)MapReduce對文件進行切分的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01SpringBoot配置MySQL5.7與MySQL8.0的異同點詳解
MySQL 是 Java 開發(fā)中最常用的數(shù)據(jù)庫之一,而 Spring Boot 提供了便捷的配置方式,隨著 MySQL 8.0 的普及,許多開發(fā)者需要從 MySQL 5.7 升級到 8.0,在實際開發(fā)中,二者的配置方式既有相似之處,也有一些需要特別注意的不同點,所以本文給大家詳細介紹了它們的異同點2024-12-12Spring Boot 自動裝配原理及 Starter 實現(xiàn)原理解析
SpringBoot通過@SpringBootApplication注解簡化了依賴引入和配置,該注解包括@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三部分,感興趣的朋友跟隨小編一起看看吧2024-09-09使用SSM+Layui+Bootstrap實現(xiàn)汽車維保系統(tǒng)的示例代碼
本文主要實現(xiàn)對汽車維修廠的信息化管理功能,。實現(xiàn)的主要功能包含用戶管理、配置管理、汽車管理、故障管理、供應(yīng)商管理、配件管理、維修訂單管理、統(tǒng)計信息、公告管理、個人信息管理,感興趣的可以了解一下2021-12-12