首页 > 解决方案 > 从 Base64 中的给定 URI 将 Dropbox 上的 PDF 下载到手机会导致损坏的无法读取的 PDF

问题描述

我从不同的来源(电话本地、Google 驱动器等)获取 PDF 的 URI,对于 Dropbox,我可以使用 URI 作为输入来读取字节数组。但我得到的 PDF 不是有效的 PDF。Base64 也不正确。

这是我的 URI:

内容://com.dropbox.android.FileCache/filecache/a54cc030-e2e0-4ef5-8e72-0ac3269a16e1

val inputStream = context.contentResolver.openInputStream(Uri.parse(uri))
val allText = inputStream.bufferedReader().use(BufferedReader::readText)
val base64Image = Base64.encodeToString(allText.toByteArray(), Base64.DEFAULT)

allText 内容(片段):

%PDF-1.3
%���������
4 0 obj
<< /Length 5 0 R /Filter /FlateDecode >>
.
.
.
13025
%%EOF

使用 .PDF 扩展名存储 allText 内容时不起作用。

格式看起来不错,但是在https://base64.guru/converter/decode/pdf中插入 base64Image 时,它​​显示它不正确。

原始 PDF 内容(片段):

2550 4446 2d31 2e33 0a25 c4e5 f2e5 eba7
f3a0 d0c4 c60a 3420 3020 6f62 6a0a 3c3c
.
.
.
.
0a73 7461 7274 7872 6566 0a31 3330 3235
0a25 2545 4f46 0a

标签: androiddropbox

解决方案


  • “我可以使用 URI 作为输入来读取字节数组。但我得到的 PDF 不是有效的 PDF。”

  • “使用 .PDF 扩展名存储allText内容时不起作用。”

您正在阅读 PDF 输入字节(十六进制)并将它们存储为错误的格式(文本)。
例如,所有有效的 PDF 文件都应该以 bytes 开头25 50 44 46。您的allText内容片段以%PDF这些字节的转换后的 ASCII/UTF 文本表示开头。

问题:
这一切都很好,因为我们可以将文本字符转换回它们各自的字节值,对吧?不,并非所有字节值都可以从文本格式中正确恢复。

示例#1:可以转换...

input bytes : 25 50 44 46
as text     : %  P  D  F
into bytes  : 25 50 44 46

示例 #2:无法转换(原始数据无法恢复,因为此类字节没有文本字符)...

input bytes : 25 C4 E5 F2 E5 EB A7 F3 A0 D0
as text     : %  � � � �  � � � � � 
into bytes  : 25 00 00 00 00 00 00 00 00 00

解决方案:

试试下面的东西。您想要代码注释中解释的逻辑......

import java.io.File
import java.io.InputStream

fun main(args: Array<String>) 
{
    //# setup access to your file...
    var inFile :InputStream = File("your-file-path-here.pdf")
    var fileSize :Int = File(path).length()

    //# read file bytes into a bytes Array...
    var inStream :InputStream = inFile.inputStream()
    var inBytes :ByteArray = inStream.readBytes()

    //# Make as String (of hex values)...
    //var hexString :String = ""
    val hexString = ""
    for (b in inBytes) { hexString = String.format("%02X", b) }

    //# check values as hex... should print: 25 
    //print(hexString) //could be long print-out for a big file

    //# Make Base64 string...
    val base64 = Base64.getEncoder().encodeToString(inBytes)
}

“Base64 也不正确。”

(选项1)

尝试将hexString上面示例代码中的转换为 Base64(注意:现在添加为val base64)。

(选项 2)

使用简单的...直接将文件字节读入 Base64 字符串

val bytes = File(filePath).readBytes()
val base64 = Base64.getEncoder().encodeToString(bytes)

推荐阅读