日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

远程传输文件--java文件流

發布時間:2023/12/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 远程传输文件--java文件流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

花了幾天時間,搞了一下遠程文件傳輸的事兒:都是用url傳流的方式進行傳輸

一、發送文件有兩種方式,都是用表單的方式進行post請求,既可以傳輸文件,也可以傳輸鍵值對。

? ? ? ? 第一種:原始的直接用stringbuffer拼接需要傳的數據

public String upLoadFilePost(String actionUrl, Map<String, List<File>> files, Map<String, String> textMap) throws IOException {String BOUNDARY = "WebKitFormBoundary"+java.util.UUID.randomUUID().toString();String PREFIX = "--", LINEND = "\r\n";String MULTIPART_FROM_DATA = "multipart/form-data";String CHARSET = "UTF-8";URL uri = new URL(actionUrl);HttpURLConnection conn = (HttpURLConnection) uri.openConnection();conn.setReadTimeout(5 * 1000);conn.setDoInput(true);// 允許輸入conn.setDoOutput(true);// 允許輸出conn.setUseCaches(false);conn.setRequestMethod("POST"); // Post方式conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Charsert", "UTF-8");conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA+ ";boundary=" + BOUNDARY);DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());if (textMap != null) {StringBuffer strBuf = new StringBuffer();Iterator iter = textMap.entrySet().iterator();while (iter.hasNext()) {Map.Entry entry = (Map.Entry) iter.next();String inputName = (String) entry.getKey();String inputValue = (String) entry.getValue();if (inputValue == null) {continue;}strBuf.append(LINEND).append(PREFIX).append(BOUNDARY).append(LINEND);strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"").append(LINEND).append(LINEND);strBuf.append(inputValue);strBuf.append(LINEND);}outStream.write(strBuf.toString().getBytes());}// 發送文件數據if (files != null)for (Map.Entry<String, List<File>> filelist : files.entrySet()) {for(int i=0;i<filelist.getValue().size();i++){StringBuilder sb1 = new StringBuilder();sb1.append(PREFIX);sb1.append(BOUNDARY);sb1.append(LINEND);sb1.append("Content-Disposition: form-data; name=\""+filelist.getKey()+"_"+i+"\"; filename=\""+ filelist.getValue().get(i).getName() + "\"" + LINEND);sb1.append("Content-Type: application/octet-stream; charset="+ CHARSET + LINEND);sb1.append(LINEND);outStream.write(sb1.toString().getBytes());InputStream is = new FileInputStream(filelist.getValue().get(i));byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {outStream.write(buffer, 0, len);}is.close();outStream.write(LINEND.getBytes());}}// 請求結束標志byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();outStream.write(end_data);outStream.flush();// 得到響應碼int res = conn.getResponseCode();if (res == 200) {InputStream in = conn.getInputStream();InputStreamReader isReader = new InputStreamReader(in);BufferedReader bufReader = new BufferedReader(isReader);String line = "";String data = "";while ((line = bufReader.readLine()) != null) {data += line;}outStream.close();conn.disconnect();return data;}outStream.close();conn.disconnect();return null;}

form表單里鍵值對的拼接結果示例

------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="textkey"tttttt

form表單里文件的拼接結果示例

------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="filekey"; filename="" Content-Type:

? ? ? ?第二種:使用httpclient,需要下載httpclient-4.5.jar、httpmime-4.5.jar兩個包,下載地址為:http://hc.apache.org/downloads.cgi?大致看了下源碼,其實也是使用的上述方法中的字符拼接,只是封裝后使用起來更簡潔方便一些。

這種方法需要注意的點:

1.HttpClient4.3版本往后,原來的MultipartEntity過時不建議再使用了,替換成新的httpmime下面的MultipartEntityBuilder?

2.multipartEntity 最好設置contentType和boundary,不然會導致后面接收文件時的第一種方法接收不到文件報錯。

3.使用addBinaryBody的坑:addBinaryBody?有6種不同用法,一般都是如下代碼所示上傳File即可,但是當傳byte[]字節數組時,必須使用4參傳值,且第四參必須帶后綴名,例如:entityBuilder.addBinaryBody("file",new byte[]{},ContentType.DEFAULT_BINARY,"fileName.jpg");否則會導致接收文件時getFileNames()為空。

4.不使用addBinaryBody,也可以直接使用addPart,先把文件轉換成FileBody就可以了。

public static Map<String,Object> uploadFileByHTTP(Map<String, List<File>> files,String postUrl,Map<String,String> postParam){String BOUNDARY = java.util.UUID.randomUUID().toString();Map<String,Object> resultMap = new HashMap<String,Object>();CloseableHttpClient httpClient = HttpClients.createDefault();try{//把一個普通參數和文件上傳給下面這個地址 是一個servletHttpPost httpPost = new HttpPost(postUrl);//設置傳輸參數MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();multipartEntity.setCharset(Charset.forName("utf-8"));multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);multipartEntity.setContentType(ContentType.MULTIPART_FORM_DATA);multipartEntity.setBoundary(BOUNDARY);//文件參數for (Map.Entry<String, List<File>> filelist : files.entrySet()) {for(int i=0;i<filelist.getValue().size();i++){//把文件轉換成流對象FileBodyFileBody fundFileBin = new FileBody(filelist.getValue().get(i)); // multipartEntity.addPart("file", fundFileBin);//相當于<input type="file" name="media"/>multipartEntity.addBinaryBody("file", filelist.getValue().get(i));}}//鍵值對參數Set<String> keySet = postParam.keySet();for (String key : keySet) {//相當于<input type="text" name="name" value=name>multipartEntity.addPart(key, new StringBody(postParam.get(key), ContentType.create("application/json", Consts.UTF_8)));}HttpEntity reqEntity = multipartEntity.build();httpPost.setEntity(reqEntity);//log.info("發起請求的頁面地址 " + httpPost.getRequestLine());//發起請求 并返回請求的響應CloseableHttpResponse response = httpClient.execute(httpPost);try {///log.info("----------------------------------------");//打印響應狀態//log.info(response.getStatusLine());resultMap.put("statusCode", response.getStatusLine().getStatusCode());//獲取響應對象HttpEntity resEntity = response.getEntity();if (resEntity != null) {//打印響應長度//log.info("Response content length: " + resEntity.getContentLength());//打印響應內容resultMap.put("data", EntityUtils.toString(resEntity,Charset.forName("UTF-8")));}//銷毀EntityUtils.consume(resEntity);} catch (Exception e) {e.printStackTrace();} finally {response.close();}} catch (ClientProtocolException e1) {e1.printStackTrace();} catch (IOException e1) {e1.printStackTrace();} finally{try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}//log.info("uploadFileByHTTP result:"+resultMap);return resultMap;}

?解釋一下發送文件中的幾點:

1.contentType使用【multipart/form-data】:它會將表單的數據處理為一條消息,以標簽為單元,用分隔符分開。既可以上傳鍵值對,也可以上傳文件,

2.boundary:請求體中的boundary參數指定的就是分隔體,請求參數之間需要通過分隔體分隔,不然就會被識別成一個參數。

二、接收文件也有兩種方式

? ? ? ? 第一種:使用MultipartHttpServletRequest

? ? ? ? 報錯問題1:xxxRequest cannot be cast to MultipartHttpServletRequest異常

????????????????????????好多文章里都是直接將request強轉為MultipartHttpServletRequest,我這里反正是強轉不了就會報這個錯,使用如下方式則沒有問題。

? ? ? ? 報錯問題2:the request was rejected because no multipart boundary was found

? ? ? ? ? ? ? ? ? ? ? ? 就是在發送文件時未設置contentType和boundary導致,所以記得一定要設置奧

? ? ? ? ?報錯問題3:request.getParameter("name")的值為null

??????????????????????????因為設置了【multipart/form-data】,這個表單是基于流的方式提交的,所以需要下載一個jar包,地址如下:http://www.servlets.com/cos/index.html ,再使用multiRequest.getParameter("name")就可以獲取到了。

public void doPost(HttpServletRequest requestold,HttpServletResponse response) {String result = "ok";// 將當前上下文初始化給 CommonsMutipartResolver (多部分解析器)MultipartResolver resolver = new CommonsMultipartResolver(requestold.getSession().getServletContext());// 檢查form中是否有enctype="multipart/form-data"if (resolver.isMultipart(requestold)) {MultipartHttpServletRequest multiRequest = resolver.resolveMultipart(requestold);//解析request,將結果放置在list中String value = multiRequest.getParameter("name");System.out.println("-----"+value+"---------");Map<String, List<MultipartFile>> fileMap = multiRequest.getMultiFileMap();for (String key : fileMap.keySet()) {List<MultipartFile> files = fileMap.get(key);for (MultipartFile file : files) {if (!file.isEmpty()) {String fileName = file.getOriginalFilename();String columnName = file.getName();// 文件保存路徑 String filePath = "d:\\download";File iFile = new File(filePath);File iFileParent = iFile.getParentFile();if(!iFileParent.exists()){iFileParent.mkdirs();}// 轉存文件 try {file.transferTo(new File(filePath));} catch (Exception e) {result = "error";log.error("轉存文件失敗!params:{columnName:"+columnName+",fileName:"+fileName+"}",e);e.printStackTrace();} }else{result = "error";log.info("file.isEmpty!");}}}}try {ServletOutputStream out = response.getOutputStream();out.write(result.getBytes());out.flush();out.close();} catch (IOException e) {e.printStackTrace();log.info("return value error!");}}

? ? ? ? 第二種:使用DiskFileItemFactory?

? ? ? ? 注意點:

? ? ? ? ? ? ? ? 1.jdk1.7以上使用,否則item.getFieldName()會報錯

? ? ? ? ? ? ? ? 2.該方法通過item.isFormField()判斷是否是文件,如果不是文件,就是鍵值對參數

? ? ? ? ? ? ? ? 3.使用stingbuffer拼接發送參數時參數末尾記得加上【\r\n】,否則會將參數視為同一個,我之前就是在傳完鍵值對參數后忘了加,導致最后一個鍵值對參數和第一個文件被視為同一個參數,當成鍵值對參數直接輸出二進制流了。

public void doPost(HttpServletRequest requestold, HttpServletResponse response) {RequestAction request = RequestUtils.getRequestAction(requestold);DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);List items = null;try {items = upload.parseRequest(requestold);} catch (FileUploadException e) {e.printStackTrace();}Iterator iter = items.iterator();String picUrl = null;while (iter.hasNext()) {FileItem item = (FileItem) iter.next();if(item.isFormField()){//判斷是非文件上傳String value;try {value = item.getString("UTF-8");System.out.println(item.getFieldName()+":"+value);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}else{//得到文件保存路徑String sysPath = request.getSession().getServletContext().getRealPath("/resources/images/article/");//得到上傳問價的文件名 test.jpgString filename = item.getName();item.getFieldName();if (null == filename || filename == "") {filename = picUrl;}sysPath = sysPath + filename;System.out.println(item.getFieldName()+":"+sysPath);File saveFile = new File(sysPath);File iFileParent = saveFile.getParentFile();if(!iFileParent.exists()){iFileParent.mkdirs();}try {item.write(saveFile);} catch (Exception e) {e.printStackTrace();}}}}

總結

以上是生活随笔為你收集整理的远程传输文件--java文件流的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。