问题描述
在XML文件中,我们有一个表示PDF文件的base64编码的字符串,其中包含一些表表示形式,即类似于this example。在解码该PDF文档(即such as this)的base64字符串时,我们最终得到一个大小为66 kB的PDF文档,可以在任何PDF查看器中正确打开该文件。
在尝试使用TypeScript中的Buffer
(在VSCode扩展名之内),即使用以下函数解码相同的base64编码的字符串时:
function decodeBase64(base64String: string): string {
const buf: Buffer = Buffer.from(base64String,"base64");
return buf.toString();
}
// the base64 encoded string is usually extracted from an XML file directly
// for testing purposes we load that base64 encoded string from a local file
const base64Enc: string = fs.readFileSync(".../base64Enc.txt","ascii");
const base64Decoded: string = decodeBase64(base64Enc);
fs.writeFileSync(".../table.pdf",base64Decoded);
我们最终得到了109 kB的PDF,并且该文档无法使用PDF查看器打开。
对于简单的PDF(例如this one),以base64编码的字符串表示形式(例如this),上面的代码有效,并且可以在任何PDF查看器中读取PDF。
我还尝试使用以下方法直接读取PDF文件的本地存储的base64编码表示形式
const buffer: string | Buffer = fs.readFileSync(".../base64Enc.txt","base64");
尽管也不能产生有用的东西。
由于atob(...)
不存在(用this suggestion将atob
替换为Buffer),即使对suggestions进行了小幅修改,其结果仍类似于这个:
const buffer: string = fs.readFileSync(".../base64Enc.txt","ascii");
// atob(...) is not present,other answers suggest to use Buffer for conversion
const binary: string = Buffer.from(buffer,'base64').toString();
const arrayBuffer: ArrayBuffer = new ArrayBuffer(binary.length);
const uintArray: Uint8Array = new Uint8Array(arrayBuffer);
for (let i: number = 0; i < binary.length; i++) {
uintArray[i] = binary.charCodeAt(i);
}
const decoded: string = Buffer.from(uintArray.buffer).toString();
fs.writeFileSync(".../table.pdf",decoded);
我并没有以可读的PDF结尾。经过“解码”的table.pdf
示例的大小为109 kB。
我在这里做错了什么?与Notepad ++提供的功能类似,如何解码诸如table.pdf示例之类的PDF以获取可读的PDF文档?
解决方法
如果您使用Uint8Array
构造函数从Buffer
获得了Uint8Array
,就从How to get an array from ArrayBuffer?的答案中大量借用:
const buffer: string = fs.readFileSync(".../base64Enc.txt","ascii");
const uintArray: Uint8Array = new Uint8Array(Buffer.from(buffer,'base64'));
fs.writeFileSync(".../table.pdf",uintArray);
将Uint8Array
直接写入文件可确保不会因字符串之间的编码更改而损坏。
请注意:
Uint8Array
指向与Buffer
相同的内部字节数组。在这种情况下,这并不重要,因为此代码未在构造函数之外引用Buffer
,但是如果有人决定为Buffer.from(buffer,'base64')
的输出创建一个新变量。