java斷點續傳,java斷點續傳 分片 tcp

本文目錄一覽:

關於JAVA斷點續傳

024字節)。第一次B接收了512字節,那麼第二次連接A就應該從513字節開始傳輸。

也就是說,在第二次傳輸時,B要提供“我要從513字節開始傳送文件F”的信息,然後A使用FileInputStream構建輸入流讀取本地文件,使用skip(512)方法跳過文件F的前512字節再傳送文件,之後B將數據追加(append)到先前接收的文件末尾即可。

進一步考慮,如果要實現多線程傳送,即分塊傳輸,也同樣的道理。假如B要求分作兩塊同時傳輸,那麼A啟動兩個線程,一個從513字節讀到768字節(工256字節),第二個線程從769字節到1024字節即可。

如果你要從網絡上下載文件,就是說A方不是你實現的,那麼你要先確認A方支不支持斷電續傳功能(HTTP1.1),然後你查閱下HTTP1.1協議,在HTTP1.1版本里,可以通過設置請求包頭某個字段的信息(使用URLConnection創建連接並使用setRequestProperty(String key, String value) 方法設置)從而精確讀取文件的某一段數據的。注意,基於HTTP斷點續傳的關鍵是1.1版本,1.0版本是不支持的。

補充:

嗯,查到了,是設置range屬性,即setRequestProperty(“range”, “bytes=513-1024”).你可以使用迅雷下載某個文件,然後從”線程信息“中就可以看到這個http1.1斷點續傳的所有行為信息了。

瀏覽器的斷點續傳用java怎麼實現

斷點設置方法,當有臨時文件時,直接在臨時文件中讀取上次中斷時的斷點位置。沒有臨時文件,即第一次時,重新設置斷點。

rantmpfile.seek()跳轉到一個位置的目的是為了讓各個斷點存儲的位置盡量分開。

java 斷點續傳需要哪些jar包

Java–實現斷點續傳(下載)

— 斷點續傳: 就像迅雷下載文件一樣,停止下載或關閉程序,下次下載時是從上次下載的地方開始繼續進行,而不是重頭開始…

— RandomAccessFile — pointer(文件指針) — seek(移動文件指針) — 斷點續傳

package com.dragon.java.downloadfile;

import java.io.File;

import java.io.IOException;

import java.io.RandomAccessFile;

/*

斷點續傳:對下載軟件非常重要!

— 第一次下載 100 字節

— 第二次下載 101 字節…想辦法知道上次從哪個地方斷掉的。 上次已經下載到了什麼位置。 記下斷點的位置

—— 需要第三方的文件專門記住斷點的位置

*/

public class Test {

public static void main(String args[]) {

File srcFile = new File(“D:/Java4Android/01_Java考古學/01_Java考古學.mp4”);

File desDir = new File(“f:/vidio”);

copyFileToDir(srcFile, desDir);

}

public static void copyFileToDir(File srcFile, File desDir) {

desDir.mkdirs();

// 創建配置文件

File configFile = new File(desDir, srcFile.getName().split(“\\.”)[0]

+ “.config”);

// 創建目標文件

File desFile = new File(desDir, srcFile.getName());

if (!configFile.exists() desFile.exists()) {

System.out.println(“已下載過該文件!”);

return;

}

RandomAccessFile rafSrc = null;

RandomAccessFile rafDes = null;

RandomAccessFile rafConfig = null;

try {

rafSrc = new RandomAccessFile(srcFile, “r”);

rafDes = new RandomAccessFile(desFile, “rw”);

rafConfig = new RandomAccessFile(configFile, “rw”);

// 設置目標文件和源文件一樣長

rafDes.setLength(srcFile.length());

// 設置配置的文件長度為8,防止第一次下載是出現EOF 異常

rafConfig.setLength(8);

// 從上次下載的位置開始繼續下載!

long pointer = rafConfig.readLong();

System.out.println(“已下載:” + ((float) pointer / srcFile.length())

* 100 + “%”);

rafSrc.seek(pointer);

rafDes.seek(pointer);

// 單次傳輸長度設置小點,好觀察是否斷點續傳

byte[] buffer = new byte[32];

int len = -1;

// 每次複製的開始,必須把源文件的指針和目標文件的指針從上次斷開的位置去讀

while ((len = rafSrc.read(buffer)) != -1) {

rafDes.write(buffer, 0, len);

// 在配置文件寫的時候,每次使文件指針移動到最初的位置 — 這樣永遠對只會存儲前8個字節

rafConfig.seek(0);

// 每複製一次之和,趕緊記錄下文件指針的位置,以備斷點續傳使用。

rafConfig.writeLong(rafSrc.getFilePointer());

}

} catch (IOException e) {

System.out.println(e);

} finally {

try {

rafSrc.close();

rafDes.close();

rafConfig.close();

} catch (IOException e) {

System.out.println(e);

}

// 在流關閉之後刪除配置文件

System.out.println(“下載成功!”);

configFile.delete();

}

}

}

