前端使用vue-simple-uploader上传大文件,用异步aiofiles保存文件不完整,原生写没问题。

来源:11-5 通过aiofiles保存图片文件-2

慕UI9336467

2020-10-14

图片描述

46.1Mb 的文件 传过去只有34Mb,用同步写入文件是完整的,问下老师这应该怎么解决啊
后端代码:

# demo.py
from sanic import Sanic
from sanic.response import json
import aiofiles

app = Sanic(__name__)

@app.route("/")
async def test(request):
    return json({"hello": "world"})
    
@app.post('/upload')
async def upload(request):
    # 获取文件信息
    upfile = request.files.get('file',None)
    filename = upfile.name
    filetype = upfile.type
    fileBody = upfile.body
    # 同步写入 文件完整可行
    #with open(f"./img/{filename}", 'ab+') as fp:
        #fp.write(fileBody)
    # 异步写入 文件不完整
    async with aiofiles.open(f"./img/{fileName}", 'ab+') as fp:
        await fp.write(fileBody)
    return json({"status":'success'})
    
if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8000)

前端代码:
npm install vue-simple-uploader -S

main.js:

import uploader from "vue-simple-uploader";
Vue.use(uploader)

App.vue:

<template>
	<div id="app">
		<h1>hello vue.js app </h1>
		<uploader :options="options" class="uploader-example">
			<uploader-unsupport></uploader-unsupport>
			<uploader-drop>
				<p>拖动文件到此处上传</p>
				<uploader-btn>选择文件</uploader-btn>
				<uploader-btn :attrs="attrs">选择图片</uploader-btn>
				<uploader-btn :directory="true">选择文件夹</uploader-btn>
			</uploader-drop>
			<uploader-list></uploader-list>
		</uploader>
	</div>
</template>

<script>
  export default {
    name: "App",
    data () {
      return {
        options: {
          target: '//localhost:8000/upload',
          testChunks: false
        },
        attrs: {
          accept: 'image/*'
        }
      }
    }
  }
</script>

<style scoped lang="css">
	.uploader-example {
		width: 880px;
		padding: 15px;
		margin: 40px auto 0;
		font-size: 12px;
		box-shadow: 0 0 10px rgba(0, 0, 0, .4);
	}
	.uploader-example .uploader-btn {
		margin-right: 4px;
	}
	.uploader-example .uploader-list {
		max-height: 440px;
		overflow: auto;
		overflow-x: hidden;
		overflow-y: auto;
	}
</style>

写回答

2回答

慕UI9336467

提问者

2020-10-15

这样应该是最好的了。

0
0

慕UI9336467

提问者

2020-10-15

@app.post('/upload')
async def upload (request):
    # 获取文件信息
    upfile = request.files.get('file',None)
    fileName = upfile.name
    fileType = upfile.type
    fileBody = upfile.body

    chunkNumber = int(request.form.get('chunkNumber',None))           # 当前块数
    chunkSize =int(request.form.get('chunkSize',None))                # 每块大小
    currentChunkSize =int(request.form.get('currentChunkSize',None))  # 当前块大小 (最后一块大小不一)
    totalSize = int(request.form.get('totalSize',None))               # 文件总大小
    totalChunks = int(request.form.get('totalChunks',None))           # 文件总块数

    fd = os.open(f"./img/{fileName}", os.O_WRONLY|os.O_BINARY|os.O_CREAT)
    if(chunkNumber == totalChunks):
        pos = totalSize - currentChunkSize
    else:
        pos = (chunkNumber-1)*currentChunkSize
    os.lseek(fd, pos, os.SEEK_SET)
    os.write(fd,fileBody)
    if(chunkNumber == totalChunks):
        os.close(fd)

    return response.json({ "status":'success' })


0
3
bobby
回复
慕UI9336467
使用lseek会造成这个问题?
2020-10-23
共3条回复

Tornado从入门到进阶 打造支持高并发的技术论坛

异步IO并发编程/Form,ORM/aiomysql、peewee-async/epoll

593 学习 · 350 问题

查看课程