Как определить тип диска (FileStore) в Windows?

145
26 января 2021, 05:40

Для объектов типа FileStore в Windows стандартными и широко известными методами легко определяется метка и буква тома, объем диска и свободного места, пример из документации:

    for (FileStore store: FileSystems.getDefault().getFileStores()) {
      long total = store.getTotalSpace() / 1024;
      long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
      long avail = store.getUsableSpace() / 1024;
      System.out.format("%-20s \t%,16d \t%,16d \t%,16d%n", store, total, used, avail);
    }

Но среди дисков есть локальные, съёмные, сетевые... Как отличить одни от других, например, если мне нужно обработать только локальные диски? У класса FileStore есть метод getAttribute(String attrName), которому нужно передавать имя атрибута, вот цитата из документации:

Suppose we want to know if ZFS compression is enabled (assuming the "zfs" view is supported):

boolean compression = (Boolean)fs.getAttribute("zfs:compression");

но какие AttributeView и какие имена атрибутов можно использовать в Windows, мне нигде найти не удалось.

Как можно отличить локальные диски от сетевых и т. п.? Можно ли без большого шаманства (типа запуска сторонних утилит и анализа их выдачи) получить еще какую-то информацию о дисках (физический диск, на котором располжен раздел, тип раздела...), доступную, например, утилите msinfo32.exe?

Answer 1

Можно использовать два варианта: использовать JACOB, воспользоваться FileStore классом или воспользоваться классом FileSystemView.

FileStore можно сделать так:

for (Path root : FileSystems.getDefault().getRootDirectories()) {
  FileStore fileStore = Files.getFileStore(root);
  System.out.format("%s\t%s\n", root, fileStore.getAttribute("volume:isRemovable"));
}

FileSystemView делается так:

File[] roots = File.listRoots();
FileSystemView fsv = FileSystemView.getFileSystemView();
for (File root : roots) {
    try {
        BasicFileAttributeView basicFileAttributeView = Files.getFileAttributeView(root.toPath(), BasicFileAttributeView.class);
        BasicFileAttributes attributes = basicFileAttributeView.readAttributes();
        System.out.println("File Key: " + attributes.fileKey());
        System.out.println("Is Regular File: " + attributes.isRegularFile());
        System.out.println("Is Other: " + attributes.isOther());
        System.out.println("Is SymbolicLink: " + attributes.isSymbolicLink());
        System.out.println("Is Directory: " + attributes.isDirectory());
        System.out.println("Drive Name: " + root);
        System.out.println("Description: " + fsv.getSystemTypeDescription(root));
        System.out.println("Is Drive: " + fsv.isDrive(root));
        System.out.println("Is File System: " + fsv.isFileSystem(root));
        System.out.println("Is File System Root: " + fsv.isFileSystemRoot(root));
        System.out.println("Is Floppy Drive: " + fsv.isFloppyDrive(root));
        System.out.println("Is Hidden File: " + fsv.isHiddenFile(root));
        System.out.println("Is Traversable: " + fsv.isTraversable(root));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Еще гайд как можно получить аттрибуты.

Источник

Вариант с JACOB:

import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class DrivesExample
{
    public interface HasNativeValue
    {
        int getNativeValue();
    }
    public enum DriveTypeEnum implements HasNativeValue
    {
        Unknown(0),
        NoRootDirectory(1),
        RemovableDisk(2),
        LocalDisk(3),
        NetworkDrive(4),
        CompactDisc(5),
        RAMDisk(6);
        public final int nativeValue;
        DriveTypeEnum(int nativeValue)
        {
            this.nativeValue = nativeValue;
        }
        public int getNativeValue()
        {
            return nativeValue;
        }
    }
    private static <T extends Enum<T> & HasNativeValue> T fromNative(Class<T> clazz, int value)
    {
        for (T c : clazz.getEnumConstants())
        {
            if (c.getNativeValue() == value)
            {
                return c;
            }
        }
        return null;
    }
    /**
     * The drive information.
     */
    public static final class Drive
    {
        /**
         * File system on the logical disk. Example: NTFS. null if not known.
         */
        public final String fileSystem;
        /**
         * Value that corresponds to the type of disk drive this logical disk represents.
         */
        public final DriveTypeEnum driveType;
        /**
         * The Java file, e.g. "C:\". Never null.
         */
        public final File file;
        public Drive(String fileSystem, DriveTypeEnum driveType, File file)
        {
            this.fileSystem = fileSystem;
            this.driveType = driveType;
            this.file = file;
        }
        @Override
        public String toString()
        {
            return "Drive{" + file + ": " + driveType + ", fileSystem=" + fileSystem + "}";
        }
    }
    /**
     * Lists all available Windows drives without actually touching them. This call should not block on cd-roms, floppies, network drives etc.
     *
     * @return a list of drives, never null, may be empty.
     */
    public static List<Drive> getDrives()
    {
        List<Drive> result = new ArrayList<>();
        ActiveXComponent axWMI = new ActiveXComponent("winmgmts://");
        try
        {
            Variant devices = axWMI.invoke("ExecQuery", new Variant("Select DeviceID,DriveType,FileSystem from Win32_LogicalDisk"));
            EnumVariant deviceList = new EnumVariant(devices.toDispatch());
            while (deviceList.hasMoreElements())
            {
                Dispatch item = deviceList.nextElement().toDispatch();
                String drive = Dispatch.call(item, "DeviceID").toString().toUpperCase();
                File file = new File(drive + "/");
                DriveTypeEnum driveType = fromNative(DriveTypeEnum.class, Dispatch.call(item, "DriveType").getInt());
                String fileSystem = Dispatch.call(item, "FileSystem").toString();
                result.add(new Drive(fileSystem, driveType, file));
            }
            return result;
        } finally
        {
            closeQuietly(axWMI);
        }
    }
    private static void closeQuietly(JacobObject jacobObject)
    {
        try
        {
            jacobObject.safeRelease();
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
    public static void main(String[] arguments)
    {
        List<Drive> drives = getDrives();
        for (Drive drive : drives)
        {
            System.out.println(drive.toString());
        }
    }
}

Пример вывода:

Drive{C:\: LocalDisk, fileSystem=NTFS}
Drive{D:\: LocalDisk, fileSystem=NTFS}
Drive{E:\: RemovableDisk, fileSystem=NTFS}
Drive{F:\: RemovableDisk, fileSystem=FAT32}
Drive{G:\: RemovableDisk, fileSystem=null}
Drive{Y:\: NetworkDrive, fileSystem=NTFS}

Чтобы использовать JACOB, добавьте JAR и DLL в виде библиотек в вашем проекте. Это решение только для Windows.

Источник Оригинальный вопрос

READ ALSO
Масштабирование ImageView

Масштабирование ImageView

Как можно реализовать ImageView c возможностью касаниями масштабировать изображения?(так же как в обычных фото галереях?)

148
Selenium и вложенные html-страницы

Selenium и вложенные html-страницы

Дело было вечером, делать было нечего

174
Проверка начертания ячейки Excel Apache POI

Проверка начертания ячейки Excel Apache POI

Как с помощью Apache POI проверить начертание ячейки, а именно применен ли полужирный стиль?

156
Интерфейс List и его реализация

Интерфейс List и его реализация

есть такое задание:

158