java socket數據流斷點續傳

設備往你這邊傳輸數據時,你得知他的設備ID、數據的MD5校驗值、操作授權代碼。

傳輸數據開始,設備向你這邊傳輸數據,你這邊將受到的數據保存到文件或者數據庫。傳輸過程中,你可能要告訴設備已經保存的數據字節數。

假如網絡連接異常,按照你說的思路,發送心跳包檢測連接情況。你這邊程序將本次操作的數據保存、並將設備ID、數據MD5校驗值、操作授權碼、已保存的字節數保存到日誌。

下次客戶端請求續傳,你就校驗它的設備ID、操作授權代碼,然後再告訴它從哪裡開始續傳,跳過那些字節。

續傳完成,通知客戶端,續傳成功。

用java向hdfs上傳文件時,如何實現斷點續傳

@Component(“javaLargeFileUploaderServlet”)

@WebServlet(name = “javaLargeFileUploaderServlet”, urlPatterns = { “/javaLargeFileUploaderServlet” })

public class UploadServlet extends HttpRequestHandlerServlet

implements HttpRequestHandler {

private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);

@Autowired

UploadProcessor uploadProcessor;

@Autowired

FileUploaderHelper fileUploaderHelper;

@Autowired

ExceptionCodeMappingHelper exceptionCodeMappingHelper;

@Autowired

Authorizer authorizer;

@Autowired

StaticStateIdentifierManager staticStateIdentifierManager;

@Override

public void handleRequest(HttpServletRequest request, HttpServletResponse response)

throws IOException {

log.trace(“Handling request”);

Serializable jsonObject = null;

try {

// extract the action from the request

UploadServletAction actionByParameterName =

UploadServletAction.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.action));

// check authorization

checkAuthorization(request, actionByParameterName);

// then process the asked action

jsonObject = processAction(actionByParameterName, request);

// if something has to be written to the response

if (jsonObject != null) {

fileUploaderHelper.writeToResponse(jsonObject, response);

}

}

// If exception, write it

catch (Exception e) {

exceptionCodeMappingHelper.processException(e, response);

}

}

private void checkAuthorization(HttpServletRequest request, UploadServletAction actionByParameterName)

throws MissingParameterException, AuthorizationException {

// check authorization

// if its not get progress (because we do not really care about authorization for get

// progress and it uses an array of file ids)

if (!actionByParameterName.equals(UploadServletAction.getProgress)) {

// extract uuid

final String fileIdFieldValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId, false);

// if this is init, the identifier is the one in parameter

UUID clientOrJobId;

String parameter = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);

if (actionByParameterName.equals(UploadServletAction.getConfig) parameter != null) {

clientOrJobId = UUID.fromString(parameter);

}

// if not, get it from manager

else {

clientOrJobId = staticStateIdentifierManager.getIdentifier();

}

// call authorizer

authorizer.getAuthorization(

request,

actionByParameterName,

clientOrJobId,

fileIdFieldValue != null ? getFileIdsFromString(fileIdFieldValue).toArray(new UUID[] {}) : null);

}

}

private Serializable processAction(UploadServletAction actionByParameterName, HttpServletRequest request)

throws Exception {

log.debug(“Processing action ” + actionByParameterName.name());

Serializable returnObject = null;

switch (actionByParameterName) {

case getConfig:

String parameterValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);

returnObject =

uploadProcessor.getConfig(

parameterValue != null ? UUID.fromString(parameterValue) : null);

break;

case verifyCrcOfUncheckedPart:

returnObject = verifyCrcOfUncheckedPart(request);

break;

case prepareUpload:

returnObject = prepareUpload(request);

break;

case clearFile:

uploadProcessor.clearFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));

break;

case clearAll:

uploadProcessor.clearAll();

