Get information about changed file in Java - java

I'm trying to monitor files in java. When a file modification will happen I want to know:
Which process did the change.
What has changed.
Also, I know that there is a way to change the "last modified date" in a file, so I want to check if someone has changed that field.
I tried "commons.io", "DefaultFileMonitor" and "WatchService", but all the information I could get from them was if a change has occurred and the file that was changed.

Unless you're on a weird OS I know absolutely nothing about, you would need to use some mechanism you implement to track who is changing your file. The OS doesn't keep track of that. It also doesn't track what has changed.
So I don't believe you can do #1 unless you can get every process that MIGHT change the file to track that it did a change.
You could do #2 if you kept copies of the file then do a comparison.

I am pretty sure you cannot do that. Neither OS nor Java is storing such information. Maybe using some kernel calls.

Related

How to read from a file that is in use

There's a file I wanted to get into, but whenever I try to open it I get the message "The process cannot access the file because it is being used by another process".
Well, I want in! So, how can i do it?
I've been brainstorming a few ways to try, I'm hoping to get some input on other ways, or if my ideas wouldn't work for some reason that is not apparent to me.
Idea 1 The folder knows where the file is, it just won't open it. What if I create a program to read from the memory address of the file, copy it, then rebuild it somewhere else? I'm not sure if this has hope, because it relies on the file being the issue.
Idea 2 How does my process know that another process is using the file? If it's checking against all the other processes, maybe I can also figure out which process is using that file and pause it or end it.
Either of these ideas will probably take me weeks. Is anyone more creative and can think of another way; or more knowledgeable and eliminate an impractical idea?
In Windows, applications are allowed to obtain exclusive locks on files. When the process opens the file, one thing you specify is who else can access it while your process does (those are the .NET methods, but equivalents exist in other languages). Excel, for example, is notorious for getting an exclusive lock when you open a file. The way around it is usually to find the offending process and kill it to break the lock. Unlocker is the app that I'm most familiar with to accomplish this. If the process is a System process, however, you may not be able to kill it. You'd have to reboot to reset the lock.
Reading directly from another process's memory is unlikely to be reliable. The application may not have an in-memory copy, may not have a complete in memory copy, may not have a consistent in memory copy, and may not have an in memory copy that matches what's on disk (If they're editing the document, for example).
Your process knows that the file is locked because when it tries to open the file, it does so by asking the operating system for access to the file. The operating system responds saying, "Request denied. Another process has this file open and locked." The OS doesn't tell your process what process has the file open because trying to open a file doesn't include asking for who already has it open. Your process must ask the right question to get the answer you're looking for.
Windows makes you specify a sharing modes when opening a file. The sharing mode may prevent the file from being read, written, or deleted while you have it open. If you want to allow simultaneous read access you should include FILE_SHARE_READ in the dwShareMode parameter when you call CreateFile (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx).
In other words, if you want to enable concurrent access to an open file you must modify the way the file is opened in the first place.
The portable standard libraries in C and Java don't offer a way to set the sharing mode when opening a file, but their usual implementations on windows set the sharing mode to READ+WRITE.

Undo file/folder operation using java

I am looking to implement undo/redo file/folder functionality for edit/delete/move etc using java. Is that possible ?
Detail: I am watching a given folder using javaFileWatcher, i get a message from watcher that if any file/folder created/edited/deleted/renamed. now i want if any user has deleted/created any file/folder i would be able to undo it using java. can any one help.
Note: I am using windows
Thanks in advance.
Not possible, a delete is final, there is no recycle bin like in the OS, you have to implement it by yourself.
As a kickoff idea have a look at the Command pattern. This is usually how undo/redo things are implemented. The idea is that you kind of store everything that is "important" about an operation into a single object and you store those in an ordered collection.
In your case the fact that you want to monitor the FS and not your own data model makes things really hard. However if you can afford redundant data storage then hypothetically it can be done I think. (I suggest you reading about the way git SCM works. I mean that it stores everything in a single .git folder and it is capable of restoring any previous state in its so called working directory from the compressed data it stores.)
Actually if you could involve git into your program then it would be much easier. I am thinking that you have a git repo initialized in the directory that you want to supervise and then every time that you are being notified about some FS change, you can ask git (git status) to tell you which files got changed actually. Even deleted file can be restored then using simple git commands.
This is far from a complete answer to your question however I might have given some ideas. Good luck.

Keeping track of a file in java 1.6

I want to keep track of multiple files in a location in a unix box, and delete them if no one is using them for a long time.
I am trying to search for reference counting but did not get much help on google.
I also saw FileTime in java 7 which can give me the last accessed time , but i have to the above work using java 6.
If anyone has any ideas or good reference to reference counting and how i can use it, it will be great.
You can use apache common IO. Set observer on your dir which checks the dir and notifying listeners of create, change or delete eventslisten. By this it is possible to track on which dir has been working by user and others are not.
Okay, so we want last access time.
You can have a read of Get the Last Access Time for a File for some further info.
You could try and have a look at http://jdevel.wordpress.com/2011/04/08/file-last-access-time-in-java-on-linux/ for a possible soultion, but this is Linux, not Unix.
Finally, you could borrow the same idea and use JNA or JNI
There is no module for File watching till JDK 1.6. What you can do is, you can write your own file watcher by seeing the
lastModified() method of the java.io.File class.
It returns you the last modified time as a long value and you keep a watch on this file during a regular interval. If the total time difference
(presentTime - lastModifiedTime)
exceeds you time criteria, you can delete the file.

How do I get my Etherpad changes to show up?

I change files like /etherpad/trunk/infrastructure/ace/www/ace2_inner.js and then run /etherpad/trunk/etherpad/rebuildjar.sh and yet when I run it again everything looks the same. Is there a trick I'm missing?
I've also tried running rebuildjar.sh with clearcache to no avail.
Look at bin/build.sh and track down which scripts are called directly and which scripts are called via subscripts. The whole thing is a mess :/
ace2_inner is perhaps one of the autogenerated .js files? What you need to do is read the first 10-20 lines of every source code file before you edit it, to make sure you're not editing an autogenerated file.
If you don't know the structure, then use bin/build.sh every time until you learn how to handle the source code. (This advice isn't actually etherpad-specific :)
And then make sure you've STOPPED all etherpad servers before starting up a new one.
Always clear the browser cache properly after changing the etherpad files. Otherwise none of your changes will show up.

Edit files single line in java

I'm trying to edit configuration file in Java. What I really need to do is to change single line, so reading the whole file and writing it back would be waste of time, since configuration file can be big.
Is there a more efficient way to do this? Except reading in/editing/writing out file. I thouhgt of converting entire file to string, replacing the line I want and writting it back.
I don't know how efficient would that be, can someone give me some other suggestions or the one I mentioned are ok, execution time is important.
I would recommend to use the Preferences API instead. Then on the Windows platform your preferences is stored in the registry. On other platforms the corresponding way to save application preferences is used. See also Preferences API Overview.
How big of a configuration file are we talking here? 1k lines? 10k? 1m lines? If the line you want to edit is the last line, just seek to the start of the line, truncate the file there and write the new one. If it's not... you will need to read it whole and write it again.
Oh, and the 2 options you mention are actually the same (read/edit/write).
On the third hand, I think it's irrelevant (unless you have weird constraints, like a flash storage device which takes too long to write, and has limited write cycles), given the sizes of most config files.

Categories

Resources