2013-04-02 13 views
10

chcę uzyskać rozmiaru przesyłania obrazu do kontroli, jeśli jest większa niż max pliku przesłać limit.I próbował tego:Kolba: Get wielkość request.files sprzeciw

@app.route("/new/photo",methods=["POST"]) 
def newPhoto(): 

    form_photo = request.files['post-photo'] 
    print form_photo.content_length 

on wydrukowany 0 Gdzie Czy robię źle? Czy powinienem znaleźć rozmiar tego obrazu ze ścieżki tymczasowej? Czy w Pythonie nie ma czegoś takiego jak PHP $_FILES['foo']['size']?

Odpowiedz

17

Istnieje kilka rzeczy, aby mieć świadomość tutaj - własność CONTENT_LENGTH będzie długość treść Prześlij plik jako zgłaszane przez przeglądarkę, ale niestety wiele przeglądarek nie wysyła tego, jak odnotowano w docs i source.

Co do Twojego TypeError, następnym krokiem jest to, że pliki przesłane poniżej 500 KB są przechowywane w pamięci jako StringIO object, a nie buforowane na dysku (zobacz te dokumenty ponownie), więc twoje wywołanie statystyk nie powiedzie się.

MAX_CONTENT_LENGTH to poprawny sposób odrzucania przesyłania plików większych niż jest to potrzebne, a jeśli jest to potrzebne, jedynym niezawodnym sposobem określenia długości danych jest wykrycie tego po obsłużeniu przesłania - albo stat plik po .save() D to:

request.files['file'].save('/tmp/foo') 
size = os.stat('/tmp/foo').st_size 

Lub jeśli nie używasz dysku (na przykład przechowywanie go w bazie danych), policz bajty czytałeś:

blob = request.files['file'].read() 
size = len(blob) 

Chociaż oczywiście uważaj, nie czytaj za dużo d ATA do pamięci, jeśli MAX_CONTENT_LENGTH jest bardzo duża

+0

OK dziękuję za odpowiedź – saidozcan

+1

nie jest http://stackoverflow.com/a/23601025/125507 lepszy? po prostu szukaj do końca pliku i nie korzystasz z pamięci? – endolith

8

Właściwym sposobem ustawienia limitu maksymalnego wysyłania plików jest konfiguracja aplikacji MAX_CONTENT_LENGTH. Na przykład, jeśli chcesz ustawić limit wysyłania 16 megabajtów, należy wykonać następujące czynności w celu konfiguracji aplikacji:

app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 

Jeśli Przesłany plik jest zbyt duży, Kolba automatycznie powróci kod statusu 413 Zamówienie Entity Too Duży - należy to zrobić po stronie klienta.

+1

Ok, to jest to dobry sposób. Nadal nie ma żadnego sposobu na uzyskanie rozmiaru obrazu? – saidozcan

+0

jest to dobre, chyba że system znajduje się na małym dysku i chcesz, aby użytkownik przesłał dowolny rozmiar pliku, chyba że przekracza wolną przestrzeń. w takim przypadku użyj pliku.seek() zasugerował Steely Wing – andrei

1

Jak ktoś już zasugerował, należy użyć

app.config['MAX_CONTENT_LENGTH'] 

ograniczyć rozmiary plików. Ale Ponieważ specjalnie chcą dowiedzieć rozmiar obrazu, można zrobić:

import os 
photo_size = os.stat(request.files['post-photo']).st_size 
print photo_size 
+3

Teraz mówi TypeError: wymuszając na Unicode: potrzebujesz łańcucha lub bufora, znaleziono FileStorage. Co powinienem zrobić? – saidozcan

+0

'request.files' nie zawiera ścieżek. – ThiefMaster

10

Jeśli nie chcesz zapisać plik na dysk, po pierwsze, należy użyć następującego kodu, to prace nad strumieniem w pamięci

import os 

file = request.files['file'] 
file.seek(0, os.SEEK_END) 
file_length = file.tell() 

inaczej, to będzie lepiej

request.files['file'].save('/tmp/file') 
file_length = os.stat('/tmp/file').st_size 
+0

'plik.seek (0, 2)' powinien zrobić to samo bez importowania 'os'? http://stackoverflow.com/a/283719/125507 seek na 0 bajtów od końca pliku – endolith

2

Poniższy fragment kodu powinien spełniać swój cel ..

 

form_photo.seek(0,2) 
size = form_photo.tell()