break;

case pauseFile:

ListUUID uuids = getFileIdsFromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));

uploadProcessor.pauseFile(uuids);

break;

case resumeFile:

returnObject =

uploadProcessor.resumeFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));

break;

case setRate:

uploadProcessor.setUploadRate(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)),

Long.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.rate)));

break;

case getProgress:

returnObject = getProgress(request);

break;

}

return returnObject;

}

ListUUID getFileIdsFromString(String fileIds) {

String[] splittedFileIds = fileIds.split(“,”);

ListUUID uuids = Lists.newArrayList();

for (int i = 0; i splittedFileIds.length; i++) {

uuids.add(UUID.fromString(splittedFileIds[i]));

}

return uuids;

}

private Serializable getProgress(HttpServletRequest request)

throws MissingParameterException {

Serializable returnObject;

String[] ids =

new Gson()

.fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId), String[].class);

CollectionUUID uuids = Collections2.transform(Arrays.asList(ids), new FunctionString, UUID() {

@Override

public UUID apply(String input) {

return UUID.fromString(input);

}

});

returnObject = Maps.newHashMap();

for (UUID fileId : uuids) {

try {

ProgressJson progress = uploadProcessor.getProgress(fileId);

((HashMapString, ProgressJson) returnObject).put(fileId.toString(), progress);

}

catch (FileNotFoundException e) {

log.debug(“No progress will be retrieved for ” + fileId + ” because ” + e.getMessage());

}

}

return returnObject;

}

private Serializable prepareUpload(HttpServletRequest request)

throws MissingParameterException, IOException {

// extract file information

PrepareUploadJson[] fromJson =

new Gson()

.fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.newFiles), PrepareUploadJson[].class);

// prepare them

final HashMapString, UUID prepareUpload = uploadProcessor.prepareUpload(fromJson);

// return them

return Maps.newHashMap(Maps.transformValues(prepareUpload, new FunctionUUID, String() {

public String apply(UUID input) {

return input.toString();

};

}));

}

private Boolean verifyCrcOfUncheckedPart(HttpServletRequest request)

throws IOException, MissingParameterException, FileCorruptedException, FileStillProcessingException {

UUID fileId = UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));

try {

uploadProcessor.verifyCrcOfUncheckedPart(fileId,

fileUploaderHelper.getParameterValue(request, UploadServletParameter.crc));

}

catch (InvalidCrcException e) {

// no need to log this exception, a fallback behaviour is defined in the

// throwing method.

// but we need to return something!

return Boolean.FALSE;

}

return Boolean.TRUE;

}

}

java web斷點續傳,我用的是fileupload來做的上傳。

使用Struts2上傳文件:

Struts文件上傳需要使用File Upload Filter。Filter Upload Filter使用一些默認的規則:

Form中的s:file name=”image”/s:file標籤對應着Action類中的三個屬性分別是:上傳文件(java.io.File類型),文件名(java.lang.String類型),文件類型(java.lang.String類型,例如:image/jpeg)。命名規約為:

文件:名字與s:file標籤中的name屬性一致,這裡為:image

文件名:文件 + FileName,這裡為:imageFileName

文件類型:文件 + ContentType,這裡為:imageContentType

所以針對上述s:file name=”image”/s:file表示啊的上傳文件的JSP和Action類被別為:

imageUpload.jsp:

[html] view plain copy

%@ page contentType=”text/html;charset=UTF-8″ language=”java” %

%@taglib prefix=”s” uri=”/struts-tags” %

html

headtitleImage Upload/title/head

body

h1 Image Upload Page /h1

s:form action=”imageUpload” method=”post” enctype=”multipart/form-data”

s:file name=”image”/s:file

s:submit/s:submit

/s:form

/body

/html

ImageUploadAction.java:

[html] view plain copy

package com.jpleasure;

import com.opensymphony.xwork2.ActionSupport;

import java.io.File;

import java.io.InputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

public class ImageUploadAction extends ActionSupport {

private File image;

private String imageFileName;

private String imageContentType;

public File getImage() {

return image;

}

public void setImage(File image) {

this.image = image;

}

public String getImageFileName() {

return imageFileName;

}

public void setImageFileName(String imageFileName) {

this.imageFileName = imageFileName;

}

public String getImageContentType() {

return imageContentType;

}

public void setImageContentType(String imageContentType) {

this.imageContentType = imageContentType;

}

public String execute() {

if (image != null) {

System.out.println(“file name is:” + this.imageFileName);

System.out.println(“file content type is:” + this.imageContentType);

System.out.println(“file length is:” + this.image.length());

}

return SUCCESS;

}

}

