Закрытие файла docx, если он открыт

#python #docx #python-docx

#python #docx #python-docx

Вопрос:

Я работаю с файлами docx и, чтобы предотвратить PermissionError: [Errno 13] Permission denied ошибку, я попытался добавить os.close() в свой код, но, как я увидел, он не принимает путь к файлу, он принимает дескриптор файла в качестве параметра.Итак, я попробовал это:

 file_path = 'my file path'
mydoc = docx.Document()
mydoc.add_paragraph('text')
try:
    mydoc.save(file_path)
    return
except PermissionError:
    fd = os.open(file_path, os.O_WRONLY)
    os.close(fd)
    mydoc.save(file_path)
    return
  

Но когда я запускаю его, он выдает первую PermissionError ошибку из-за обработки ошибок, но когда он пытается это сделать fd = os.open(file_path, os.O_WRONLY) , я получаю ту же ошибку. Итак, есть ли возможный способ закрыть файл docx, если он открыт?

Редактировать:

Вот полная трассировка

 Exception in Tkinter callback
Traceback (most recent call last):
  File "C:Users17326PycharmProjectsnewEksimain2.py", line 194, in arat
    mydoc.save(dosya_yolu)
  File "C:Users17326PycharmProjectsnewEksivenvlibsite-packagesdocxdocument.py", line 167, in save
    self._part.save(path_or_stream)
  File "C:Users17326PycharmProjectsnewEksivenvlibsite-packagesdocxpartsdocument.py", line 111, in save
    self.package.save(path_or_stream)
  File "C:Users17326PycharmProjectsnewEksivenvlibsite-packagesdocxopcpackage.py", line 172, in save
    PackageWriter.write(pkg_file, self.rels, self.parts)
  File "C:Users17326PycharmProjectsnewEksivenvlibsite-packagesdocxopcpkgwriter.py", line 32, in write
    phys_writer = PhysPkgWriter(pkg_file)
  File "C:Users17326PycharmProjectsnewEksivenvlibsite-packagesdocxopcphys_pkg.py", line 141, in __init__
    self._zipf = ZipFile(pkg_file, 'w', compression=ZIP_DEFLATED)
  File "C:Users17326AppDataLocalProgramsPythonPython38-32libzipfile.py", line 1251, in __init__
    self.fp = io.open(file, filemode)
PermissionError: [Errno 13] Permission denied: 'C:/Users/17326/Desktop/entries.docx'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:Users17326AppDataLocalProgramsPythonPython38-32libtkinter__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:Users17326PycharmProjectsnewEksimain2.py", line 197, in arat
    fd = os.open(dosya_yolu, os.O_WRONLY)
PermissionError: [Errno 13] Permission denied: 'C:/Users/17326/Desktop/entries.docx'
  

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

1. Что заставляет вас думать, что файл «открыт»? Вы знаете, что он открыт в каком-то другом процессе? Если вы это сделаете, то обычно вы не сможете закрыть файл, который был открыт другим процессом. Вы, конечно, не можете сделать это так, как пытаетесь это сделать. — я предполагаю, что вы получаете PermissionError ошибку не потому, что файл открыт, а по какой-то другой причине, например, у вас нет прав доступа к файлу или целевому каталогу для записи файла.

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

3. Я почти уверен, что у меня есть разрешение на этот файловый целевой каталог, потому что, когда файл закрыт, мой код работает нормально.

4. Можете ли вы добавить всю обратную трассировку? Похоже, что вы получаете ошибку разрешения при сохранении файла, при обработке этой ошибки вы пытаетесь повторно открыть тот же файл, вызывая другую ошибку разрешения.

5. Вы пытаетесь принудительно закрыть файл, который используется другим приложением? Хотя технически это может быть выполнимо с помощью злых взломов WinAPI, я бы настоятельно рекомендовал отказаться от этого, поскольку у вас нет возможности узнать, в каком состоянии находится файл, и вы вполне можете удалить его содержимое. Почему вы хотите это сделать?

Ответ №1:

В python-docx нет такого понятия, как «открытый» файл. Когда вы читаете в файле, чтобы отредактировать его с помощью document = Document("my-file.docx") , python-docx считывает в файле, и все. Да, он открыт на долю секунды во время чтения, но он не остается открытым. Цикл открытия / закрытия заканчивается до того, как Document() вызов вернется.

То же самое при сохранении файла. При вызове document.save("my-output-file.docx") файл открывается, записывается и закрывается, и все это до того, как .save() метод вернет результат.

Так что это не похоже на сам Word, где вы открываете файл, работаете над ним некоторое время, а затем сохраняете и закрываете его. Вы просто считываете «начальный» файл в память, вносите изменения в этот объект в памяти, а затем позже записываете представление в памяти (почти всегда в другой файл).

Комментарии на правильном пути. Ищите проблему с разрешениями, которая не позволяет вам записывать файл в этом расположении, которое не подключено к открытому файлу, если только у вас нет соответствующего файла, открытого в Word или чем-то еще во время запуска вашей программы.

Ответ №2:

python-docx может открывать документ из так называемого файлоподобного объекта. Он также может сохраняться в файлоподобный объект. Это может быть удобно, когда вы хотите получить исходный или целевой документ через сетевое подключение или из базы данных и не хотите (или вам не разрешено) взаимодействовать с файловой системой. На практике это означает, что вы можете передать открытый файл или объект потока StringIO / BytesIO, чтобы открыть или сохранить документ следующим образом:

 f = open('foobar.docx', 'rb')
document = Document(f)
f.close()

# or

with open('foobar.docx', 'rb') as f:
    source_stream = StringIO(f.read())
document = Document(source_stream)
source_stream.close()
...
target_stream = StringIO()
document.save(target_stream)
  

Ответ №3:

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

 file_path = 'my file path'
mydoc = docx.Document()
mydoc.add_paragraph('text')
hasError = False
try:
    fd = open(file_path)
    fd.close()
    mydoc.save(file_path)
except PermissionError:
    raise Exception("oh no some other process is using the file or you don't have access to the file, try again when the other process has closed the file")
    hasError = True
finally:
    if not hasError:
        mydoc.save(file_path)
return
  

Ответ №4:

Закрытие файла doc / docx, если он открыт с помощью Python 1. Сохраните файл doc / docx 2. Закройте файл doc / docx 3. Закройте приложение Word

 from win32com import client as wc
w = wc.Dispatch('Word.Application')
doc = w.Documents.Open(file_path)
doc.SaveAs("Savefilename_docx.docx", 16)
doc.Close()
w.Quit()