【发布时间】:2021-11-10 23:14:05
【问题描述】:
以下代码旨在在将文件添加到其文件夹时触发。如果文件类型为.csv或.txt,则需要读取文件。起初,我收到消息
Message=[Errno 13] Permission denied: 'TestDataFile2021-09-11_15-54.csv'
尝试读取文件时。我相信这是因为该文件夹正在被工作线程使用。我一直在想办法暂停线程、运行函数并继续监视文件夹。
错误:
# Loop the data lines
with open(data_file, 'r+') as temp_f:
我需要暂停的地方:
if fType == ".csv" or fType == ".txt":
data_file = a_string
thread_pool_executor.submit(self.process_csv) # Pause thread, run process_csv, and resume
self.process_csv()
完整代码:
import os
import win32file
import win32event
import win32con
from win32com import client
import ctypes
import pandas as pd
import csv
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from openpyxl import load_workbook
import wx
import glob
from os.path import splitext
from concurrent import futures
import sys
import time
thread_pool_executor = futures.ThreadPoolExecutor(max_workers=3)
class MainFrame(wx.Frame):
def __init__(self, parent, title):
super(MainFrame, self).__init__(parent, title=title,size=(600,400))
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour("light gray")
#Create sizers
vbox = wx.BoxSizer(wx.VERTICAL)
#Create widgets
st1 = wx.StaticText(self.panel, label='Script is not running.')
tc = wx.TextCtrl(self.panel)
btn_start = wx.Button(self.panel, label='Run Script', size=(100, 30))
btn_start.SetBackgroundColour(wx.Colour(198, 89, 17))
#self.btn_login.SetFont(self.b_font)
btn_start.Bind(wx.EVT_BUTTON, self.onStart)
vbox.Add(st1,-1 , wx.ALIGN_CENTRE | wx.ALL, 5)
vbox.Add(btn_start, 0, wx.ALIGN_CENTRE | wx.ALL, 5)
vbox.Add(tc,2, wx.EXPAND| wx.ALL, 10)
#Layout
self.panel.SetSizer(vbox)
self.Centre()
self.Show()
def onStart(self,event):
print('Listening')
self._quit = False
thread_pool_executor.submit(self.monitor_folder)
thread_pool_executor.submit(self.active_listening)
def process_csv(self):
data_file = "TestDataFile2021-09-11_15-54.csv"
data_file_delimiter = ','
largest_column_count = 0
# Loop the data lines
with open(data_file, 'r+') as temp_f:
lines = temp_f.readlines()
for l in lines:
column_count = len(l.split(data_file_delimiter)) + 1
largest_column_count = column_count if largest_column_count < column_count else largest_column_count
column_names = [i for i in range(0, largest_column_count)]
# Read csv
df = pd.read_csv(data_file, delimiter=data_file_delimiter, names=column_names) #header=None,
df.fillna("", inplace=True)
print(df)
def active_listening(self):
m = 'Listening'
i = 1
while self._quit == False:
time.sleep(2)
if i <= 3:
m = m + "."
print(m)
i = i + 1
else:
i = 1
m = 'Listening'
def monitor_folder(self):
#wx.CallAfter(self.print1)
while self._quit == False:
path_to_watch = os.path.abspath (".")
# FindFirstChangeNotification sets up a handle for watching
# file changes. The first parameter is the path to be
# watched; the second is a boolean indicating whether the
# directories underneath the one specified are to be watched;
# the third is a list of flags as to what kind of changes to
# watch for. We're just looking at file additions / deletions.
#
change_handle = win32file.FindFirstChangeNotification (
path_to_watch,
0,
win32con.FILE_NOTIFY_CHANGE_FILE_NAME
)
#
# Loop forever, listing any file changes. The WaitFor... will
# time out every half a second allowing for keyboard interrupts
# to terminate the loop.
try:
old_path_contents = dict ([(f, None) for f in os.listdir (path_to_watch)])
while 1:
result = win32event.WaitForSingleObject (change_handle, 500)
# If the WaitFor... returned because of a notification (as
# opposed to timing out or some error) then look for the
# changes in the directory contents.
if result == win32con.WAIT_OBJECT_0:
new_path_contents = dict ([(f, None) for f in os.listdir (path_to_watch)])
added = [f for f in new_path_contents if not f in old_path_contents]
deleted = [f for f in old_path_contents if not f in new_path_contents]
if added:
print ("Added: ", ", ".join (added))
#Get file type
a_string = ", ".join (added)
length = len(a_string)
fType = a_string[length - 4:]
if fType == ".csv" or fType == ".txt":
data_file = a_string
thread_pool_executor.submit(self.process_csv) # Pause thread, run process_csv, and resume
self.process_csv()
else:
print('Not what we want')
if deleted: print ("Deleted: ", ", ".join (deleted))
old_path_contents = new_path_contents
win32file.FindNextChangeNotification (change_handle)
finally:
win32file.FindCloseChangeNotification (change_handle)
def main():
app = wx.App()
ex = MainFrame(None, title='Border')
ex.Show()
app.MainLoop()
if __name__ == '__main__':
main()
【问题讨论】:
标签: python csv threadpool win32com concurrent.futures