Struts.xml配置文件:

[html] view plain copy

action name=”imageUpload” class=”com.jpleasure.ImageUploadAction”

result/success.jsp/result

/action

這樣當我們選中上傳文件,提交的時候:文件內容會以File類型的方式放在image聲明的變量中。文件的名字將會被放在imageFileName命名的變量中,文件的類型被放在imageContentType命名的變量中。

文件下載:

文件下載需要使用一個特殊的Result,stream類型的Result。Stream類型的Result主要用來處理文件下載操作。

處理原理為:所有的下載文件都是將一個二進制的流寫入到HttpResponse中去。在Action類中定義一個InputSream類型的二進制流,在Result返回給用戶的時候返回給用戶。

擴展上述的代碼,將上傳來的文件直接下載給用戶:

ImageUploadAction中需要追加一個InputSream類型的對象,並且指向上傳的文件,代碼如下,紅色部分表示變化:

[html] view plain copy

package com.jpleasure;

import com.opensymphony.xwork2.ActionSupport;

import java.io.File;

import java.io.InputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

public class ImageUploadAction extends ActionSupport {

private File image;

private String imageFileName;

private String imageContentType;

private InputStream imageInputStream = null;

public InputStream getImageInputStream() {

return imageInputStream;

}

public void setImageInputStream(InputStream imageInputStream) {

this.imageInputStream = imageInputStream;

}

public File getImage() {

return image;

}

public void setImage(File image) {

this.image = image;

}

public String getImageFileName() {

return imageFileName;

}

public void setImageFileName(String imageFileName) {

this.imageFileName = imageFileName;

}

public String getImageContentType() {

return imageContentType;

}

public void setImageContentType(String imageContentType) {

this.imageContentType = imageContentType;

}

public String execute() {

if (image != null) {

System.out.println(“file name is:” + this.imageFileName);

System.out.println(“file content type is:” + this.imageContentType);

System.out.println(“file length is:” + this.image.length());

try {

this.imageInputStream = new FileInputStream (image);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

return SUCCESS;

}

}

配置文件為,紅色為變化部分:

[html] view plain copy

action name=”imageUpload” class=”com.jpleasure.ImageUploadAction”

result name=”success” type=”stream”

param name=”contentType”image/pjpeg/param

param name=”inputName”imageInputStream/param

param name=”contentDisposition”attachment;filename=”image.jpg”/param

param name=”bufferSize”1024/param

/result

/action

ContentType表示下載文件的類型。

InputName表示Action類中用來下載文件的字段的名字。

ContentDisposition用來控制文件下載的一些信息,包括是否打開另存對話框,下載文件名等。

BufferSize表示文件下載時使用的緩衝區的大小。

實際項目開發的考慮:

控制上傳文件的類型和最大允許上傳文件的size

使用File Upload Intercepter的參數可盈控制上傳文件的類型和最大允許上傳文件的size。例如:

[html] view plain copy

struts

package name=”myPackage” extends=”struts-default”

interceptor-ref name=”fileUpload”

param name=”maximumSize”2MB/param

param name=”allowedTypes”text/html,image/jpeg/param

/interceptor-ref

interceptor-ref name=”basicStack”/

action name=”imageUpload” class=”com.jpleasure.ImageUploadAction”

result name=”success” type=”stream”

param name=”contentType”image/pjpeg/param

param name=”inputName”imageInputStream/param

param name=”contentDisposition”

attachment;filename=”image.jpg”

/param

param name=”bufferSize”1024/param

/result

/action

/package

/struts

上述表示允許上傳jpeg和html類型的文件,且最大文件上傳size為2MB

顯示錯誤信息:

可以使用如下key表示的message來顯示文件上傳出錯的提示信息:

消息Key    說明  

struts.messages.error.uploading    文件無法正常上傳時的公共錯誤  

struts.messages.error.file.too.large    文件大小超過最大允許size時的錯誤提示  

struts.messages.error.content.type.not.allowed    文件類型不在上傳文件允許類型中的錯誤提示  

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/180060.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-22 05:11
下一篇 2024-11-22 05:11

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論