要清楚,我不相信这种方法实际上会提高下载速度。不过,如果您从多个镜像下载相同的文件,它可能会提供更一致的下载速度。
首先,如果您的文件不是太大,您可以在写出之前缓冲所有文件。因此,分配你的所有线程可以访问一个缓冲区:
byte[] buf = new byte[fileSize];
现在你创建一个合适的主题类型:
public class WriterThread extends Thread
{
byte[] buf;
int write_pos, write_remaining;
public WriterThread(byte[] buf, int start, int len)
{
this.buf = buf;
this.write_pos = start;
this.write_remaining = len;
}
@Override
public void run()
{
try (Socket s = yourMethodForSettingUpTheSocketConnection();
InputStream istream = s.getInputStream()) {
while (this.write_remaining > 0) {
int read = istream.read(this.buf, this.write_pos, this.write_remaining);
if (read == -1) error("Not enough data received");
this.write_remaining -= read;
this.write_pos += read;
}
// otherwise you are done reading your chunk!
}
}
}
现在你可以开始为许多WriterThread
对象与适当的开始和长度。例如,对于一个文件,是6000个字节大小:
byte[] buf = new byte[6000];
WriterThread t0 = new WriterThread(buf, 0, 3000);
WriterThread t1 = new WriterThread(buf, 3000, 3000);
t0.start();
t1.start();
t0.join();
t1.join();
// check for errors
注意的重要一点在这里:每个WriterThreads都有referecence完全相同的缓冲,只是不同的偏移,它开始于写作。当然,你必须确保yourMethodForSettingUpTheSocketConnection
请求从偏移量this.write_pos
开始的数据;你如何做到这一点取决于你使用的网络协议,超出了你所问的范围。
如果您的文件太大而无法放入内存,则此方法无效。相反,您必须先使用(较慢)方法首先创建一个大文件,然后写入该文件。虽然我还没有尝试过,你应该能够使用java.nio.file.File.newByteChannel()' to set up a suitable
SeekableByteChannel as your output file. If you create such a
SeekableByteChannel sbc`,那么你应该能够做到
sbc.location(fileSize - 1); // move to the specified position in the file
sbc.write(java.nio.ByteBuffer.allocate(1)); // grow the file to the expected final size
然后用每个线程一个不同SeekableByteChannel
对象,指向同一个文件在磁盘上,并使用SeekableByteChannel.location(int)
方法设置写入起始位置。你需要一个临时byte[]
围绕你可以用一个ByteBuffer
(通过ByteBuffer.wrap()
),但在其他方面的战略是类似于上面:
thread_local_sbc.location(this.write_pos);
,然后每thread_local_sbc.write()
将会写入文件开始this.write_pos
。
我不确定这个,所以我把它作为评论发布,但是你不能在文件中的指定位置写入吗?既然你知道每个部分的大小,我认为你可以创建一个1024kB的空白文件,并且每个线程都可以从一个不同的索引开始写。 – DeadlyJesus 2013-04-29 12:44:36
为什么有人希望有三个线程来下载文件并大幅增加开销? – 2013-04-29 12:50:12
实际上,我想通过将文件分割成多个部分并分别下载它们来提高文件下载速度,从而提高整体速度。这是我想要实现的逻辑背后的想法 – Dinesh 2013-04-29 14:18:13