Я получаю URI PDF из разных источников (локально на телефоне, Google Диске и т.д.), А для Dropbox я могу прочитать байтовый массив, используя URI в качестве входных данных. Но полученный мной 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
При сохранении контента allText с расширением .PDF не работает.
Формат выглядит хорошо, но при вставке base64Image в https://base64.guru/converter/decode/pdf он показывает, что это не правильно.
Оригинальное содержание 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".
"При хранении контента
allText
с расширением .PDF не работает".
Вы читаете входные байты PDF (в шестнадцатеричном формате) и сохраняете их в неправильном формате (текст).
Например, все допустимые файлы PDF должны начинаться с байтов 25 50 44 46
. Ваш allText
контента 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)
Попробуйте преобразовать в Base64 hexString
в приведенном выше примере кода (примечание: теперь добавлено как val base64
).
(вариант 2)
Непосредственно читать байты файла в строку Base64 с помощью простого...
val bytes = File(filePath).readBytes()
val base64 = Base64.getEncoder().encodeToString(bytes)
Это мой URI:
Это не файл.
val file = File(uri)
Это не то, как вы используете Uri
. Используйте ContentResolver
и openInputStream()
чтобы получить InputStream
для содержимого, идентифицированного Uri
.
Обратите внимание, что чтение всего содержимого, не говоря уже о преобразовании его в Base64 в памяти, может привести к OutOfMemoryErrors
.
BufferedReader::readText
. Читайте в байтах .