Using multiple FileSystemWatchers - filesystemwatcher

I want to use multiple FileSystemWatchers to watch different text files.
I am successful in creating the watchers and the file change events are being invoked and I can add the changes in the text files to a string and display this on a form.
What I want to know is how I can tell which watcher is causing the event?
Eg. watcher1, watcher2 or watcher3?
I know I can find out the path and file name of the file that has changed but this doesn't really help me.

I realize you already found your own way to do this, but I recommend you look at the sender parameter within the event that is being fired. This is common for a lot of events. Here is a small example:
private static FileSystemWatcher watcherTxt;
private static FileSystemWatcher watcherXml;
static void Main(string[] args)
{
String dir = #"C:\temp\";
watcherTxt = new FileSystemWatcher();
watcherTxt.Path = dir;
watcherTxt.Filter = "*.txt";
watcherTxt.EnableRaisingEvents = true;
watcherTxt.Created += new FileSystemEventHandler(onCreatedFile);
watcherXml = new FileSystemWatcher();
watcherXml.Path = dir;
watcherXml.Filter = "*.xml";
watcherXml.EnableRaisingEvents = true;
watcherXml.Created += new FileSystemEventHandler(onCreatedFile);
Console.ReadLine();
}
private static void onCreatedFile(object sender, FileSystemEventArgs e)
{
if (watcherTxt == sender)
{
Console.WriteLine("Text Watcher Detected: " + e.FullPath);
}
if (watcherXml == sender)
{
Console.WriteLine("XML Watcher Detected: " + e.FullPath);
}
}

Related

thelinmichael/spotify-web-api-java: How to get value from Async/Sync methods

For instance, I want to obtain the uri of a Spotify track and put it in another method as a String value, however I'm lost on how I'd go about doing that. I tried experimenting with SharedPreferences to get the value but getString method wasn't working. I was just wondering if there's a simpler way to getting say track.getUri (or any) in another method from the Async/Sync method. Any assistance would be greatly appreciated.
The code so far:
private static final String accessToken = "...";
private static final String id = "01iyCAUm8EvOFqVWYJ3dVX";
public static SharedPreferences.Editor editor;
private static final SpotifyApi spotifyApi = new SpotifyApi.Builder()
.setAccessToken(accessToken)
.build();
private static final GetTrackRequest getTrackRequest = spotifyApi.getTrack(id)
// .market(CountryCode.SE)
.build();
public static void getTrack_Sync() {
try {
final Track track = getTrackRequest.execute();
System.out.println("Name: " + track.getName());
} catch (IOException | SpotifyWebApiException | ParseException e) {
System.out.println("Error: " + e.getMessage());
}
}
#RequiresApi(api = Build.VERSION_CODES.N)
public void getTrack_Async() {
try {
final CompletableFuture<Track> trackFuture = getTrackRequest.executeAsync();
// Thread free to do other tasks...
// Example Only. Never block in production code.
final Track track = trackFuture.join();
String uri = track.getUri();
editor = getSharedPreferences("uri", 0).edit();
editor.putString("uri", uri);
editor.commit();
editor.apply();
System.out.println("Name: " + track.getUri());
} catch (CompletionException e) {
System.out.println("Error: " + e.getCause().getMessage());
} catch (CancellationException e) {
System.out.println("Async operation cancelled.");
}
}
public void go() {
getTrack_Async();
// String value = editor.getString("uri", )
}
To get the track you need some kind of information to start with. e.g. I have the spotify trackId and can find the track (synchronously) like this:
public Track getTrack(String trackId) {
return spotifyApi.getTrack(trackId).build().execute();
}
Now the Track object (specifically com.wrapper.spotify.model_objects.specification.Track) provides a lot of information. e.g. the field uri.
So you could do just:
public void run(String trackId) {
Track track = spotifyApi.getTrack(trackId).build().execute();
String uri = track.uri;
// now call something else with the uri?
}
Does that help? Your question was not entirely clear for me.

How to debug FileSystemWatcher c#

