Python — запись и чтение из временного файла

#python #temporary-files

#python #временные файлы

Вопрос:

Я пытаюсь создать временный файл, который я записываю в несколько строк из другого файла, а затем создаю некоторые объекты из данных. Я не уверен, как найти и открыть временный файл, чтобы я мог его прочитать. Мой код:

 with tempfile.TemporaryFile() as tmp:
    lines = open(file1).readlines()
    tmp.writelines(lines[2:-1])

dependencyList = []

for line in tmp:
    groupId = textwrap.dedent(line.split(':')[0])
    artifactId = line.split(':')[1]
    version = line.split(':')[3]
    scope = str.strip(line.split(':')[4])
    dependencyObject = depenObj(groupId, artifactId, version, scope)
    dependencyList.append(dependencyObject)
tmp.close()
  

По сути, я просто хочу создать временный документ посредника для защиты от случайной перезаписи файла.

Комментарии:

1.Я никогда не использовал временные файлы, есть ли какая-либо причина, по которой вы не используете стандартные open() write read методы and ?

2. Я хочу защитить от возможности того, что имя файла уже существует, и я мог бы его перезаписать

3. 1. рассматривали ли вы возможность простого преобразования выходных данных из одного скрипта во входные данные второго скрипта? 2. Вы проверяете, существует ли временный файл в пути, который вы просматриваете?

4. У вас проблема с областью действия. Временный файл tmp существует только в рамках with цикла, который его создает.

5. Пожалуйста, оставьте свой комментарий в качестве ответа, Пирс Дарра, чтобы я мог его изменить.

Ответ №1:

У вас проблема с областью действия; файл tmp существует только в пределах области действия with оператора, который его создает. Кроме того, вам нужно будет использовать a NamedTemporaryFile , если вы хотите получить доступ к файлу позже, за пределами начального with (это дает ОС возможность доступа к файлу). Кроме того, я не уверен, почему вы пытаетесь добавить во временный файл … поскольку он не будет существовать до его создания.

Попробуйте это:

 import tempfile

tmp = tempfile.NamedTemporaryFile()

# Open the file for writing.
with open(tmp.name, 'w') as f:
    f.write(stuff) # where `stuff` is, y'know... stuff to write (a string)

...

# Open the file for reading.
with open(tmp.name) as f:
    for line in f:
        ... # more things here
  

Комментарии:

1. Также убедитесь, что вы добавили «f.seek (0)» после записи в файл, если вы собираетесь читать из него, не закрывая и не открывая его снова. В противном случае вы будете читать конец файла, что даст вам неверный результат.

2. Я получаю Permission denied при попытке открыть временный файл

3. @CGFoX я думаю, это указывает на какую-то проблему с вашей файловой системой. В вашей ОС есть расположение временных файлов по умолчанию, и это то, что Python использует для них. Например, в macOS 10.14 Mojave (и, я полагаю, также в других версиях) местоположение /var/folders/ . Если вы получаете сообщение об отказе в разрешении, у вас, вероятно, нет доступа на запись в это местоположение.

4. tempfile.NamedTemporaryFile() имеет значение по умолчанию delete=True , поэтому может быть доступен вне области видимости with или при закрытии.

5. Вы можете использовать with tempfile.NamedTemporaryFile() as f напрямую, пропуская open() .

Ответ №2:

Согласно документам, файл удаляется при TemporaryFile закрытии, и это происходит при выходе из with предложения. Итак … не выходите из with предложения. Перемотайте файл и выполните свою работу в with .

 with tempfile.TemporaryFile() as tmp:
    lines = open(file1).readlines()
    tmp.writelines(lines[2:-1])
    tmp.seek(0)

    for line in tmp:
        groupId = textwrap.dedent(line.split(':')[0])
        artifactId = line.split(':')[1]
        version = line.split(':')[3]
        scope = str.strip(line.split(':')[4])
        dependencyObject = depenObj(groupId, artifactId, version, scope)
        dependencyList.append(dependencyObject)
  

Комментарии:

1. Спасибо, что решили это. Что выполняет .seek(0)?

2. это та перемотка, о которой вы говорите?

3. После вас tmp.writelines указатель на файл находится в конце файла. tmp.seek(0) снова возвращает его к началу (перематывает его — возможно, это древний язык кассетных лент!), Чтобы вы могли прочитать то, что написали.

Ответ №3:

В случае, если файл необходимо открыть во второй раз, например, прочитать другим процессом, это может вызвать проблемы в ОС Windows:

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

Следовательно, безопасным решением является создание временного каталога, а затем вручную создать в нем файл:

 import os.path
import tempfile

with tempfile.TemporaryDirectory() as td:
    f_name = os.path.join(td, 'test')
    with open(f_name, 'w') as fh:
        fh.write('<content>')
    # Now the file is written and closed and can be used for reading.
  

Комментарии:

1. Или from pathlib import Path и затем f_name = Path(td) / 'test'

Ответ №4:

Я просто хочу создать временный документ посредника для защиты от случайной перезаписи файла.

Надеюсь, вы открываете файл в режиме чтения и избегаете произвольных os.remove() вызовов, поэтому в обычном случае вероятность несчастного случая невелика.

Тем не менее, если обычные средства защиты отключены по уважительной причине, вы можете создать резервную копию файла, создав временный файл и скопировав в него содержимое исходного файла с помощью shutil :

 import shutil
import tempfile


orig_path = "hello.txt"

# make a sample file
with open(orig_path, "w") as f:
    f.write("hello world")

with tempfile.NamedTemporaryFile() as temp:
    shutil.copy2(orig_path, temp.name)

    # or optionally write to the file:
    #temp.write("hello world".encode("utf-8"))
    #temp.flush()
    #temp.seek(0)

    # temp will be available in this block
    print(temp.read().decode("utf-8")) # => hello world

# temp will be deleted after the block