Суффикс Python mkstemp
У меня есть следующий фрагмент кода, который обрабатывает загрузку изображений для меня в проекте Django, над которым я работаю:
def upload_handler(source):
fd, filepath = tempfile.mkstemp(prefix=source.name, dir=MEDIA_ROOT)
with open(filepath, 'wb') as dest:
shutil.copyfileobj(source, dest)
return MEDIA_URL + basename(dest.name)
Все нормально работает с частью загрузки, но mkstemp сохраняет мое изображение с дополнительными 6 случайными суффиксами после расширения (например, test.png -> test.pngbFVeyh). Даже если я передам суффикс во второй строке кода, он добавляет его, но также и дополнительные 6 случайных символов. Другая странная вещь в том, что в папке загрузки (в моем случае MEDIA_ROOT) она создается вместе с другим пустым файлом с типом документа в формате обычного текста с тем же именем, что и изображение (например, test.pngbFVeyh). Я прочитал документацию по mkstemp, но не нашел альтернативного решения.
2 ответа
Имя генерируется случайным образом, потому что это цель tempfile.mkstemp
, Файл с таким именем создан, потому что это как tempfile.mkstemp
работает. Он также открывается и дескриптор файла возвращается вам в fd
которую ты игнорируешь. Вы, кажется, не понимаете, как tempfile.mkstemp
следует использовать, и вам, вероятно, нужно использовать что-то другое вместо этого.
def upload_handler(source):
# this is creating a temp file and returning an os handle and name
fd, filepath = tempfile.mkstemp(prefix=source.name, dir=MEDIA_ROOT)
# this next line just clears the file you just made (which is already empty)
with open(filepath, 'wb') as dest:
# this is a strange way to get a fobj to copy :)
shutil.copyfileobj(source, dest)
return MEDIA_URL + basename(dest.name)
префикс и суффикс делают именно это, поэтому, если вы не хотите, чтобы ваше имя файла начиналось или заканчивалось временными символами, вам нужно использовать как префикс, так и суффикс. Например,
name = os.path.basename(source.name)
prefix, suffix = os.path.splitext(name)
_, filepath = tempfile.mkstemp(prefix=prefix, suffix=suffix, dir=MEDIA_ROOT)
но было бы лучше, если вы используете tempfile.NamedTemporaryFile
, а затем возвращается файлоподобный объект (поэтому вам не нужно создавать fobj из имени файла, а временный файл удаляется по умолчанию, когда закончите).
fobj, _ = tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix, dir=MEDIA_ROOT)
shutil.copyfileobj(source, fobj)