Вопрос

I'm trying to create a function to do one thing: return the most recent file name, in real time.

Now I found this fine piece by googling:

function FileWatch(pathToWatch)
    txtDetectedFiles = createFigure;
    fileObj = System.IO.FileSystemWatcher(pathToWatch);
    fileObj.EnableRaisingEvents = true;
    changeListener =addlistener(fileObj, 'Changed', @onChange); %need to keep in scope

    function txtDetectedFiles = createFigure % Creates Figure
        figHdl = figure('Name','FileWatcher',...
                        'Menubar','none',...
                         'Toolbar','none',...
                         'NumberTitle','off',...
                         'Units','normalized',...
                         'Position',[0.4,0.4,0.4,0.2]);
        uicontrol('Parent',figHdl,...
                  'Style','text',...
                  'Units','normalized',...
                  'Position',[0.1,0.9,0.8,0.08],...
                   'String',['Path Watched: ',pathToWatch]);
        txtDetectedFiles = uicontrol('Parent',figHdl,...
                                     'Style','edit',...
                                     'Enable','inactive',...
                                     'Units','normalized',...
                                     'Position',[0.1,0.05,0.8,0.45],...
                                     'Max',3);
    end %createFigure

    function onChange(~,evt)
        existStr = get(txtDetectedFiles,'String');
        if isempty(existStr)
            existStr = {};
        end %if
        existStr{length(existStr)+1} = ['New file Detected: ',char(evt.FullPath.ToString())];
        set(txtDetectedFiles,'String',existStr);

        newestfile = (char(evt.FullPath.ToString()));
        assignin ('base','newestfile',newestfile); % Sets Variable to the newestfile
    end %onChange 
end %FileWatch 

It responds far better than my previous methods and it works, I added newestfile and assignin to return the most recent file as a string.

The problem is however, I cannot seem to shorten this into more basic function without the figures. I simply need this to watch a directory, and return new files quickly. When I delete the figures (createfigure), it does not respond, so it seems a requirement...

Can someone please help me with this? So once more, I'm looking for a simpler, non GUI/figure/uicontrol version of this.

Это было полезно?

Решение

The issue is that, as the comments in the code say, you have to keep changeListener alive. That is, keep a reference somewhere where it is not destroyed. In the with-figures version a reference is probably kept in the workspace of the nested functions (yet another reason not to use them).

The following works for me:

function listeners = FileWatch(pathToWatch, callback)
    persistent Listeners;

    % to check/clear the existing ones:
    listeners = [];
    switch pathToWatch
        case 'clear'
           Listeners = [];
           return
        case 'list'
           listeners = Listeners;
           return;
    end

    fileObj = System.IO.FileSystemWatcher(pathToWatch);
    fileObj.EnableRaisingEvents = true;

    changeListener = addlistener(fileObj, 'Changed', @onChange); %need to keep in scope
    % alternatively:
    % taking the callback as input-argument would make it a more universal function:
    % changeListener = addlistener(fileObj, 'Changed', callback);


    if isempty(Listeners)
        Listeners = changeListener;
    else
        Listeners(end+1) = changeListener;
    end

end

function onChange(~,evt)
    newestfile = char(evt.FullPath.ToString());
    fprintf('File-Event: %s\n', newestfile);
    % do whatever you want to do with it :)
end %onChange 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top