Can someone explain how I debug this?
I have built a windows service which monitors a folder and when a file is created in that folder, it moves that newly created file to another folder. Pretty simple and works. I am trying to pad it out now with out features and I'm starting to get generic IOExpections thrown in event viewer, so I want to try and debug. But the issue I am having is when to create the new file in the directory during debugging.
This is my code so far
which line should I stop at during stepping through, place my new file in the directory and then continue debugging so that it picks up the created file?
public void OnDebug()
{
OnStart(null);
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected override void OnStart(string[] args)
{
string pathToWatch = ConfigurationManager.AppSettings["DirectoryToWatch"];
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = pathToWatch;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
watcher.Created += new FileSystemEventHandler(FileCreated);
watcher.EnableRaisingEvents = true;
}
private void FileCreated(object source, FileSystemEventArgs e)
{
try
{
DateTime dt = File.GetCreationTime(e.FullPath);
File.Move(e.FullPath.ToString(), ConfigurationManager.AppSettings["DirectoryToMoveTo"] + e.Name + dt.ToString());
LogEvent($"New file found and moved \n {e.FullPath.ToString()}");
}
catch (IOException ex)
{
LogEvent(ex.ToString());
}
}
You can start by adding a breakpoint inside the function FileCreated.
I suggest you add a breakpoint at
DateTime dt = File.GetCreationTime(e.FullPath);
When you create a new file in the directory being watched, the FileSystemWatcher gets notified and the function FileCreated is called.
I also suggest you to log the destination path for your move. Just to make sure it's a valid path.

Downloads with JavaFX WebView

my web application offers a download. Javascript creats at the click the url (it depends on the user input) and the browser should open it, so that the page isn't reloaded.
For that, I think I have to alternatives:
// Alt1:
window.open(pathToFile);
// Alt2:
var downloadFrame = document.getElementById('downloads');
if (downloadFrame === null) {
downloadFrame = document.createElement('iframe');
downloadFrame.id = 'downloads';
downloadFrame.style.display = 'none';
document.body.appendChild(downloadFrame);
}
downloadFrame.src = pathToFile;
Both works under Firefox. Problem with open new window method: If the creation of the file at the server needs more time, the new empty tab will be closed late.
Problem with iframe: If there is an error at the server, no feedback is given.
I think at firefox the iframe is the better solution. But the web application must run with an JavaFX WebView, too. JavaFX haven't a download feature, I have to write it. One possible way is to listen on the location property:
final WebView webView = new WebView();
webView.getEngine().locationProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) {
if (newLoc.cotains("/download")) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Save " + newLoc);
File saveFile = chooser.showSaveDialog(webView.getEngine().getScene().getWindow());
if (saveFile != null) {
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
is = new BufferedInputStream(new URL(newLoc).openStream());
os = new BufferedOutputStream(new FileOutputStream(saveFile));
while ((readBytes = is.read()) != -1) {
os.write(b);
}
} finally {
try { if (is != null) is.close(); } catch (IOException e) {}
try { if (os != null) os.close(); } catch (IOException e) {}
}
}
}
}
}
There are some problems:
The download start depends on a part of the url, because JafaFX supports no access to the http headers (that is bearable)
If the user starts the download with the same url two times, only the first download works (the change event only fires, if the url is new). I can crate unique urls (with #1, #2 and so on at the end). But this is ugly.
Only the "window.open(pathToFile);" method works. Loading an iframe don't fire the change location event of the website. That is expectable but I haven't found the right Listener.
Can someone help me to solve 2. or 3.?
Thank you!
PS: Sorry for my bad english.
edit:
For 2. I found a way. I don't know if it is a good one, if it is performant, if the new webview is deleted or is in the cache after download, ....
And the user don't get an feedback, when some a problem is raised:
webView.getEngine().setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
#Override public WebEngine call(PopupFeatures config) {
final WebView downloader = new WebView();
downloader.getEngine().locationProperty().addListener(/* The Listener from above */);
return downloader.getEngine();
}
}
I think you may just need to use copyURLtoFile to get the file...call that when the location changes or just call that using a registered java class. Something like this:
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
Using copyURLToFile the current page doesn't have to serve the file. I think registering the class is probably the easiest way to go... something like this:
PHP Code:
Download $filename
Java (in-line class in your javafx class/window... in this case my javafx window is inside of a jframe):
public class JavaApp {
JFrame cloudFrameREF;
JavaApp(JFrame cloudFrameREF)
{
this.cloudFrameREF = cloudFrameREF;
}
public void getfile(String filename) {
String newLoc = "http://your_web_site.com/send_file.php?filename=" + filename;
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
}
}
This part would go in the main javafx class:
Platform.runLater(new Runnable() {
#Override
public void run() {
browser2 = new WebView();
webEngine = browser2.getEngine();
appREF = new JavaApp(cloudFrame);
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
#Override public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
JSObject win
= (JSObject) webEngine.executeScript("window");
// this next line registers the JavaApp class with the page... you can then call it from javascript using "app.method_name".
win.setMember("app", appREF);
}
}
});
You may not need the frame reference... I was hacking some of my own code to test this out and the ref was useful for other things...

How to download excel file from web application?

