javascript - 数组缓冲区的文本导致文件损坏

标签 javascript html filereader

我有一个示例,用户可以从中选择一个文件(尤其是 PDF 文件),将该文件转换为数组缓冲区,从该数组缓冲区构造回文件并下载该文件。按预期工作。

<input type="file" id="file_input" class="foo" />
<div id="output_field" class="foo"></div>


$(document).ready(function(){
    $('#file_input').on('change', function(e){
        readFile(this.files[0], function(e) {
            //manipulate with result...
            $('#output_field').text(e.target.result);
            try {           
            var file = new Blob([e.target.result], { type: 'application/pdf' });
            var fileURL = window.URL.createObjectURL(file);
            var seconds = new Date().getTime() / 1000;
            var fileName = "cert" + parseInt(seconds) + ".pdf";
            var a = document.createElement("a");
            document.body.appendChild(a);
            a.style = "display: none";
            a.href = fileURL;
            a.download = fileName;
            a.click();
             }
            catch (err){
            $('#output_field').text(err);
            }
        });     
    });
});

function readFile(file, callback){
    var reader = new FileReader();
    reader.onload = callback
    reader.readAsArrayBuffer(file);
}

现在假设我使用的是 reader.readAsText(file); 而不是 reader.readAsArrayBuffer(file);。在那种情况下,我会将文本转换为数组缓冲区并尝试做同样的事情。

$(document).ready(function(){
    $('#file_input').on('change', function(e){
        readFile(this.files[0], function(e) {
            //manipulate with result...
            try {
            var buf = new ArrayBuffer(e.target.result.length * 2); 
            var bufView = new Uint16Array(buf);
            for (var i=0, strLen = e.target.result.length; i<strLen; i++) {
                     bufView[i] = e.target.result.charCodeAt(i);
            }

            var file = new Blob([bufView], { type: 'application/pdf' });
            var fileURL = window.URL.createObjectURL(file);
            var seconds = new Date().getTime() / 1000;
            var fileName = "cert" + parseInt(seconds) + ".pdf";
            var a = document.createElement("a");
            document.body.appendChild(a);
            a.style = "display: none";
            a.href = fileURL;
            a.download = fileName;
            a.click();
             }
            catch (err){
            $('#output_field').text(err);
            }
        });

    });
});

function readFile(file, callback){
    var reader = new FileReader();
    reader.onload = callback
    reader.readAsText(file);
}

Now if I passed a PDF file that is small in size and only has text, this would work file, but when selecting files that are large and/or has images in them, a currputed file will be downloaded.

现在我知道我正在努力让自己的生活更艰难。但我想做的是以某种方式将 readAsText() 的结果转换为 arrayBuffer,以便 readAsText()readAsArrayBuffer() 工作相同。

最佳答案

readAsText method不只是使字节在 UCS-16 字符串中可访问。相反,它根据给定的文本编码格式(默认为 UTF-8)将它们解码为文本。这会弄乱您尝试读取的任何二进制数据。正如您已经想到的那样,为此使用 readAsArrayBuffer

您可以尝试使用TextEncoderencode您的文本返回到类型化数组,但这并不能保证产生相同的结果:BOM 被剥离,无效的 UTF-8 序列导致错误,如果您不走运,那么甚至会发生 Unicode 规范化。

如果您明确指定单字节解码可能会更容易,但实际上您应该只使用 readAsArrayBuffer

关于javascript - 数组缓冲区的文本导致文件损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55691669/

相关文章:

javascript - 将方法作为参数传递的不同语法?

java - 为什么 FileWriter 有 write(String) 却没有 FileReader.read(String)

javascript - FileReader+canvas图片加载问题

javascript - 检查子属性是否存在的更简洁的方法

javascript - 使用类的 Vue 实例

javascript - 加载页面时显示重新加载框的灯箱

html - 通过包装不滚动条在 DIV 中溢出

html - 防止网格在 flex 盒内溢出

javascript - 相对容器的 Chrome native 拖放不正确渲染重影

Jenkins 参数化构建不创建文件