從 HTTP 服務器下載文本文件,支援:指定下載行數、流式處理避免 OOM、編碼自動適配、異常安全關閉流。可作為 FTP/HDFS 多源同步的基礎組件。
package com.util.http;
import java.io.*;
import java.net.*;
public class HttpUtil {
private final String httpPath;
public HttpUtil(String httpPath) { this.httpPath = httpPath; }
/** 獲取輸入流 (通用) */
public InputStream getStream(String url) {
try {
URLConnection conn = new URL(url).openConnection();
return conn.getInputStream();
} catch (IOException e) {
throw new RuntimeException("獲取流失敗: " + url, e);
}
}
/**
* 下載指定行數
* @param url 遠程地址
* @param localFile 本地保存路徑
* @param maxLines 最大行數 (-1 表示全部)
* @return 實際下載行數,-1 表示失敗
*/
public int downloadLines(String url, String localFile, int maxLines) {
try (InputStream in = getStream(url);
BufferedReader reader = new BufferedReader(new InputStreamReader(in, detectEncoding(in)));
BufferedWriter writer = new BufferedWriter(new FileWriter(localFile))) {
String line;
int count = 0;
while ((line = reader.readLine()) != null && (maxLines < 0 || count < maxLines)) {
writer.write(line);
writer.newLine();
count++;
}
return count;
} catch (IOException e) {
throw new RuntimeException("下載失敗: " + url, e);
}
}
/** 簡易編碼檢測 (實際建議用 Apache Tika 或 juniversalchardet) */
private String detectEncoding(InputStream in) throws IOException {
in.mark(4);
byte[] bom = new byte[4];
in.read(bom);
in.reset();
if (bom[0] == (byte)0xEF && bom[1] == (byte)0xBB && bom[2] == (byte)0xBF) return "UTF-8";
if (bom[0] == (byte)0xFE && bom[1] == (byte)0xFF) return "UTF-16BE";
if (bom[0] == (byte)0xFF && bom[1] == (byte)0xFE) return "UTF-16LE";
return "GBK"; // 國內常見默認
}
public static void main(String[] args) {
if (args.length < 3) {
System.err.println("用法: java HttpUtil ");
return;
}
new HttpUtil(args[0]).downloadLines(args[0], args[1], Integer.parseInt(args[2]));
}
}
BufferedReader.readLine() + BufferedWriter.newLine(),天然處理跨平台換行符 (\n/\r\n)。getStream() 可復用於其他下載邏輯;易於加入斷點續傳 (Range 頭)、進度回調、校驗和等功能。// 1. 檢查本地文件大小
long existing = Files.size(Paths.get(localFile));
// 2. 發送 Range 請求
URLConnection conn = new URL(url).openConnection();
conn.setRequestProperty("Range", "bytes=" + existing + "-");
// 3. 追加寫入 (FileOutputStream(localFile, true))
// 4. 對比 Content-Range 响應頭驗證完整性
HttpUtil 專注「行級文本下載」,代碼簡潔、健壯,可直接集成到 ETL、日誌收集、配置同步等管道中。生產環境建議加入連接池、重試策略、熔斷監控。