How to "Watch" a File for Modification/Change

How can I watch a file for modification / change?

As noted, you can use pyinotify:

E.g.:

import webbrowser
import pyinotify

class ModHandler(pyinotify.ProcessEvent):
# evt has useful properties, including pathname
def process_IN_CLOSE_WRITE(self, evt):
webbrowser.open(URL)

handler = ModHandler()
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch(FILE, pyinotify.IN_CLOSE_WRITE)
notifier.loop()

This is more efficient than polling. The kernel tells you when it does the operation, without you having to constantly ask.

How to watch a file, whenever it changes, take the new additional line and perform some actions on it with powershell

What you are doing is only allowed to show a file in real-time on the screen. You cannot mess with the output doing that.

The command you are using is not for interactive use cases.

You can monitor for file updates without doing what you are doing, by using a SystemFileWatcher, which allows for monitor for file actions, that you can then take action on.



'PowerShell filesystemwatcher monitor file'

https://duckduckgo.com/?q=%27PowerShell+filesystemwatcher+monitor+file%27&t=h_&ia=web


For example from one of the hits from the above link.

https://powershell.one/tricks/filesystem/filesystemwatcher

Monitoring Folders for File Changes

With a FileSystemWatcher, you can monitor folders for file changes and
respond immediately when changes are detected. This way, you can
create “drop” folders and respond to log file changes.

Specifically, as per your use case:

Advanced Mode (asynchonous)

If you expect changes to happen in rapid succession or even
simultaneously, you can use the FileSystemWatcher in asynchronous
mode: the FileSystemWatcher now works in the background and no longer
blocks PowerShell. Instead, whenever a change occurs, an event is
raised. So with this approach, you get a queue and won’t miss any
change.

On the back side, this approach has two challenges:

  • Handling Events: since PowerShell is single-threaded by nature, it is
    not trivial to respond to events, and even more cumbersome to debug
    event handler code.

    Keeping PowerShell running: ironically, because the FileSystemWatcher
    now no longer blocks PowerShell, this leads to another problem. You
    need to keep PowerShell waiting for events but you cannot use
    Start-Sleep or and endless loop because as long as PowerShell is busy

    • and it is considered busy even if it sleeps - no events can be handled.

Implementation

The script below does the exact same thing as the synchronous version
from above, only it is event-based and won’t miss any events anymore:

# find the path to the desktop folder:
$desktop = [Environment]::GetFolderPath('Desktop')

# specify the path to the folder you want to monitor:
$Path = $desktop

# specify which files you want to monitor
$FileFilter = '*'

# specify whether you want to monitor subfolders as well:
$IncludeSubfolders = $true

# specify the file or folder properties you want to monitor:
$AttributeFilter = [IO.NotifyFilters]::FileName, [IO.NotifyFilters]::LastWrite

try
{
$watcher = New-Object -TypeName System.IO.FileSystemWatcher -Property @{
Path = $Path
Filter = $FileFilter
IncludeSubdirectories = $IncludeSubfolders
NotifyFilter = $AttributeFilter
}

# define the code that should execute when a change occurs:
$action = {
# the code is receiving this to work with:

# change type information:
$details = $event.SourceEventArgs
$Name = $details.Name
$FullPath = $details.FullPath
$OldFullPath = $details.OldFullPath
$OldName = $details.OldName

# type of change:
$ChangeType = $details.ChangeType

# when the change occured:
$Timestamp = $event.TimeGenerated

# save information to a global variable for testing purposes
# so you can examine it later
# MAKE SURE YOU REMOVE THIS IN PRODUCTION!
$global:all = $details

# now you can define some action to take based on the
# details about the change event:

# let's compose a message:
$text = "{0} was {1} at {2}" -f $FullPath, $ChangeType, $Timestamp
Write-Host ""
Write-Host $text -ForegroundColor DarkYellow

# you can also execute code based on change type here:
switch ($ChangeType)
{
'Changed' { "CHANGE" }
'Created' { "CREATED"}
'Deleted' { "DELETED"
# to illustrate that ALL changes are picked up even if
# handling an event takes a lot of time, we artifically
# extend the time the handler needs whenever a file is deleted
Write-Host "Deletion Handler Start" -ForegroundColor Gray
Start-Sleep -Seconds 4
Write-Host "Deletion Handler End" -ForegroundColor Gray
}
'Renamed' {
# this executes only when a file was renamed
$text = "File {0} was renamed to {1}" -f $OldName, $Name
Write-Host $text -ForegroundColor Yellow
}

# any unhandled change types surface here:
default { Write-Host $_ -ForegroundColor Red -BackgroundColor White }
}
}

# subscribe your event handler to all event types that are
# important to you. Do this as a scriptblock so all returned
# event handlers can be easily stored in $handlers:
$handlers = . {
Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Deleted -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $action
}

# monitoring starts now:
$watcher.EnableRaisingEvents = $true

Write-Host "Watching for changes to $Path"

# since the FileSystemWatcher is no longer blocking PowerShell
# we need a way to pause PowerShell while being responsive to
# incoming events. Use an endless loop to keep PowerShell busy:
do
{
# Wait-Event waits for a second and stays responsive to events
# Start-Sleep in contrast would NOT work and ignore incoming events
Wait-Event -Timeout 1

# write a dot to indicate we are still monitoring:
Write-Host "." -NoNewline

} while ($true)
}
finally
{
# this gets executed when user presses CTRL+C:

# stop monitoring
$watcher.EnableRaisingEvents = $false

# remove the event handlers
$handlers | ForEach-Object {
Unregister-Event -SourceIdentifier $_.Name
}

# event handlers are technically implemented as a special kind
# of background job, so remove the jobs now:
$handlers | Remove-Job

# properly dispose the FileSystemWatcher:
$watcher.Dispose()

Write-Warning "Event Handler disabled, monitoring ends."
}

