Versioning or create Delta of File - java

I want to compare or get delta of two files that means if a file or directory has just been renamed or moved or changed into another folder will handle these operations like a deletion and subsequent file (re)creation, resulting in re-transmitting the entire file or even directory to the mirror location at the new location or with the new name or a file that made changes then how can i get that changes not the whole file.
How can i achieve this in java or android.

It sounds like you need something like rsync. There is a Java implementation
http://sourceforge.net/projects/jazsync/ so you might want to look into that. I'm not sure how stable it is or how well it works with Android.

Related

Read a file from same folder as JAR file but still read resources folder when loading from IDE

I've been trying to make jar application that can read a csv file in the same directory as it. This is, however, proving difficult as my means for accessing the file currently is:
InputStream is = getClass().getClassLoader().getResourceAsStream(filename);
Which works for my program running in the IDE and for my tests but doesn't work when I run the program from the compiled jar file. I have no idea how to get it to work for both. I seriously can't understand this path stuff, it seems like there are a million ways to do it and only one of them work for only one specific scenario.
I've been trying to make jar application that can read a csv file in the same directory as it.
Ah, there's your problem. That just isn't a thing.
There are only 2 types of files:
Application Resources
These are read only, and are as much part of your app as your class files are. It is not in any way relevant to think about 'editing' them - that's not the kind of thing they are. It is reasonable to assume that if this resource is somehow missing, the app is as corrupt / misinstalled as it would be if class files are missing.
For this, you use .getResource and .getResourceAsStream. And note that getClass().getClassLoader() is wrong, you want MyClass.class.getResource and then add a slash if you want to go from root (because getClass() potentially breaks when you subclass, and going via classloader is [A] just typing for no reason, and [B] breaks in bootload scenarios. MyOwnClassName.class.getResource never breaks, so, always use that).
This asks java to look in the same place class files are and nowhere else. Your class files are inside the jar files, and not next to them, therefore, it won't find a text file that is sitting next to jar files.
it does not make sense that it does work during development: That means you shoved a file inside the resources folder, which is equivalent to having a CSV file inside the jar file. You must have gone out of your way to tell your build system to do weird things. Don't do that.
If that CSV file is not intended to be user editable it should be inside the jar file and not next to it: That makes it an application resource. Examples of application resources:
You have a GUI, and you need to store the icon files and splash screen art and such someplace.
You ship static data with your app, such as a table of all US states along with the zipcodes they use (could be a text or csv file for example).
Templates of config files. Not config files themselves.
DLLs and the like that you need to unpack (because windows/linux/mac isn't going to look inside jars for them).
You're a webapp and you want to ship the HTML static files along with your webapp.
If this is what your CSV file is, the fix is to put it in the jar, not next to it, then load it with MyClass.class.getResource(name).
Config files and project files
For example:
For a rich text editor (like, say, LibreOffice Writer), the .odt files representing your writings.
Save games for a game.
A config file, which can be edited by the user, or is edited by your own app in a 'preferences' dialog. This stores for example whether to open the app full screen or not, or authentication info for a third party API you're using.
These should not be in the jar, should not be loaded with .getResource at all, and should not be in src/main/resources in the first place.
They also should not be next to your jar! That's an outdated and insecure model (the idea that editable files sit in the same place the app itself sits): A proper OS configuration means that an app cannot write to itself which is most easily accomplished by having it be incapable of writing to its directory. Some OSes (notably, windows) did this wrong for a while.
For example on windows, your app lives in C:\Program Files\MakorisAwesomeApp\makori.jar, and the data files for it live somewhere in C:\Users\UserThatInstalledIt\Documents\MakorisAwesomeApp.
oh linux, your app might be /usr/bin/makori and the data lives somewhere in the home dir. Config data might live in /etc/.
You don't "ship" your config files, you instead make installers that create them. You can do this part in-app by detecting that the relevant config file does not exist, load in a template (that is a resource, shipped inside your jar, loaded with getResource), and write it out, and tell the user to go look at it and edit it.
I really want a CSV file next to my jars!
Well, that's wrong, so, there are no libraries that make this easy. When you want to do silly things its good that APIs don't make that easy, right?
There are really hacky ways to do this. You can use .getResource to get a URL and then 'parse' this. This breaks the classloader abstraction concept (because in java, you can write your own classloaders and they can load from anywhere, not just files or entries in jars), but you can ask for 'yourself' (MyClass.class.getResource("MyClass.class")), pull the URL apart and figure out what's happening - does it start with file://? Then it is a file, so turn it into a j.i.File object, and go from there. Does it start with jar://? find the !, substring out the jar part, and now you know the jar. Make that a java.io.File, ask for the parent dir, and look there for the CSV.
You have to write all this. It's complicated code that is hard to test. You should not do this.

How to induce a timedelay when transferring the file from one directory to another by using twaitforfile or custom java code?

I am using talend to pickup file from source folder and transfer to the destination folder,however i want to pickup the file for processing only if the file is completely written in the source or not during/when the file is actively being copied into the source folder.
I realize that in talend when trying to move the file from source to dest. when the file is being still written into source folder-it shows an error message that "file is still being used by another proces" however i dont want that error to be triggered for each every run,i would want to skip and move to the next file in the iteration folder.
Can i use a twait or twaitforfile between components or add java code to handle it such that
"presenttime(sysdate)-filetime(arrivaltimeinto the folder)>timedifference(lets say around 3-5 minutes)"
Only if the condition is satisfied move the file to destination folder.
Please suggest which is the best efficient way to handle this.
In advanced settings of tWaitForFile, you have an option "WAIT_RELEASE" : you can set it, and when a file is detected, it will perform a 2d check XXXms after the first one, to make sure that the file is released (so that it is not actively being copied to the repository). When the file is fully copied, you are then able to use it.

Where and how to store text files for reading/writing

I have an app that accesses words from a csv text files. Since they usually do not change I have them placed inside a .jar file and read them using .getResourceAsStream call. I really like this approach since I do not have to place a bunch of files onto a user's computer - I just have one .jar file.
The problem is that I wanted to allow "admin" to add or delete the words within the application and then send the new version of the app to other users. This would happen very rarely (99.9% only read operations and 0.1% write). However, I found out that it is not possible to write to text files inside the .jar file. Is there any solution that would be appropriate for what I want and if so please explain it in detail as I'm still new to Java.
It is not possible because You can't change any content of a jar which is currently used by a JVM.
Better Choose alternate solution like keeping your jar file and text file within the same folder

Self exploding and rejaring jar file during execution

I am currently working on a program to make sitting charts for my teacher's classroom. I have put all of the data files in the jar. These are read in and put in to a table. After running the main function of the program, it updates the files to match what the tables values are. I know I need to explode the jar and then rejar it during excution in order to edit the files, but I can't find any explination on how to rejar during excution. Does anyone have any ideas?
Short answer:
Put data files outside of the binary and ship together with JAR in a separate folder.
Long one:
It seems like you are approaching the problem from the wrong direction. JAR file is something like an executable (.exe) on Windows platform - a read only binary containing code.
You can (although it is a bad practice) put some resources like data files, multimedia, etc. inside JAR (like you can inside .exe). But a better solution would be to place these resources outside of the binary so you can switch them without recompiling/rebuilding.
If you need to modify the resources on-the-fly while the application is running, you basically have no choice. The data files have to be outside the binary. Once again, you'll never see a Windows .exe file modifying itself while running.
Tomasz is right that the following is bad practice, but it is possible.
The contents of the classpath are read into memory during bootstrapping, however the files are modifiable but their changes will not be reflected after initialisation. I would recommend putting the data into another file, separate to your class files, but if you insist on keeping them together, you could look at:
JarInputStream or ZipInputStream to read the contents of the JAR file
Get the JarEntry for the appropriate file
Read and modify the contents as you desire
JarOutputStream or ZipOutputStream to write the contents back out
Make sure you're not reading the resource through the classpath and that it's coming from a file on disk / network.

How to make inotify wait when processing multiple files

I am working on a directory syncing program that uses jnotify to check for changes.
The idea is whenever jnotify detects a change, a sync is performed. The problem is that when many files are copied to or modified in a directory, many syncs are performed instead of one large sync.
Ideally if you were to copy 100 large files to directory A, the sync to directory B would not occur until all the files are fully copied to directory A.
I have thought about somehow using a temp directory (A1) to hold files until they are fully copied and then moving them into A1. But this solution does not work well because I am using unison to perform the sync which only sends file deltas - and that is a feature I would like to use and not circumvent.
Perhaps there is a way to use i/jnotify to detect when multiple files are being updated at once?
Here's a suggestion. How about setting up a set on your application and have it collect up "modified" files/etc it would add that file to a set and when the number of files exceed a certain amount of number, say 100, you would then do a sync. It would also be a good idea to set up a timer too if you want it to be reasonable responsive, like if there is no new changes/etc that is being added to the set for X amount of time go ahead and do a sync also.

Categories

Resources