Web2Py — загрузите файл и прочитайте содержимое в виде Zip-файла.

Я пытаюсь загрузить zip-файл из формы Web2Py, а затем прочитать содержимое:

form = FORM(TABLE(
           TR(TD('Upload File:', INPUT(_type='file', 
                                       _name='myfile', 
                                       id='myfile', 
                                       requires=IS_NOT_EMPTY()))), 
           TR(TD(INPUT(_type='submit',_value='Submit')))
       ))

if form.accepts(request.vars):  
    data=StringIO.StringIO(request.vars.myfile)  
    import zipfile  
    zfile=zipfile.Zipfile(data)

По какой-то причине этот код работает и жалуется, что файл не является zip-файлом, хотя загруженный файл является zip-файлом.

Я новичок в Web2Py. Как можно представить data в виде zip-файла?


person jitendra    schedule 20.06.2011    source источник


Ответы (2)


Загрузка полей формы web2py уже является cgi.FieldStorage, вы можете получить необработанные загруженные байты, используя:

data = request.vars.myfile.value

Для файлового объекта StringIO не нужен, используйте:

filelike = request.vars.myfile.file
zip = zipfile.Zipfile(filelike)
person reingart    schedule 15.09.2011

Загрузки HTTP — это не просто необработанные двоичные файлы, они закодированы в смешанной многокомпонентной форме. Запишите request.vars.myfile на диск, и вы увидите, что он скажет что-то вроде

------------------BlahBlahBoundary
Content-Disposition: type="file"; name="myfile"
Content-Type: application/octet-stream

<binary data>
------------------BlahBlahBoundary--

Наивным решением для этого является использование cgi.FieldStorage(), в примере, который я привожу, используется wsgi.input, который является частью mod_wsgi.

form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
raw_filw = cStringIO.StringIO(form['myfile'].file.read())

Здесь следует отметить две вещи

  • Всегда используйте cStringIO, если он у вас есть, это будет быстрее, чем StringIO

  • Если вы разрешаете такие загрузки, вы передаете файл в оперативную память, поэтому, каким бы большим ни был файл, сколько оперативной памяти вы будете использовать - это НЕ масштабируется. Чтобы избежать этого, мне пришлось написать собственный пользовательский анализатор потока MIME для потоковой передачи файлов на диск через python. Но, если вы учитесь или это доказательство концепции, вы должны быть в порядке.

person synthesizerpatel    schedule 20.06.2011
comment
Спасибо за решение. Проблема в том, что сейчас я работаю над тестированием сервера и не использую wsgi, что усложняет задачу. - person jitendra; 20.06.2011
comment
wsgi.input — это просто дескриптор файла в сокете вашего сообщения. Вместо wsgi.input используйте request.vars.myfile - person synthesizerpatel; 20.06.2011