I'm trying to find a way to keep track of files even when they are moved or renamed in the file system.
One idea I had was to use the new UserDefinedFileAttributeView in Java 7 and create a custom file attribute as a sort of custom id. I thought that this might work on different platforms (Windows and Mac primarily). But I can't get it to work. Even trying the example on this page - http://docs.oracle.com/javase/tutorial/essential/io/fileAttr.html - When I get to this line:
UserDefinedFileAttributeView view = Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
I only get a null value for the view variable, and then the program stops with a nullpointer exception.
I then found that there is a perhaps easier way to do this for Mac at least: use the BasicFileAttributes fileKey attribute. I tried this, and the fileKey seems to stay the same even if I move the file or rename it. However, it also says that this functionality is platform dependent, and I remember reading somewhere that it doesn't work on Windows...
So first of all, is the fileKey method a stable way of doing this on Mac? And if so, what can I do for the same functionality for Windows? Anyone know why I get null on the UserDefinedFileAttributeView? Because if I could get that to work it should be cross-platform I guess.
This is not something that needs to be super robust and scalable, it is just a small helper application I'm developing, but it needs to be at least reliable in identifying files when moved or renamed...
I tried the Oracle example on a Windows XP computer. There was a very minor bug in the code example, but other than this, the code worked fine -- at least on Windows XP. Hopefully it would also work on Linux etc, but I personally have only tried it on Windows XP.
public static void main(String args[])
throws Exception
{
Path target = Paths.get("C:\\mytemp\\Something.txt");
Files.createFile(target);
UserDefinedFileAttributeView view = Files.getFileAttributeView(target, UserDefinedFileAttributeView.class);
view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
String name = "user.mimetype";
ByteBuffer buf = ByteBuffer.allocate(view.size(name));
view.read(name, buf);
buf.flip();
String value = Charset.defaultCharset().decode(buf).toString();
System.out.println("value="+value);
Just to be sure the attribute was not just being read from the view, I also ran the same code using a 2nd view. This also worked...
public static void main(String args[])
throws Exception
{
Path target = Paths.get("C:\\mytemp\\SomethingDifferent.txt");
Files.createFile(target);
UserDefinedFileAttributeView view = Files.getFileAttributeView(target, UserDefinedFileAttributeView.class);
view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
String name = "user.mimetype";
UserDefinedFileAttributeView view2 = Files.getFileAttributeView(target, UserDefinedFileAttributeView.class);
ByteBuffer buf = ByteBuffer.allocate(view2.size(name));
view2.read(name, buf);
buf.flip();
String value = Charset.defaultCharset().decode(buf).toString();
System.out.println("value="+value);
}
It would be great if such custom file attributes work across all the major platforms, as such custom file attributes are incredibly handy in some situations. Hope they do.
This is not implemented on the OSX version of Java. This bug is still open: https://bugs.openjdk.java.net/browse/JDK-8030048
This bug was closed, https://bugs.openjdk.java.net/browse/JDK-8040830, with a reference to use a 3rd party workaround (which I haven't tried): https://github.com/IsNull/xattrj