Найти - Пользователи
Полная версия: загрузка файлов из html-формы в mod_python
Начало » Web » загрузка файлов из html-формы в mod_python
1
axe
Получаю данные в mod_python с помощью util.FieldStorage(req, True):
    req_data = FieldStorage(req, True, file_callback=Storage) ## про file_callback напишу ниже
args = {}
for field in req_data.list:
args[field.name] = field.value
Если из формы был отправлен файл, то в соответствующей переменной args будет находится строка с содержимым файла.

В документации пишут, что если пришёл файл, то можно использовать file_callback=Storage, где Storage - это класс, который будет управлять созданием файла. Немного изменил код из примера:
class Storage(file):
def __init__(self, advisory_filename):
self.advisory_filename = advisory_filename
self.delete_on_close = False ## чтобы файл не создавался
self.already_deleted = False
self.real_filename = '/tmp/www/dev_python/' + advisory_filename ## тут указывают директорию, куда класть файл
file.__init__(self, self.real_filename, 'w+b')

def close(self):
if self.already_deleted:
raise Exception()
super(Storage, self).close()
if self.delete_on_close:
self.already_deleted = True
os.remove(self.real_filename)
Временный файл создаётся в указанной папке, но не понятно, как получить ссылку на созданный объект и как сделать, чтобы строка, содержащая текст файла, не создавалась в args. Думаю, что загрузка лишних 3-5Mb в оперативку это не дело.
axe
Нашёл ссылку на объект типа файл:
        for field in req_data.list:
if field.name == 'myFile':
print type(field.file)
print dir(field.file)
использование класса Storage - опционально. Без него тип получается просто <file>. Но тогда неясно, где храниться этот временный файл.
dimabest
axe
Но тогда неясно, где храниться этот временный файл
зачем тебе знать где хранится файл, если он временный?
axe
Мм. Не совсем то я сказал. Для начала мне надо получить имя файла, а не путь, где он храниться.
Можно ли узнать имя загружаемого файла без использования file_callback?

По идее у файла есть поле file.name, но там вместо имени оказывается строка “<fdopen>”, и это не имя загружаемого файла.
А если использовать Storage, то имя файла получается определено, но файл получается не совсем временный.
dimabest
axe
Можно ли узнать имя загружаемого файла без использования file_callback?
да.

data = FieldStorage(req)

print data['field_name'].filename
axe
Да, действительно имя файла есть. Спасибо.
Но всё-таки важно, действительно ли этот файл создаётся где-то.

Я попробовал поставить на закачку файл в 200 метров. При загрузке файла используемая оперативная память сервера увеличилась чуть ли не на 500 метров. После того, как процесс загрузки закончился, память снова вернулась к исходному состоянию.
Причём не влияет, использую ли я Storage или нет.

Можно ли отключить загрузку файла в оперативку?
axe
чтобы вместо 500 метров получилось всё-таки 200 (с чем-то), добавил проверку:
    args = {}
for field in req_data.list:
if type(field.file) is not file: ## если файл
args[field.name] = field.value
иначе field.value это строка, содержимое которой есть содержимое файла.
dimabest
FieldStorage читает файлы из stdin порциями по “bufsize = 8*1024 # I/O buffering size for copy to file” и, по умолчанию, сразу записывает в tempfile. Имя файла на компьютере пользователя доступно через data.filename, ссылка на файл доступна через data.file (если надо содержимое временного файла сохранить на диск - читай также порциями data.file.read(chunk_size)). Как только ты обращаешься к атрибуту value - файл из temp-а целиком считывается в оперативку, поэтому для больших файлов так data.value делать не надо.

value - это не строка. В классе FieldStorage обращение к несуществующим атрибутам объекта перехватывается методом __getattr__. Только когда ты дергаешь в своем коде value - данные читаются из temp-файла и отдается строка, никак не раньше.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB