Найти - Пользователи
Полная версия: Закрыт ли файл?
Начало » Python для экспертов » Закрыт ли файл?
1 2
slice
есть задача открыть файл (не в питоне), пусть будет txt или word или что угодно, для этого используем
import os
os.startfile('NEWS.txt')

ок, мы его открыли
как потом, после закрытия, доказать что он закрыт?

я пробовал использовать

import psutil

и смотреть за процессами, но а если будет открыт другой файл а предыдущий будет закрыт, а процесс то один. Помогите пожалуйста
slice
[code python]import psutil, os,re

def notClose(pid):
while psutil.pid_exists(pid)!=False:
pass
else: return False
def openFile(file):
data = {
'docx':'word',
'txt':'notepad'
}
try:
processName = data[re.split('\.',file)[-1]]
except KeyError:
print('Неизвестный формат файла')

os.startfile(file)
for i in psutil.pids():

process = psutil.Process(i)
if processName in data.name() or processName.upper() in data.name():
if notClose(data.pid)==False:
print(file,'closed')


[/code]
код как бы работает, но на вордах нет. Как получить время создания процесса ?
py.user.next
python.org. os.startfile()
startfile() returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve the application’s exit status.

Попробуй subprocess.Popen() использовать вместо этого.
doza_and
Думаю проблема ТС пошире - он не знает что запускать.
Судя по тому что он запускает ОС windows

Тогда можно командой assoc получить имя ассоциации
командой ftype по имени ассоциации получить шаблон командной строки
В него подставить имя файла.
И использовать не Popen а check_call тогда управление не вернется пока не закончится выполнение команды
py.user.next
doza_and
И использовать не Popen а check_call тогда управление не вернется пока не закончится выполнение команды
Там есть метод .wait()

Функция check_call() реализована через call(), а call() реализована через Popen().
https://github.com/python/cpython/blob/master/Lib/subprocess.py

Но фишка этих функций в том, что они не так гибки, как изначальный объект из Popen(), с которым можно сделать всё по максимуму.

doza_and
Думаю проблема ТС пошире - он не знает что запускать.
Да, но он не просто не знает, что запускать, а не знает, как это делается вообще.
Отдавать неизвестную фигню на откуп чего-то там - это явно к чему-нибудь приведёт, и совсем не к тому, что не ожидалось.
В общем, нужно конкретно выбирать: если у тебя текстовый файл, открывай его только в блокноте; если у тебя документ ворда, открывай его только в ворде; если у тебя html-страница, открывай её только в браузере. Нужно сделать функцию выбора конкретной процедуры открытия и в ней определять, как открыть файл.
PEHDOM
Нихрена не выйдет, разные программы по разному работают с файлами, тот же блокнот открывает файл, считывает его в память и сразу закрывает, тоесть процесс еще не завершен, файл кагбэ “открыт” а реально он закрыт. Вы можете с ним сделать все что угодно, изменить, переименовать, удалить.
С вордом ситуация обратная, он открывает файл и держит его, пока его не звкроют.. проверить достаточно просто, банальный код:
 import os
import time
myFile = 'r.doc'
os.startfile(myFile)
time.sleep(5)
try:
    inFile = open(myFile,'ab')
except IOError:
    print('файл {} еще открыт'.format(myFile))
else:
    print('файл {} закрыт'.format(myFile))
    inFile.close()
при открытии файла в ворде, получим сообщение что файл еще открыт, а в блокноте, что файл закрыт.
doza_and
py.user.next
если у тебя документ ворда, открывай его только в ворде
:) а у меня вордовые документы ворд частенько не может открыть или портит при открытии. Поэтому конкретно у меня ассоциирован docx на Libreoffice. Ничего не поделаешь еще один уровень редиректа.
py.user.next
doza_and
Поэтому конкретно у меня ассоциирован docx на Libreoffice.
Видел, как в git'е сделано? Когда нужно сравнить два файла, используется difftool - абстрактный сравниватель.

http://schacon.github.io/git/git-difftool.html
CONFIG VARIABLES

git difftool falls back to git mergetool config variables when the difftool equivalents have not been defined.

diff.tool
The default diff tool to use.

diff.guitool
The default diff tool to use when --gui is specified.

То есть мы имеем difftool по умолчанию, но используется он через абстрактный difftool, к которому что-то прикручено. По умолчанию прикручено что-то и в настройках можно указать, которые перекроют умолчания.

Так и здесь надо сделать ему: определить абстрактный текстовый редактор, абстрактный документный редактор, абстрактный html-страничный просмотрщик. А потом сделать для них настройки, где можно записать, что запускает каждый из абстрактных редакторов или просмотрщиков.

У меня так в загрузчике файлов из Интернета сделано: качается всё через абстрактный загрузчик, а в абстрактном загрузчике записан Wget, но при этом, если я заменю его на Curl, например, вся программа этого даже не заметит, потому что все загрузки она просит выполнить абстрактный загрузчик через его методы.

И как понять тогда, закрыт у него файл или открыт? Очень просто - надо ему сделать обёртку, которая создаёт признак открытого файла и удаляет этот признак после закрытия приложения. И всё это происходит за пределами питона на уровне операционной системы. Так что из питона внутри системы ничего не надо проверять, достаточно проверить наличие признака (временного файла, например).
doza_and
py.user.next
Так и здесь надо сделать ему: определить абстрактный текстовый редактор,
Согласен. Штатный способ сделать это в винде я описал. Там только от рождения fallback нету. Это надо самому пилить.

По поводу контроля открытия я считал что автор хочет контролировать открытие исполняемого файла т.е. подождать когда пользователь закончит манипуляции с файлом.
Если самого документа, то пусть ТС уточняет что он хочет.
Я согласен с
PEHDOM
проверить достаточно просто, банальный код:
Занятость файла проверяется элементарно. А то что приложение может считать файл и сразу закрыть, ну чтоже - значит он уже закрыт. Может пользователь его не по Save а по SaveAs сохранит. Значит это другой файл а не первый!

Кстати контроль процесса тоже может не сработать. Иногда запускаемый процесс порождает еще один процесс для редактирования, а сам закрывается.
PEHDOM
PS, если у человека только венда, тогда уже проще запускать файл через shellExecuteEх , венда сама найдет чем это файо открыть(при условии конечно что ассоциации выставлены в самой венде), запустит нужное приложение, откроет файл в этом приложении, и вернет хендл приложения, а уже имея хендл с помощью pywin32 или pywinauto с этим процессом можно делать все что угодно.
 import win32com.shell.shell as shell
import win32event
fileName = 'test.txt'
dict = shell.ShellExecuteEx(fMask = 64, lpFile=fileName, lpParameters='', nShow=1)
hndl = dict['hProcess']
print (hndl)
ret = win32event.WaitForSingleObject(hndl, -1)
print (ret)
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