多线程下载工具JAVA源码 本人写了 许多代码 唯独Java用的比较爽 代码比较烦
nvjava.rar
(4.5 KB, 下载次数: 13)
[Java] 纯文本查看 复制代码 import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class DownloadTool extends JFrame {
private JProgressBar progressBar;
private JButton startButton;
private ExecutorService executorService;
private static final int THREAD_COUNT = 4; // 使用4个线程进行下载
private JLabel speedLabel;
private JLabel timeLabel;
private long startTime;
private AtomicInteger totalDownloadedBytes = new AtomicInteger(0);
private int fileSize = 0;
public DownloadTool() {
setTitle("多线程下载工具");
setSize(400, 150);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
startButton = new JButton("开始下载");
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
startDownload();
}
});
speedLabel = new JLabel("速度: 0.00 MB/S");
timeLabel = new JLabel("剩余时间: 00:00:00");
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); // 使用FlowLayout排列标签
infoPanel.add(speedLabel);
infoPanel.add(timeLabel);
setLayout(new BorderLayout());
add(infoPanel, BorderLayout.NORTH);
add(progressBar, BorderLayout.CENTER);
add(startButton, BorderLayout.SOUTH);
}
private void startDownload() {
String fileURL = "https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.17_250110_x64_01.exe"; // 替换为实际的文件URL
String savePath = "qq.exe"; // 替换为实际的保存路径
try {
URL url = new URL(fileURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
fileSize = connection.getContentLength();
executorService = Executors.newFixedThreadPool(THREAD_COUNT);
int partSize = fileSize / THREAD_COUNT;
startTime = System.currentTimeMillis();
for (int i = 0; i < THREAD_COUNT; i++) {
int startByte = i * partSize;
int endByte = (i == THREAD_COUNT - 1) ? fileSize : (i + 1) * partSize - 1;
executorService.execute(new DownloadThread(url, savePath, startByte, endByte));
}
new Thread(() -> {
while (!executorService.isTerminated()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
updateSpeedAndTime();
}
// 确保在所有线程完成后更新进度条到100%
if (totalDownloadedBytes.get() == fileSize) {
SwingUtilities.invokeLater(() -> {
progressBar.setValue(100);
progressBar.setString("下载完成");
});
}
}).start();
executorService.shutdown();
} catch (IOException e) {
e.printStackTrace();
}
}
private void updateSpeedAndTime() {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - startTime;
double speed = (totalDownloadedBytes.get() * 1000.0) / (elapsedTime * 1024 * 1024); // MB/S
int remainingBytes = fileSize - totalDownloadedBytes.get();
long remainingTime = (long) (remainingBytes / (speed * 1024 * 1024) * 1000); // 毫秒
String speedText = String.format("速度: %.2f MB/S", speed);
String timeText = String.format("剩余时间: %02d:%02d:%02d",
remainingTime / 3600000,
(remainingTime % 3600000) / 60000,
(remainingTime % 60000) / 1000);
SwingUtilities.invokeLater(() -> {
speedLabel.setText(speedText);
timeLabel.setText(timeText);
});
}
private class DownloadThread implements Runnable {
private URL url;
private String savePath;
private int startByte;
private int endByte;
public DownloadThread(URL url, String savePath, int startByte, int endByte) {
this.url = url;
this.savePath = savePath;
this.startByte = startByte;
this.endByte = endByte;
}
@Override
public void run() {
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range", "bytes=" + startByte + "-" + endByte);
InputStream inputStream = connection.getInputStream();
byte[] buffer = new byte[4096];
int bytesRead;
try (RandomAccessFile outputStream = new RandomAccessFile(savePath, "rw")) {
outputStream.seek(startByte);
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalDownloadedBytes.addAndGet(bytesRead);
updateProgressBar(bytesRead);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void updateProgressBar(final int bytesRead) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int progress = (int) ((totalDownloadedBytes.get() * 100.0) / fileSize);
progressBar.setValue(progress);
double downloadedMB = totalDownloadedBytes.get() / (1024.0 * 1024.0);
double totalMB = fileSize / (1024.0 * 1024.0);
String progressText = String.format("%.2f MB/%.2f MB", downloadedMB, totalMB);
progressBar.setString(progressText);
}
});
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new DownloadTool().setVisible(true);
}
});
}
}
|