如何从文件的URI获取base64?

5

通常情况下,我的任务是从选择的文件中获取base64。为了打开文件浏览器,我调用以下函数:

Original Answer翻译成"最初的回答"

private fun showFileBrowser() {
    val intent = Intent(Intent.ACTION_GET_CONTENT)
    intent.setType("*/*")
    startActivityForResult(intent, FILE_CHOOSE_REQUEST_CODE)
}

它已成功打开。选择文件后,将调用onActivityResult。以下是代码:
最初的回答:成功打开。当选择某个文件时,将调用onActivityResult。以下是代码:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (requestCode == FILE_CHOOSE_REQUEST_CODE) {
        // not that data.data is Uri
        if(data != null && data.data != null) {
            val encodedBase64 = getBase64FromPath(data.data.path)
            print(encodedBase64)
        }


    }

}

这是我将文件转换为base64的方法:
 private fun getBase64FromPath(path: String): String {

    try {
        val bytes = File(path).readBytes()

        return Base64.encodeToString(bytes, Base64.DEFAULT)
    } catch (error: IOException) {
        error.printStackTrace() // This exception always occurs 
    }

}

看起来我做的一切都是正确的,但是我得到了FileNotFoundException。我不知道这是什么原因。我没有添加任何权限,因为我不想写任何东西到scared,我只想让用户选择一个文件,然后将其转换为base64并发送到服务器。那么,我的代码有什么问题呢?

最初的回答:

您需要添加读取文件的权限,否则您将无法访问用户选择的文件。在AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
1个回答

4
我的任务是从所选文件获取base64。
您的代码与文件关系不大。ACTION_GET_CONTENT不仅限于设备上的文件,更不用说您可以访问的文件系统上的文件了。
当选择某个文件时,将调用onActivityResult。
通过onActivityResult()获取Uri。 Uri不是文件,如果该Uri的方案为file,则Uri上的getPath()只有意义。大多数Uri值将具有content方案。
请使用以下功能替换您的功能:
"最初的回答"
private fun getBase64ForUriAndPossiblyCrash(uri: Uri): String {

    try {
        val bytes = contentResolver.openInputStream(uri).readBytes()

        return Base64.encodeToString(bytes, Base64.DEFAULT)
    } catch (error: IOException) {
        error.printStackTrace() // This exception always occurs 
    }

该函数名中的“AndPossiblyCrash”部分是因为如果内容太大,你将会耗尽内存。同时请注意,您正在主应用程序线程上执行此操作,因此在读取时您的UI将被冻结。"最初的回答"

你在解决方案中使用了contentResolver。问题是为什么需要它?例如,上面的答案避免使用它。 - neo
@neo:好的,另一个答案是针对文件的。正如我所写的,Uri 不是文件。ContentResolver 及其 openInputStream() 方法可以处理 filecontent 类型的 Uri 值,而你有一个 content 类型的 Uri - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接