首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 使用 HTTP 協議實現文件下載完整教學範例

     編輯:Java 相關知識

Java HTTP 文件下載實戰指南

在 Java 開發中,透過 HTTP 協議下載文件是常見需求。本文提供一個完整、可直接運行的範例,展示如何使用 HttpURLConnection 實現文件下載,包含文件名解析、進度顯示、異常處理等關鍵技術點。

核心實現邏輯

下載流程主要包含四個步驟:建立連接、解析文件名、讀取數據流、寫入本地文件。關鍵在於正確處理 Content-Disposition 響應頭以獲取原始文件名,並對 URL 編碼的文件名進行解碼。

完整代碼範例

package com.hongyuan.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;

public class FileDownload {
    public static final String LOCAL_PATH = "d:/";

    public static void main(String[] args) {
        // 待下載文件地址
        String fileUrl = "https://211.162.55.16/cdn.百度pcs.com/file/6a73dab7c03023a9835cc737f447674d?xcode=af6ffdc43a44169bac968d32c4bd420084a9a97c308112c9&fid=3255571826-250528-130564002&time=1397293108&sign=FDTAXER-DCb740ccc5511e5e8fedcff06b081203-mQkOeRDtXpyQWwYJkI%2BxKJpxn5k%3D&to=cb&fm=N,B,U,nc&newver=1&expires=1397297563&rt=sh&r=854979042&logid=1751715936&sh=1&vuk=3255571826&fn=Web%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%20%E7%AC%AC5%E7%89%88.pdf&wshc_tag=0&wsiphost=ipdbm";
        
        InputStream in = null;
        OutputStream out = null;
        HttpURLConnection conn = null;
        String fileName = null;
        
        try {
            // 初始化連接
            URL url = new URL(fileUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);

            // 獲取文件名
            String disposition = conn.getHeaderField("Content-Disposition");
            if (disposition != null && !"".equals(disposition)) {
                // 從響應頭中獲取文件名
                fileName = disposition.split(";")[1].split("=")[1].replaceAll("\"", "");
            } else {
                // 從 URL 中獲取文件名
                fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            }

            if (fileName != null && !"".equals(fileName)) {
                // 文件名解碼
                fileName = URLDecoder.decode(fileName, "utf-8");
            } else {
                // 若無法獲取文件名,則隨機生成一個
                fileName = "file_" + (int)(Math.random() * 10);
            }

            // 讀取數據
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                byte[] buffer = new byte[2048];
                in = conn.getInputStream();
                out = new FileOutputStream(new File(LOCAL_PATH, fileName));
                int count = 0;
                int finished = 0;
                int size = conn.getContentLength();
                
                while ((count = in.read(buffer)) != -1) {
                    if (count != 0) {
                        out.write(buffer, 0, count);
                        finished += count;
                        System.out.printf("########################################---->%1$.2f%%\n", (double)finished / size * 100);
                    } else {
                        break;
                    }
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) out.close();
                if (in != null) in.close();
                if (conn != null) conn.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

關鍵技術點解析

  • 連接設置:setDoInput(true) 和 setDoOutput(true) 啟用輸入輸出流
  • 文件名獲取策略:優先從 Content-Disposition 響應頭解析,失敗則從 URL 提取
  • 中文文件名處理:使用 URLDecoder.decode() 處理 URL 編碼的中文文件名
  • 進度顯示:通過 Content-Length 計算下載百分比,實時輸出進度條
  • 資源釋放:finally 塊確保流和連接正確關閉,防止資源洩漏

常見問題與優化建議

生產環境中建議增加:斷點續傳支持(Range 請求頭)、多線程分塊下載、下載速度限制、更完善的異常重試機制。對於大文件,建議使用 BufferedInputStream 和 BufferedOutputStream 提升 I/O 效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved