UNIX设置扩展属性setxattr

时间:2015-08-10 12:22:47

标签: java unix attributes

- 如何在UNIX中编写UserDefinedFileAttributes?

- 如何在UNIX中设置setxattr?

我在UNIX服务器上使用Windows制作的java程序。作为此项的一部分,我使用UserDefinedFileAttributeView将扩展文件信息写入文件。

我有一个测试,看看文件系统是否支持UserDefinedFileAttributeView:

public static String[] supportedFileAttributeViews() {
    final FileSystem defaultFS = FileSystems.getDefault();
    return defaultFS.supportedFileAttributeViews()
           .toArray(new String[defaultFS.supportedFileAttributeViews().size()]);
}

在UNIX服务器上,这给了我:

"basic" "owner" "user"  "unix"  "dos"   "posix"

所以我想可以将UserDefinedFileAttributes写入文件( - >" user")

但如果java写入文件我会收到错误:

java.nio.file.FileSystemException: .... 
Error writing extended attribute 'test': Operation not supported
at sun.nio.fs.LinuxUserDefinedFileAttributeView.write
(LinuxUserDefinedFileAttributeView.java:246)
........

我编写UserDefinedFileAttributes的代码:

public static boolean writeCustomMETAfile(String filepath,String name, String value) {
    boolean succes = false;
    try {
        Path file = Paths.get(filepath);
        UserDefinedFileAttributeView userView = Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
        //userView.write(name, Charset.defaultCharset().encode(value));

         final byte[] bytes = value.getBytes("UTF-8");
         final ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
         writeBuffer.put(bytes);
         writeBuffer.flip();

        userView.write(name, writeBuffer);
        succes = true;

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return succes;
}

我一直在搜索StackOverflow和各种手册(UNIX)和其他网络资源,但现在没有运气了。

UNIX命令行上的

man 2 setxattr

给了我一些信息,我尝试了各种chmod设置。

它可能在i节点中吗?:

An i-node holds most of the metadata for a
Unix file — on classic Unix, it holds all but the
i-node number itself

所以问题是: - 如何在UNIX中编写UserDefinedFileAttributes /如何在UNIX中设置setxattr?

1 个答案:

答案 0 :(得分:1)

在下面找到一个小片段,它会在文件上读写xattr。 为简单起见,没有适当的异常处理。

Path path = Paths.get("/tmp/foobar");

// you should get the filestore for the path
FileStore fileStore = Files.getFileStore(path);
System.out.println("fileStore     : " + fileStore);

// check if the filesystem supports xattr
//
// I found out that the reported state might be wrong for ext3/ext4
//
// if you create following properties file it will be correct
// echo "ext4=user_attr" > $JAVA_HOME/lib/fstypes.properties
//
// keep in mind that it's possible that your ext3/ext4 does not support xattr
// might be related to: kernel configuration, mount options, etc.
boolean supportsXattr = fileStore.supportsFileAttributeView(UserDefinedFileAttributeView.class);
System.out.println("supports xattr: " + supportsXattr);

// get the file attribute view
UserDefinedFileAttributeView view = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
String xattrName = "xattr-foo";
String xattrValue = "dummy-value";

Charset defaultCharset = Charset.defaultCharset();
if (view.list().contains(xattrName)) {
    // get the size of the attribute value
    int xattrSize = view.size(xattrName);
    ByteBuffer buffer = ByteBuffer.allocateDirect(xattrSize);

    // read the attribute value
    int bytesRead = view.read(xattrName, buffer);

    // decode the buffer and print it
    buffer.flip();
    xattrValue = defaultCharset.decode(buffer).toString();
    System.out.println("xattr name    : " + xattrName);
    System.out.println("xattr value   : " + xattrValue);
} else {
// edit: System.out.println to System.out.printf in the next line
    System.out.printf("file has no xattr [%s]%n", xattrName);
}

// write the current value back reversed, can be checked next run
// or on command line
String newXattrValue = new StringBuilder(xattrValue).reverse().toString();
view.write(xattrName, defaultCharset.encode(newXattrValue);

编辑我在github上推了一个完整的例子。它也适用于Windws上的NTFS分区。

扩展属性可以在Linux上设置为

setfattr -n user.foo_name -v bar_value /tmp/foobar

可以检索为

getfattr -n user.foo_name /tmp/foobar