I'm using Wicket (not sure if it matters) but I'm using Workbook to create an excel file for a user to download. But I'm not sure how exactly to do this. What I would like to happen is the user clicks the button, a log is created and a prompt is given to the user to open (and save to temp files) or to save to their computer. The file is then deleted from the server side, or maybe it is stored in the User's session and deleted at end of session.
Can someone point me in the right direction? If I can have the file not saved in the session at all, that'd be create and have it just have it sent to the client using FileOutputStream somehow..
here is my current code:
private void excelCreator()
{
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("SSA User ID " + currentSSAIDSelection2.getSsaUserId()));
Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();
int i = 0;
while (auditLogEntrys.hasNext())
{
final AuditLogEntry auditLogEntry = auditLogEntrys.next();
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
row.createCell(1).setCellValue(auditLogEntry.getSourceName());
row.createCell(2).setCellValue(auditLogEntry.getCategory());
row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
row.createCell(4).setCellValue(auditLogEntry.getAction());
i++;
}
try
{
FileOutputStream output = new FileOutputStream("ssaUserIDAccess.xls");
workbook.write(output);
output.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
You would have to create a DownloadLink with the temporary file as input. The temporary File must be deleted after download (file.delete())).
Alternatively you can try this:
IResourceStream stream = new ByteArrayResourceStream(data, "application/vnd.ms-excel");
RequestCycle.get().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(stream, filename).setContentDisposition(ContentDisposition.ATTACHMENT));
In this case data is the byte[] content of your workbook which can be for example retrieved with output.toByteArray().
In case anyone runs into this problem here is my solution. There wasn't a lot of straight forward answers on this but this is my solution:
My excelCreator method handles the creation of the excel Sheet, and returns it as a file.
private File excelCreator()
{
Workbook workbook = new HSSFWorkbook();
File excelfile = new File("userIDAccess.xls");
logList = getServer().findAuditLogs(getUserId(), null);
Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("User ID " + getUserId()));
Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();
int i = 0;
while (auditLogEntrys.hasNext())
{
final AuditLogEntry auditLogEntry = auditLogEntrys.next();
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
row.createCell(1).setCellValue(auditLogEntry.getSourceName());
row.createCell(2).setCellValue(auditLogEntry.getCategory());
row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
row.createCell(4).setCellValue(auditLogEntry.getAction());
i++;
}
try
{
FileOutputStream output = new FileOutputStream(excelfile);
workbook.write(output);
output.close();
}catch(Exception e)
{
e.printStackTrace();
}
return excelfile;
}
IModel excelFileModel = new AbstractReadOnlyModel()
{
public Object getObject()
{
return excelCreator();
}
};
I created an IModel to capture the file created inside my excelCreator() method and returned.
auditDownloadlink = new DownloadLink("auditDownloadlink", excelFileModel);
I pass the I.D. of the download link, and then pass the imodel.
finally,
I call,
auditDownloadlink.setDeleteAfterDownload(true);
auditDownloadlink.setCacheDuration(Duration.NONE);
This deletes the file after it is created. And the cache setting is a setting to make sure it is compatible with all browsers (That's how I interpreted it, but you may not need it).
The Imodel creates the File on the fly so it doesn't have to be stored anywhere, and then the file is deleted once it is downloaded.
Hope this helps someone!
You could create a Resource to do this, and make a ResourceLink.
public class ExcelProducerResource extends AbstractResource
{
public ExcelProducerResource()
{
}
#Override
protected ResourceResponse newResourceResponse( Attributes attributes )
{
final String fileName = getFileName();
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
resourceResponse.setCacheDuration( Duration.NONE );
resourceResponse.setFileName( fileName );
resourceResponse.setWriteCallback( new WriteCallback()
{
#Override
public void writeData( Attributes attributes ) throws IOException
{
OutputStream outputStream = attributes.getResponse().getOutputStream();
writeToStream( outputStream );
outputStream.close();
}
} );
return resourceResponse;
}
void writeToStream(OutputStream outputStream) throws IOException
{
//.. do stuff here :)
}
String getFileName()
{
//.. do stuff here :)
}
}

How to embed a program inside another using GTK, XLib or any similar?

I'm trying to make a "simple" program, all it does is to list all opened programs and, once you choose one, it opens it inside your window (like a thumbnail you may say, but you can also interact).
One thing, it has to be one way only (I can't alter the embbeded program and add a "socket" or "plug" for instance). I want to be able to embbed any program (e.g. Opera, evince, JDownloader etc).
Does anyone have any idea of how can I do it?
If it can't be done using GTK, can it be done using X or any similar? How?
It appears that you're looking for something like XEmbed. A good tutorial in python and gtk is at http://www.moeraki.com/pygtktutorial/pygtk2tutorial/sec-PlugsAndSockets.html
You can use GtkPlug and GtkSocket for that.
using System;using Gtk;using System.Runtime.InteropServices; public partial class MainWindow : Gtk.Window{
public MainWindow () : base(Gtk.WindowType.Toplevel)
{
Gtk.Socket socket;
int xid;
Fixed fixed2=new Fixed();
this.socket = new Socket();
this.socket.WidthRequest = 500;
this.socket.HeightRequest = 500;
this.socket.Visible = true;
this.socket.Realized += new EventHandler(OnVideoWidgetRealized);
fixed2.Put(socket, 0, 0);
fixed2.SetSizeRequest(500,500);
this.Add(fixed2);
this.ShowAll();
OnButton17Clicked();
}
protected virtual void OnVideoWidgetRealized (object sender, EventArgs
args)
{
this.xid = (int)socket.Id;
Console.WriteLine("this.xid:"+this.xid);
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
this.socket = new Socket();
}
protected void OnButton17Clicked ()
{
var paramString = string.Format("-wid {0} 1.avi", xid);
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "mplayer.exe";
proc.StartInfo.Arguments = paramString;
proc.Start();
proc.WaitForExit();
}
public static void Main()
{
Application.Init();
new MainWindow();
Application.Run();
}}

Resources