package com.estate.expert.admin.utils;
|
|
import java.io.*;
|
import java.net.*;
|
import java.nio.channels.Channels;
|
import java.nio.channels.ReadableByteChannel;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.nio.file.StandardCopyOption;
|
import java.util.Map;
|
import java.util.HashMap;
|
|
public class FileDownloader {
|
|
/**
|
* 增强的文件下载方法
|
*/
|
public byte[] downloadFile(String fileUrl) throws Exception {
|
// 验证URL
|
if (fileUrl == null || fileUrl.trim().isEmpty()) {
|
throw new IllegalArgumentException("URL不能为空");
|
}
|
|
URL url = new URL(fileUrl);
|
|
// 设置超时和请求头
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
connection.setRequestMethod("GET");
|
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
|
connection.setRequestProperty("Accept", "application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/msword");
|
connection.setConnectTimeout(30000);
|
connection.setReadTimeout(60000);
|
connection.setInstanceFollowRedirects(true);
|
|
int responseCode = connection.getResponseCode();
|
|
if (responseCode != HttpURLConnection.HTTP_OK) {
|
throw new IOException("HTTP请求失败,状态码: " + responseCode);
|
}
|
|
// 检查内容类型
|
String contentType = connection.getContentType();
|
if (contentType == null ||
|
(!contentType.contains("word") &&
|
!contentType.contains("octet-stream") &&
|
!contentType.contains("document"))) {
|
System.out.println("警告: 内容类型可能不是Word文档: " + contentType);
|
}
|
|
// 获取文件大小
|
int contentLength = connection.getContentLength();
|
System.out.println("文件大小: " + (contentLength > 0 ? contentLength + " 字节" : "未知"));
|
|
// 下载文件
|
try (InputStream inputStream = connection.getInputStream();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
|
byte[] buffer = new byte[8192];
|
int bytesRead;
|
long totalBytes = 0;
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
outputStream.write(buffer, 0, bytesRead);
|
totalBytes += bytesRead;
|
|
if (contentLength > 0) {
|
int progress = (int) ((totalBytes * 100) / contentLength);
|
if (progress % 10 == 0) {
|
System.out.print("\r下载进度: " + progress + "%");
|
}
|
}
|
}
|
|
byte[] fileData = outputStream.toByteArray();
|
|
if (fileData.length == 0) {
|
throw new IOException("下载的文件内容为空");
|
}
|
|
System.out.println("\n下载完成,实际大小: " + fileData.length + " 字节");
|
|
// 验证文件格式(检查是否是有效的Word文档)
|
if (!isValidWordDocument(fileData)) {
|
System.out.println("警告: 下载的文件可能不是有效的Word文档");
|
}
|
|
return fileData;
|
|
} finally {
|
connection.disconnect();
|
}
|
}
|
|
/**
|
* 验证是否为有效的Word文档
|
*/
|
private boolean isValidWordDocument(byte[] data) {
|
if (data.length < 4) {
|
return false;
|
}
|
|
// 检查.docx格式 (ZIP格式)
|
if (data[0] == 0x50 && data[1] == 0x4B && data[2] == 0x03 && data[3] == 0x04) {
|
return true;
|
}
|
|
// 检查.doc格式 (OLE格式)
|
if (data[0] == (byte)0xD0 && data[1] == (byte)0xCF &&
|
data[2] == 0x11 && data[3] == (byte)0xE0) {
|
return true;
|
}
|
|
return false;
|
}
|
|
/**
|
* 下载并保存到文件
|
*/
|
public File downloadToFile(String fileUrl, String outputPath) throws Exception {
|
byte[] data = downloadFile(fileUrl);
|
|
File outputFile = new File(outputPath);
|
File parentDir = outputFile.getParentFile();
|
if (parentDir != null && !parentDir.exists()) {
|
parentDir.mkdirs();
|
}
|
|
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
fos.write(data);
|
}
|
|
System.out.println("文件已保存到: " + outputFile.getAbsolutePath());
|
return outputFile;
|
}
|
|
/**
|
* 批量下载
|
*/
|
public Map<String, byte[]> batchDownload(String[] urls) {
|
Map<String, byte[]> results = new HashMap<>();
|
|
for (String url : urls) {
|
try {
|
System.out.println("下载: " + url);
|
byte[] data = downloadFile(url);
|
results.put(url, data);
|
System.out.println("✓ 下载成功");
|
} catch (Exception e) {
|
System.err.println("✗ 下载失败: " + e.getMessage());
|
results.put(url, null);
|
}
|
}
|
|
return results;
|
}
|
|
/**
|
* 使用NIO下载(更高效)
|
*/
|
public void downloadWithNIO(String fileUrl, String outputPath) throws Exception {
|
URL url = new URL(fileUrl);
|
|
try (InputStream inputStream = url.openStream();
|
ReadableByteChannel rbc = Channels.newChannel(inputStream);
|
FileOutputStream fos = new FileOutputStream(outputPath)) {
|
|
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
}
|
|
System.out.println("NIO下载完成: " + outputPath);
|
}
|
}
|