gpt4 book ai didi

Java NTFS 压缩属性

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:06:08 25 4
gpt4 key购买 nike

我需要从 Java 读取和修改 NTFS 分区上文件的“压缩”属性。我在 java.nio.file.attribute 中想象了一些东西package 可以做到——见鬼,它是一个足够复杂的包,但我找不到这个属性。

DosFileAttributes 类只有经典的 hidden/system/readonly/archive 属性的 getter。

我试过了 Files.readAttributes它允许从特定的“属性 View ”动态检索所有属性。在“dos:*”下,只有 DosFileAttributes 类的公共(public)方法已经可用的相同属性。我尝试了“ntfs:*”和“windows:*”,但它们没有被接受为有效的 View 名称。

我也尝试了 UserDefinedFileAttributeView,但它在我尝试过的任何文件上都给了我一个空列表。

我想知道是否要支付给 attrib命令(接受它不适用于安装在 Linux 或其他操作系统下的 NTFS 分区的限制)但它似乎也不支持该属性。帮忙?

最佳答案

由于标准 Java API 似乎确实缺少此功能,因此我查看了自己使用 JNA 进行的操作.这是我第一次使用 JNA。它没有我想要的那么漂亮,而且 JNA 的代码似乎非常缺乏泛型,但它比使用 JNI 并尝试为所需的不同平台(最低 x86 和 x64)设置糟糕的交叉编译器要好一百倍即使您只针对一个操作系统)。最初是烦人的编译过程驱使我从 C++ 转向 Java,我希望永远不必回到它。

无论如何,这似乎可行。希望它对其他人也有用。它提供了四种公共(public)方法:

  • isAvailable() -- 调用其他方法是否有效(即,我们在 Windows 上并且 JNA native 库加载正常)
  • isCompressed(文件)
  • setCompressed(文件, boolean 值)
  • volumeSupportsFileCompression(File) -- 询问 Windows 文件所在的分区是否支持 [单个] 文件压缩。例如,在 NTFS 上为真,在 FAT(U 盘等)上为假。

Windows API 中的压缩是通过专用的 I/O 控制操作完成的,而不仅仅是“SetAttributes”调用。如果它更简单(与其他文件属性同构),为了完整起见,我也会将加密属性放在那里,但无论如何。

import java.io.File;
import java.io.IOException;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.ShortByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT.HANDLE;

public class WindowsFileOps {
private WindowsFileOps() {}


private static interface Kernel32Extra extends StdCallLibrary {
int COMPRESSION_FORMAT_NONE = 0x00000000;
int COMPRESSION_FORMAT_DEFAULT = 0x00000001;
int FSCTL_SET_COMPRESSION = 0x0009C040;

Kernel32Extra INSTANCE = (Kernel32Extra)Native.loadLibrary("kernel32",
Kernel32Extra.class, W32APIOptions.UNICODE_OPTIONS);

boolean GetVolumeInformation(
String lpRootPathName,
Pointer lpVolumeNameBuffer,
int nVolumeNameSize,
IntByReference lpVolumeSerialNumber,
IntByReference lpMaximumComponentLength,
IntByReference lpFileSystemFlags,
Pointer lpFileSystemNameBuffer,
int nFileSystemNameSize
);
}


private static Boolean isAvailable;
public static boolean isAvailable() {
if (isAvailable == null) {
try {
isAvailable = Kernel32.INSTANCE != null && Kernel32Extra.INSTANCE != null;
} catch (Throwable t) {
isAvailable = false;
}
}
return isAvailable;
}


private static String pathString(File file) {
// "\\?\" is a Windows API thing that enables paths longer than 260 chars
return "\\\\?\\" + file.getAbsolutePath();
}


private static int getAttributes(File file) throws IOException {
int attrib = Kernel32.INSTANCE.GetFileAttributes(pathString(file));
if (attrib == Kernel32.INVALID_FILE_ATTRIBUTES) {
throw new IOException("Unable to read file attributes of " + file);
}
return attrib;
}


public static boolean isCompressed(File file) throws IOException {
return (getAttributes(file) & Kernel32.FILE_ATTRIBUTE_COMPRESSED) != 0;
}


public static void setCompressed(File file, boolean compressed) throws IOException {
HANDLE hFile = Kernel32.INSTANCE.CreateFile(
pathString(file),
Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE,
Kernel32.FILE_SHARE_READ,
null,
Kernel32.OPEN_EXISTING,
0,
null);
try {
if (!Kernel32.INSTANCE.DeviceIoControl(
hFile,
Kernel32Extra.FSCTL_SET_COMPRESSION,
new ShortByReference((short)(
compressed
? Kernel32Extra.COMPRESSION_FORMAT_DEFAULT
: Kernel32Extra.COMPRESSION_FORMAT_NONE
)).getPointer(),
2,
null, 0,
new IntByReference(),
null
)) throw new IOException("Unable to alter compression attribute of " + file);
} finally {
Kernel32.INSTANCE.CloseHandle(hFile);
}
}


public static boolean volumeSupportsFileCompression(File file) throws IOException {
IntByReference flags = new IntByReference();
if (!Kernel32Extra.INSTANCE.GetVolumeInformation(
pathString(file.getAbsoluteFile().toPath().getRoot().toFile()),
null, 0,
null,
null,
flags,
null, 0
)) throw new IOException("GetVolumeInformation failure");
return (flags.getValue() & Kernel32.FILE_FILE_COMPRESSION) != 0;
}
}

关于Java NTFS 压缩属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19401889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com