使用 NIO 下载已经分段的文件 - Java 11
Download already segmented files with NIO - Java 11
我想下载一个已经分成数百个片段的大文件到一个文件中。
所以我有一个数组中所有段的所有 URL-s,我将它手动分成 4 个部分,同时启动 4 个线程,然后在最后将它们合并到一个巨大的文件。
我认为我可以改进我的代码的部分是在我下载这些部分时的部分。目标是打开文件一次,并将所有段附加到其中。
我也对其他解决方案持开放态度。
static void downloadFileSection(int begin, int end, int marker, String[] segmentURLs, String segID) {
try(var file = FileChannel.open(Path.of(segID + "_" + marker + ".seg"), WRITE, CREATE)){
var byteArrayHandler = BodyHandlers.ofByteArray();
IntStream.range(begin, end)
.forEach(index -> {
System.out.println("Downloading segment: " + index);
try {
//This is the part that I think is wrong. I shouldn't be creating a ByteBuffer every segment download.
//Main.sendNormalRequest is a method that sends a request using java 11-s HttpClient.send method.
file.write(ByteBuffer.wrap(Main.sendNormalRequest(segmentURLs[index], byteArrayHandler).body()));
} catch (IOException e) {
e.printStackTrace();
}
});
}catch (IOException e) {
e.printStackTrace();
}
}
您可以使用 BodyHandlers.ofPublisher() 获得 Publisher<List<ByteBuffer>>
。然后,如果状态为 200 OK,请提供并订阅您自己的 Flow.Subscriber<List<ByteBuffer>>
实现,并将字节写入文件,因为它们来自 onNext(...)
方法。如果这些字节表示文本,那么您可能需要注意字符 encoding/transcoding,特别是如果您需要使用与服务器发送的编码不同的编码(通常是 UTF-8)来写入文件。
我想下载一个已经分成数百个片段的大文件到一个文件中。
所以我有一个数组中所有段的所有 URL-s,我将它手动分成 4 个部分,同时启动 4 个线程,然后在最后将它们合并到一个巨大的文件。 我认为我可以改进我的代码的部分是在我下载这些部分时的部分。目标是打开文件一次,并将所有段附加到其中。 我也对其他解决方案持开放态度。
static void downloadFileSection(int begin, int end, int marker, String[] segmentURLs, String segID) {
try(var file = FileChannel.open(Path.of(segID + "_" + marker + ".seg"), WRITE, CREATE)){
var byteArrayHandler = BodyHandlers.ofByteArray();
IntStream.range(begin, end)
.forEach(index -> {
System.out.println("Downloading segment: " + index);
try {
//This is the part that I think is wrong. I shouldn't be creating a ByteBuffer every segment download.
//Main.sendNormalRequest is a method that sends a request using java 11-s HttpClient.send method.
file.write(ByteBuffer.wrap(Main.sendNormalRequest(segmentURLs[index], byteArrayHandler).body()));
} catch (IOException e) {
e.printStackTrace();
}
});
}catch (IOException e) {
e.printStackTrace();
}
}
您可以使用 BodyHandlers.ofPublisher() 获得 Publisher<List<ByteBuffer>>
。然后,如果状态为 200 OK,请提供并订阅您自己的 Flow.Subscriber<List<ByteBuffer>>
实现,并将字节写入文件,因为它们来自 onNext(...)
方法。如果这些字节表示文本,那么您可能需要注意字符 encoding/transcoding,特别是如果您需要使用与服务器发送的编码不同的编码(通常是 UTF-8)来写入文件。