如何更有效地通过 http 下载大文件?

2024-02-16

我正在尝试在 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(使用前将#替换为@)

如何更有效地通过 http 下载大文件? 的相关文章

随机推荐

  • 如何在 AWS Step Function 中获取纪元时间

    我们可以使用 State EnteredTime 引用AWS Step函数中的当前时间 但这给出了ISO格式 有没有办法获取纪元秒 毫秒 我想基于此在 DynamoDB 中添加 TTL 值 这可能吗 或者我是否必须仅为时间戳调用 Lambd
  • 观察对象的所有元素(除了一个元素)

    我的代码中有一块手表 scope watch foo function true 这确保了如果对象 foo 中的任何属性发生更改 则将调用此监视 我想对此破例 如果 foo 中除一个属性之外的任何属性发生更改 我想调用此监视 如果该属性发生
  • 如何使用从密码派生的密钥正确加密和解​​密文件

    我正在尝试找出使用 PBEWithHmacSHA256AndAES 256 标准加密和解密文件的正确过程 据我了解 看这个示例代码 https docs oracle com javase 8 docs technotes guides s
  • 如何从文件中获取 Unix 权限掩码? [复制]

    这个问题在这里已经有答案了 如何使用 python 在 nix 上获取文件的权限掩码 例如 644 或 755 有没有任何函数或类可以做到这一点 非常感谢 os stat是一个包装器stat 2 http linux die net man
  • 谷歌绘图 API [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一种方法来创建谷歌绘图 https docs google com drawings通过 A
  • docker 存储库名称组件必须匹配

    我正在尝试使用此插件构建我的图像 https github com spotify docker maven plugin use a dockerfile https github com spotify docker maven plu
  • 使用jetpack导航将自定义过渡动画添加到底部导航设置

    我正在开发一个使用 jetpack 组件的应用程序 我用三个片段缝合了底部导航 如guide https developer android com topic libraries architecture navigation navig
  • 来电时系统级别会发生什么?

    我已经从以下位置下载了 master 分支的完整源代码https android googlesource com platform frameworks base master https android googlesource com
  • 带有数学运算符的递归函数

    我想构建一个函数 它接受两个自然数 n 和 m 并返回以 n 开头并以 m 1 结尾的所有自然数的平方的元组 如果 m 小于 n 我能够决定函数是否应该返回 但它不应该崩溃或返回某种错误消息 因此 squares tuple 3 7 返回
  • 我如何解决 java2d 中的 ClassCastException(错误 ID 7172749)

    我很不幸遇到了 java8 的 bug 对于其他人来说这似乎不是什么大问题 因此 Oracle 不会在 java9 之前修复它 该错误有错误 ID 7172749 http bugs java com bugdatabase view bu
  • 跨源请求被阻止

    所以我有这个 Go http 处理程序 它将一些 POST 内容存储到数据存储中 并检索一些其他信息作为响应 在后端我使用 func handleMessageQueue w http ResponseWriter r http Reque
  • Django 表单 - 附加到类元排除和小部件

    是否可以附加到继承表单的排除或小部件变量 到目前为止我已经进行了以下设置 class AddPropertyForm forms ModelForm num months forms ChoiceField choices MONTHS r
  • Eclipse 中的 ScalaTest 运行配置:找不到 Suite 类

    问题 我无法设置运行配置来为项目中的 Scalatest 运行 scalatest 重现步骤 右键单击 Scala Suite 然后单击 运行方式 gt 运行配置 在左侧 我看到了 ScalaTest 的配置模板 我单击 新建 并填写名称但
  • 如何将分层数据数据绑定到 WPF TreeView?

    该类型如下所示 class Category public string Name public string Message public ObservableCollection
  • 升级到 android sdk tools 20/platform sdk tools 12 后无法再启动应用程序

    我升级了我的 sdk 工具 现在我无法再从 Eclipse 启动应用程序 我仍然可以从命令行安装 当我启动时 我收到一个错误窗口和一个空的设备选择器 错误窗口显示 An error has occurred See error log fo
  • Google 日历 - 找不到请求的活动

    我在 Google 日历中创建了活动 然后将其发布到网站上 作为 Google 日历中的 HTML 代码 活动网址 单击 URL 后 它会将我重定向到 Google 日历 其中包含以下文本 找不到请求的事件 应该是什么问题呢 我希望人们应该
  • 在预排序的 DataFrame 上使用 pandas groupby 进行迭代顺序

    情况 我根据特定列中的值使用特定分类器对 DataFrame 中的行进行分类 我的目标是根据特定条件将结果附加到一个新列或另一列 代码看起来像这样 df pd DataFrame A list with classifier ids Onl
  • Android,ArrayAdapter的add()函数不起作用

    我有一个附加到 AutoCompleteTextView textView 组件的 ArrayAdapter myAdapter 一旦用户按下一个字符 我想用包含该字符的项目填充 AutoCompleteTextView 的下拉列表 我使用
  • 了解汇编中的 JMP 代码

    我最近刚刚触及汇编语言和调试的表面 我有以下代码 Address Hex dump Command Comments 006E3689 E8 C5F9FFFF CALL 006E3053 gt 006E368E E9 DB E9 gt 00
  • 如何更有效地通过 http 下载大文件?

    我正在尝试在 Kotlin 中下载大文件 这个问题 除了我使用 Kotlin 而不是 java 语法略有不同 val client OkHttpClient val request Request Builder url urlString