Подтвердить что ты не робот

Как перенести на диск временный файл с помощью Python?

Я пытаюсь использовать модуль tempfile для управления и создания текстовых файлов. Когда файл будет готов, я хочу сохранить его на диск. Я думал, что это будет так же просто, как использовать "shutil.copy". Тем не менее, я получаю "разрешение отклонено" IOError:

>>> import tempfile, shutil
>>> f = tempfile.TemporaryFile(mode ='w+t')
>>> f.write('foo')
>>> shutil.copy(f.name, 'bar.txt')

Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    shutil.copy(f.name, 'bar.txt')
  File "C:\Python25\lib\shutil.py", line 80, in copy
    copyfile(src, dst)
  File "C:\Python25\lib\shutil.py", line 46, in copyfile
    fsrc = open(src, 'rb')
IOError: [Errno 13] Permission denied: 'c:\\docume~1\\me\\locals~1\\temp\\tmpvqq3go'
>>> 

Разве это не предназначено при использовании библиотеки tempfile? Есть лучший способ сделать это? (Возможно, я пропускаю что-то очень тривиальное)

4b9b3361

Ответ 1

Файл, созданный с помощью TemporaryFile или NamedTemporaryFile, автоматически удаляется, когда он закрывается, поэтому вы получаете сообщение об ошибке. Если вы этого не хотите, вы можете использовать mkstemp вместо этого (см. Документы для tempfile).

>>> import tempfile, shutil, os
>>> fd, path = tempfile.mkstemp()
>>> os.write(fd, 'foo')
>>> os.close(fd)
>>> shutil.copy(path, 'bar.txt')
>>> os.remove(path)

Ответ 2

hop прав, а dF. неверно для причины возникновения ошибки.

Поскольку вы еще не вызвали f.close(), файл не удален.

doc для NamedTemporaryFile говорит:

Можно ли использовать имя для открытия файла во второй раз, тогда как именованный временный файл все еще открыт, он варьируется в разных платформах (его можно использовать в Unix, он не может работать в Windows NT или более поздней версии).

И для TemporaryFile:

В Unix запись каталога для файла удаляется сразу после создания файла. Другие платформы не поддерживают это; ваш код не должен полагаться на временный файл, созданный с использованием этой функции, имеющей или не имеющей видимого имени в файловой системе.

Поэтому, чтобы сохранить временный файл (в Windows), вы можете сделать следующее:

>>> import tempfile, shutil
>>> f = tempfile.NamedTemporaryFile(mode='w+t', delete=False)
>>> f.write('foo')
>>> file_name = f.name
>>> f.close()
>>> shutil.copy(file_name, 'bar.txt')

Решение, предоставленное Hans Sjunnesson, также отключено, поскольку copyfileobj копирует только файл-подобный объект в файл-подобный объект, а не имя файла:

shutil.copyfileobj(fsrc, fdst [, length])

Скопируйте содержимое файлового объекта fsrc в файл-подобный объект fdst. Целая длина, если задана, является размером буфера. В частности, значение отрицательной длины означает копирование данных без циклирования по исходным данным в кусках; по умолчанию данные считываются в кусках, чтобы избежать неконтролируемого потребления памяти. Обратите внимание: если текущая позиция файла объекта fsrc не равна 0, будет скопировано только содержимое из текущей позиции файла в конец файла.

Ответ 3

Начиная с python 2.6 вы также можете использовать NamedTemporaryFile с параметром delete=, установленным на False. Таким образом, временный файл будет доступен даже после его закрытия.

Обратите внимание, что в Windows (NT и более поздних версиях) вы не можете получить доступ к файлу во второй раз, пока он еще открыт. Вы должны закрыть его, прежде чем копировать его. Это не относится к системам Unix.

Ответ 4

Вы всегда можете использовать shutil.copyfileobj в своем примере:

new_file = open('bar.txt', 'rw')
shutil.copyfileobj(f, new_file)