从 Base64 中的给定 URI 将 Dropbox 上的 PDF 下载到 phone 会产生损坏的不可读 PDF
Downloading a PDF on Dropbox to a phone from a given URI in Base64 gives broken unreadable PDF
我从不同的来源(本地 phone、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)
所有文本内容(片段):
%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
This is my URI:
那不是文件。
val file = File(uri)
这不是您使用 Uri
的方式。使用 ContentResolver
和 openInputStream()
在 Uri
.
标识的内容上获得 InputStream
请注意,阅读全部内容,更不用说在内存中转换为Base64,可能会导致您遇到OutOfMemoryErrors
。
"I can read a byte array using the URI as input. But the PDF that I'm getting is not a valid PDF."
"When storing the allText
content with .PDF extension doesn't work."
您正在读取 PDF 输入字节(十六进制)并将它们存储为错误的格式(文本)。
例如,所有有效的 PDF 文件都应以字节 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 is also not correct."
(选项 1)
尝试将上面示例代码中的 hexString
转换为 Base64(注意:现在添加为 val base64
)。
(选项 2)
使用简单的方法直接将文件字节读入 Base64 字符串...
val bytes = File(filePath).readBytes()
val base64 = Base64.getEncoder().encodeToString(bytes)
我从不同的来源(本地 phone、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)
所有文本内容(片段):
%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
This is my URI:
那不是文件。
val file = File(uri)
这不是您使用 Uri
的方式。使用 ContentResolver
和 openInputStream()
在 Uri
.
InputStream
请注意,阅读全部内容,更不用说在内存中转换为Base64,可能会导致您遇到OutOfMemoryErrors
。
"I can read a byte array using the URI as input. But the PDF that I'm getting is not a valid PDF."
"When storing the
allText
content with .PDF extension doesn't work."
您正在读取 PDF 输入字节(十六进制)并将它们存储为错误的格式(文本)。
例如,所有有效的 PDF 文件都应以字节 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 is also not correct."
(选项 1)
尝试将上面示例代码中的 hexString
转换为 Base64(注意:现在添加为 val base64
)。
(选项 2)
使用简单的方法直接将文件字节读入 Base64 字符串...
val bytes = File(filePath).readBytes()
val base64 = Base64.getEncoder().encodeToString(bytes)