android - 从 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
解决方案
“我可以使用 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)
推荐阅读
- python - 我需要一种方法来循环将自定义对象添加到文件中
- angular - 将主机和 ComponentResolver 从 AngularDart 4 迁移到 5
- java - 我可以只连接一次wifi吗?
- android - 每次从其他活动开始时,如何停止创建活动?
- java - 如何使用 JUnit 5 测试调用 Instant.now() 的代码?
- android - 如何在android中添加多色ProgressBar
- inheritance - kotlin 类扩展在列表上下文中使用时解析父类的值而不是子类
- java - 需要在集成测试用例中模拟 bean
- javascript - 尝试设置变量时返回未定义的函数
- angular - 启用 Ivy 的 Angular 8 - @swimlane/ngx-datatable 抛出入口点错误