我正在尝试在 Kotlin 中下载大文件(这个问题。除了我使用 Kotlin 而不是 java,语法略有不同。
val client = OkHttpClient()
val request = Request.Builder().url(urlString).build()
val response = client.newCall(request).execute()
val is = response.body().byteStream()
val input = BufferedInputStream(is)
val output = FileOutputStream(file)
val data = ByteArray(1024)
val total = 0L
val count : Int
do {
count = input.read(data)
total += count
output.write(data, 0, count)
} while (count != -1)
output.flush()
output.close()
input.close()
它的工作原理是它在不使用太多内存的情况下下载文件,但它似乎不必要地无效,因为它不断尝试写入更多数据而不知道是否有新数据到达。
我自己的测试似乎也证实了这一点,同时在资源非常有限的虚拟机上运行它,因为它似乎使用更多的 CPU,同时下载速度比 python 中的类似脚本要低,并且当然使用wget
.
我想知道是否有一种方法可以给某些东西一个回调,如果 x 字节可用或者它是文件末尾,那么我就不必不断地尝试获取更多数据而不知道是否存在是任意的。
编辑:
如果 okhttp 不可能,我使用其他东西没有问题,只是它是我习惯的 http 库。
从版本 11 开始,Java 内置了一个Http客户端 https://openjdk.java.net/groups/net/httpclient/intro.html它实现了
具有非阻塞背压的异步数据流
如果您希望代码仅在有数据需要处理时运行,那么这就是您所需要的。
如果您有能力升级到 Java 11,您将能够使用以下方法开箱即用地解决您的问题HttpResponse.BodyHandlers.ofFile https://download.java.net/java/early_access/jdk11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandlers.html#ofFile(java.nio.file.Path,java.nio.file.OpenOption...)身体处理程序。您不必自己实现任何数据传输逻辑。
科特林示例:
fun main(args: Array<String>) {
val client = HttpClient.newHttpClient()
val request = HttpRequest.newBuilder()
.uri(URI.create("https://www.google.com"))
.GET()
.build()
println("Starting download...")
client.send(request, HttpResponse.BodyHandlers.ofFile(Paths.get("google.html")))
println("Done with download.")
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)