You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Java代码实现Egnyte分片上传并调用Egnyte REST API

Java实现Egnyte分片上传(调用REST API)

我来帮你梳理如何用Java实现Egnyte的分片上传,结合官方Chunked Upload API规范,我会修正并完善你提供的代码示例,同时解释关键要点:

核心流程说明

Egnyte的分片上传需要三个核心步骤才能完成:

  1. 初始化分片上传:先调用API获取唯一的上传ID,用于后续所有分片的关联
  2. 逐个上传分片:按固定大小拆分本地文件,依次上传每个分片,带上分片编号和字节范围信息
  3. 完成上传:所有分片上传成功后,触发合并操作,让服务器生成最终文件

完整代码实现(修正并完善版)

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

public class EgnyteChunkedUploader {

    // 替换为你的Egnyte配置信息
    private static final String EGNYTE_API_BASE = "https://your-domain.egnyte.com/pubapi/v1/fs";
    private static final String AUTH_TOKEN = "your-valid-auth-token";
    private static final String EGNYTE_TARGET_PATH = "/Shared/Uploads/"; // 上传到Egnyte的目标目录

    public ResponseEntity<String> uploadFileChunked(File localFile) throws Exception {
        // 1. 第一步:初始化分片上传,获取上传ID
        String initUploadUrl = EGNYTE_API_BASE + "/chunked" + EGNYTE_TARGET_PATH + localFile.getName();
        HttpHeaders initHeaders = buildEgnyteRequestHeaders();
        ResponseEntity<String> initResponse = new RestTemplate().exchange(
                initUploadUrl,
                HttpMethod.POST,
                new HttpEntity<>(initHeaders),
                String.class
        );
        // 从响应中解析uploadId(实际项目建议用JSON解析库,比如Jackson)
        String uploadId = extractUploadId(initResponse.getBody());

        // 2. 第二步:分片上传配置与执行
        long totalFileSize = localFile.length(); // 修正原代码错误:获取文件实际大小而非磁盘总空间
        int chunkSize = 1024 * 1024; // 1MB分片大小,官方建议范围1MB-5GB
        byte[] chunkBuffer = new byte[chunkSize];
        int partNumber = 1; // Egnyte分片编号从1开始
        ResponseEntity<String> chunkUploadResponse = null;

        // try-with-resources自动关闭流,避免资源泄漏
        try (FileInputStream fis = new FileInputStream(localFile);
             BufferedInputStream bis = new BufferedInputStream(fis)) {

            int bytesRead;
            while ((bytesRead = bis.read(chunkBuffer)) > 0) {
                // 构建当前分片的上传URL
                String chunkUrl = EGNYTE_API_BASE + "/chunked" + EGNYTE_TARGET_PATH + localFile.getName()
                        + "/" + uploadId + "/" + partNumber;

                // 设置分片请求头,关键是Content-Range告知服务器分片范围
                HttpHeaders chunkHeaders = buildEgnyteRequestHeaders();
                long startByte = (long) (partNumber - 1) * chunkSize;
                long endByte = Math.min(startByte + bytesRead - 1, totalFileSize - 1);
                chunkHeaders.add("Content-Range", String.format("bytes %d-%d/%d", startByte, endByte, totalFileSize));

                // 构建带分片数据的请求实体
                HttpEntity<byte[]> chunkEntity = new HttpEntity<>(chunkBuffer, chunkHeaders);
                // 上传当前分片
                chunkUploadResponse = new RestTemplate().exchange(
                        chunkUrl,
                        HttpMethod.POST,
                        chunkEntity,
                        String.class
                );

                partNumber++;
            }
        }

        // 3. 第三步:完成上传,触发服务器合并分片
        String completeUploadUrl = EGNYTE_API_BASE + "/chunked" + EGNYTE_TARGET_PATH + localFile.getName() + "/" + uploadId;
        HttpHeaders completeHeaders = buildEgnyteRequestHeaders();
        ResponseEntity<String> completeResponse = new RestTemplate().exchange(
                completeUploadUrl,
                HttpMethod.PUT,
                new HttpEntity<>(completeHeaders),
                String.class
        );

        return completeResponse;
    }

    // 构建Egnyte请求头,包含认证和内容类型
    private HttpHeaders buildEgnyteRequestHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + AUTH_TOKEN);
        headers.add("Content-Type", "application/octet-stream");
        return headers;
    }

    // 从初始化响应中提取uploadId(示例实现,需根据实际响应格式调整)
    private String extractUploadId(String responseBody) {
        // 假设响应格式为{"uploadId": "xxxx-xxxx-xxxx"},实际用JSON库更可靠
        int startIdx = responseBody.indexOf("uploadId") + 10;
        int endIdx = responseBody.indexOf("\"", startIdx);
        return responseBody.substring(startIdx, endIdx);
    }
}

关键细节解释

  • 初始化上传的必要性:必须先获取uploadId,否则服务器无法识别多个分片属于同一个文件
  • Content-Range头:这是Egnyte识别分片的核心,必须准确设置当前分片在整个文件中的字节范围
  • 分片编号规则:必须从1开始,且连续无缺失,否则合并操作会失败
  • 资源管理:用try-with-resources确保文件流自动关闭,避免内存泄漏

额外注意事项

  • 确保你的认证令牌拥有目标目录的上传权限
  • 实际项目中需要添加异常处理(比如网络重试、分片上传失败重试)
  • 分片大小可根据网络情况调整,但不要超出官方建议的范围

内容的提问来源于stack exchange,提问作者Udhayam P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:26:26