在 js 中读取文件会损坏文件

在 js 中我正在运行这段代码


let str = new TextDecoder("utf8").decode(new Uint8Array(reader.result));


let data = {

    name:file.name,

    size: args.loaded,

    contentsize:str.length,

    type:file.type,

    content:str

};

let res = await $.post({

    url:"/api/files",

    data:JSON.stringify(data),

    processData: false,

    contentType: "application/json",

})

reader.result 的输出


reader.readAsArrayBuffer(file);

然后在 php 中获取


$new["actual"] =strlen($new["content"]);

$new["content"] = new MongoDB\BSON\Binary($new["content"] ,MongoDB\BSON\Binary::TYPE_GENERIC);

$result = IO::$db->files->insertOne($new);

然后会产生一个数据库文档


    "name" : "test.pdf", 

    "size" : NumberInt(128454), 

    "contentsize" : NumberInt(122693), 

    "type" : "application/pdf", 

    "actual" : NumberInt(215693)

}

但是,当我将文件内容删除回文件系统时,文件已损坏并且无法打开。我已经运行了 VSCode 附带的文件比较器,并说数据库内容和原始内容之间有 0 差异,所以我只能认为问题在于文件大小和读取内容的 3kb 差异,但是什么或者为什么我无法逃脱


注意似乎只是二进制文件


繁星淼淼
浏览 93回答 2
2回答

天涯尽头无女友

您的示例是 PDF 文件。PDF 文件不是文本文件,不应作为文本文件处理。如果更改行结尾,这将更改文件中不同对象的偏移量,从而损坏 PDF 文件。更糟糕的是,如果 PDF 文件中存在二进制流(例如字体、图像等),则会破坏流的内容,并可能导致无法对其进行解码。要解决此问题,请确保将 PDF 文件作为二进制文件进行读取和写入。

拉丁的传说

好的,UTF-8 规范并不包含字节数据范围内所有位代码的字符,其他语言(例如 PHP)通过添加完成字节代码映射的特殊非 UTF-8 字符来解决此问题,但事实并非如此在 JavaScript 中所以这是 JavaScript 的限制,它不会告诉你它已经命中了一个字节码,它无法反序列化,这会突出显示发生了问题,它只是跳过该字节并移动到下一个字节,从而破坏了你的数据并隐藏腐败发生的原因。这意味着您不能在 JavaScript 中使用 UTF-8 编码器对包含不支持的字节码之一的任何内容进行编码,要解决此问题,可以选择将字节转换为十六进制字符串,然后使用它来解码在服务器端进行序列化,这会导致一定程度的数据膨胀,因为您使用 2 个字节发送一个字节(尽管这比尝试对字节数组进行编码要少得多),但由于 2 个字母的十六进制字符串映射所有字节范围值意味着二进制数据不会损坏,并且可以安全地用于基于文本的数据序列化(例如通过 JavaScript 的 JSON)
打开App,查看更多内容
随时随地看视频慕课网APP