So, with the above, you tweak it to look for updates/modifications, then use

$CaptureLine = Get-Content -Path 'UNCToTheLogFile' | Select-Object -Last 1

Or

$CaptureLine = Get-Content -Path  'D:\temp\book1.csv' -Tail 1

And do what you want from that.

How do I make my program watch for file modification in C++?

There are several ways to do this depending on the platform. I would choose from the following choices:

Cross Platform

Trolltech's Qt has an object called QFileSystemWatcher which allows you to monitor files and directories. I'm sure there are other cross platform frameworks that give you this sort of capability too, but this one works fairly well in my experience.

Windows (Win32)

There is a Win32 api called FindFirstChangeNotification which does the job. There is a nice article which a small wrapper class for the api called How to get a notification if change occurs in a specified directory which will get you started.

Windows (.NET Framework)

If you are ok using C++/CLI with the .NET Framework then
System.IO.FileSystemWatcher is your class of choice. Microsoft has a nice article on
how to monitor file system changes using this class.

OS X

The FSEvents API is new for OS X 10.5 and very full-featured.

Linux

Use inotify as Alex mentioned in his answer.

Watching for file and directory changes in Java

This will allow you to experiment with creating, deleting, moving and renaming files under D:\Temp, and should allow you to learn what you need:

import static com.sun.nio.file.ExtendedWatchEventModifier.FILE_TREE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class Foo3
{
public static void main(String[] args) throws Exception
{
FileSystem fs = FileSystems.getDefault();
WatchService ws = fs.newWatchService();
Path pTemp = Paths.get("D:/Temp");
pTemp.register(ws, new WatchEvent.Kind[] {ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE}, FILE_TREE);
while(true)
{
WatchKey k = ws.take();
for (WatchEvent<?> e : k.pollEvents())
{
Object c = e.context();
System.out.printf("%s %d %s\n", e.kind(), e.count(), c);
}
k.reset();
}
}
}

How can I see what has changed in a file before committing to git?

You're looking for

git diff --staged

Depending on your exact situation, there are three useful ways to use git diff:

  1. Show differences between index and working tree; that is, changes you haven't staged to commit:
git diff [filename]

  1. Show differences between current commit and index; that is, what you're about to commit (--staged does exactly the same thing, use what you like):
git diff --cached [filename]

  1. Show differences between current commit and working tree:
git diff HEAD [filename]

git diff works recursively on directories, and if no paths are given, it shows all changes.

Is there a way to watch file changes in main js file runned in nodejs?

You can use nodemon. It will detect any changes to your directory and rerun the app.

npm install --save-dev nodemon
nodemon --inspect-brk index.js

watchdog monitoring file for changes

Instead of LoggingEventHandler define your handler:

#!/usr/bin/python
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
print(f'event type: {event.event_type} path : {event.src_path}')

if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='/data/', recursive=False)
observer.start()

try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

on_modified is called when a file or directory is modified.



Related Topics



Leave a reply



Submit