首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在php中合并上传的文件块会导致文件损坏。

在php中合并上传的文件块会导致文件损坏。
EN

Stack Overflow用户
提问于 2022-01-09 14:27:12
回答 1查看 330关注 0票数 0

我正在我的应用程序中开发一个文件上传部分。客户端是Vue.js,后端是PHP。以Laravel作为我的框架。

我正在使用Blob.slice()在客户端分割所选的文件(我还尝试了FileReader Api,Resumablejs,现在正在进行自己的实现)。数据是使用xhr (尝试使用Axios,XMLHTTPRequest)发送的,每个“片”或“块”都有一个请求。我在后端获取数据并将传入的文件保存为"chunk1“、"chunk2”.诸若此类。在接收到最后一个块时,我使用PHP合并这些块。

我的问题是合并的文件以某种方式损坏了。mp4s -不可玩或不可寻觅,前任-腐败,一些前任做好事,但并非所有(它的不可预测),一些小的pdfs生存。

失败尝试

multipart/form-data

  1. 发送切片数据

--用存储保存块::put()或Storage::putFileAs() --用fopen保存块(文件,'wb‘或'ab'),fwrite(),fclose() --用file_put_contents保存块

  1. 用base64编码

发送切片数据

--保存已接收的块(base64编码),->使用base64_decode()读取每个块,同时将数据保存在新文件中-将接收到的所有块(base64编码)追加到一个文件中,->稍后创建一个新文件,解码该附加文件。(这是迄今为止最成功的一次尝试,但仍有一些文件被破坏,特别是前任)。

客户端代码..。

代码语言:javascript
复制
upload(file, start = 0, request = 0) {
        let chunkSize = 1024 * 1024 * 3;
        let end = (start + chunkSize) > file.fileObject.size ? file.fileObject.size : (start + chunkSize);
        let reader = new FileReader();
        let slice = file.fileObject.slice(start, end);

        reader.onload = (e) => {

            let data = {
                fileName: file.fileObject.name,
                chunkNumber: request + 1,
                totalChunks: Math.ceil(file.fileObject.size / chunkSize),
                chunk: reader.result.split(',')[1]
            }

            axios({
                url: '/api/admin/batch-sessions/'+ this.batchSessionId +'/files',
                method: 'POST',
                data: data,
                headers: {'Content-Type': 'application/json'}
            })
            .then(res => {
                start += chunkSize;
                request++;

                if (start <= file.fileObject.size) {
                    this.upload(file, start, request);
                }
            })
            .catch(err => {
                console.log(err.message);
            });
        }

        reader.readAsDataURL(slice);
    }

服务器端代码..。

代码语言:javascript
复制
public function handle()
{
    $chunks = Storage::disk('s3-upload-queue')
        ->files($this->directory);

    $mergedFile = Storage::disk('s3-upload-queue')->path($this->directory.'/'.basename($this->directory));
    $base64File = Storage::disk('s3-upload-queue')->path($this->directory.'/'.basename($this->directory).'.b64');

    $mfs = fopen($mergedFile, 'wb');
    $b64fs = fopen($base64File, 'r');

    fwrite($mfs, base64_decode(fread($b64fs, filesize($base64File))));

    fclose($mfs);
    fclose($b64fs);
}

实际上,我对不同的编码没有深入的了解,我在这里读到了关于base64在堆栈溢出上分块的内容,并试图创建大小的“片段”(1024 * 1024 * 3)。这是使用base64编码传输成功合并大多数文件的时候。但这也是不可预测的。有些文件仍然被损坏。我正试着正确地理解这一点。如果需要更多的信息,请告诉我。谢谢。

EN

回答 1

Stack Overflow用户

发布于 2022-10-28 12:04:35

代码语言:javascript
复制
chunk: reader.result.split(',')[1]

那是什么?您要删除base64前缀吗?它不存在于块中,所以您的块始终是空的,因为索引"1“中没有任何内容,因为字符串没有被拆分。

我也会使用这样的代码来获取blob:

代码语言:javascript
复制
let blob = file.slice(offset, length + offset);
file.fileReader.readAsBinaryString(blob);



file.fileReader.onload = async function() {
     let base64 = btoa(this.result)
   // Do whatever you want
}

关于腐败,你还想知道是否所有的块都发送成功了?您是否在服务器端,而不仅仅是在客户端保存块日志?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70642207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档