在Java 11上使用ShellFolder.getShellFolder()的替换或方式

问题描述 投票:0回答:1

我当前正在使用ShellFolder.getShellFolder()来确定是本地驱动器(直接连接到Windows计算机)还是远程驱动器上的特定路径。

package com.jthink.songkong.analyse.analyser;

import com.jthink.songkong.analyse.filename.WindowsFileSystem;
import com.jthink.songkong.ui.MainWindow;
import sun.awt.shell.ShellFolder;
import sun.awt.shell.ShellFolderColumnInfo;

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;

/**
 * Only Windows can load these methods because of reliance on sun classes
 *
 */
public class WindowsFilesystemType
{

    public static final String WINDOWS_SHELL_ATTRIBUTES = "Attributes";
    public static final String WINDOWS_SHELL_ITEM_TYPE = "Item type";
    public static final String WINDOWS_SHELL_SIZE = "Size";
    /**
     * Is Windows NTFS or FAT32
     *
     * @param newPath
     * @return
     */
    public static boolean isNTFSOrFAT32(String newPath)
    {
        Path root = Paths.get(newPath).getRoot();
        if (root == null)
        {
            return false;
        }
        try
        {
            FileStore fs = Files.getFileStore(root);
            if (fs.type().equals(WindowsFileSystem.NTFS)
                    || fs.type().equals(WindowsFileSystem.FAT)
                    || fs.type().equals(WindowsFileSystem.FAT32)
                    || fs.type().equals(WindowsFileSystem.EX_FAT))
            {
                return true;
            }
            return false;
        }
        catch (IOException ex)
        {
            MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
            return false;
        }
    }

    /**
     * Is this a remote drive, only works for Windows because relies on underlying Windows code
     *
     * @param newPath
     *
     * @return true if this a remote (Network) drive
     */
    public static boolean isRemote(String newPath)
    {
        try
        {
            Path root = Paths.get(newPath).getRoot();
            ShellFolder shellFolder = ShellFolder.getShellFolder(root.toFile());
            ShellFolderColumnInfo[] cols = shellFolder.getFolderColumns();
            for (int i = 0; i < cols.length; i++)
            {
                if (cols[i].getTitle().equals(WINDOWS_SHELL_SIZE)
                        &&  ((String) shellFolder.getFolderColumnValue(i)).startsWith(WindowsShellFileSystemType.NETWORK_DRIVE))
                {
                    return true;
                }
                else if (cols[i].getTitle().equals(WINDOWS_SHELL_ATTRIBUTES)
                        &&  ((String) shellFolder.getFolderColumnValue(i)).startsWith("\\"))
                {
                    return true;
                }
            }
        }
        catch (Exception ex)
        {
            return false;
        }
        return false;
    }

    /**
     * Is this a local drive, only works for Windows because relies on underlying Windows code
     *
     * @param newPath
     *
     * @return true if this a local drive
     */
    public static boolean isLocal(String newPath)
    {
        try
        {
            Path root = Paths.get(newPath).getRoot();
            ShellFolder shellFolder = ShellFolder.getShellFolder(root.toFile());
            ShellFolderColumnInfo[] cols = shellFolder.getFolderColumns();
            for (int i = 0; i < cols.length; i++)
            {
                if (cols[i].getTitle().equals(WINDOWS_SHELL_SIZE)
                        &&  ((String) shellFolder.getFolderColumnValue(i)).startsWith(WindowsShellFileSystemType.LOCAL_DISK))
                {
                    return true;
                }
                else if (cols[i].getTitle().equals(WINDOWS_SHELL_ATTRIBUTES)
                        &&  ((String) shellFolder.getFolderColumnValue(i)).startsWith("\\"))
                {
                    return false;
                }
            }
        }
        catch (Exception ex)
        {
            return true;
        }
        return true;
    }

}

在Java 8上工作正常

我现在正在迁移到Java 11,我正在使用maven编译项目,并且如果将用于编译器的source参数从8增加到9(或更高版本),则是

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <compilerVersion>11</compilerVersion>
                    <source>8</source>
                    <target>11</target>
                    <verbose>true</verbose>
                    <fork>true</fork>
                </configuration>
            </plugin>

由于引入了模块系统,编译失败(保持在8且将目标设置为11可以)

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] c:\Code\jthink\SongKong\src\main\java\com\jthink\songkong\analyse\analyser\WindowsFilesystemType.java:[5,14] error: package sun.awt.shell is not visible
  (package sun.awt.shell is declared in module java.desktop, which does not export it)
[ERROR] c:\Code\jthink\SongKong\src\main\java\com\jthink\songkong\analyse\analyser\WindowsFilesystemType.java:[6,14] error: package sun.awt.shell is not visible
  (package sun.awt.shell is declared in module java.desktop, which does not export it)
[INFO] 2 errors

所以,我正在寻找一种替代方法,或者:

  1. 是否有一种方法可以将src设置为11并允许通过使用某些模块选项进行编译
  2. 最好可以使用标准的Java库可靠地检测本地驱动器还是远程驱动器
java windows java-9 java-11 java.nio.file
1个回答
0
投票

目前看来,我在标准Java API中所需的功能似乎还无法替代(在Windows上标识路径是远程还是本地,这是确定的。

因此,选择是继续使用将来可能不存在的非公共类,还是编写hacky代码与将来可能会更改的操作系统命令(net)进行交互。

因此,务实的解决方案是让我继续使用非公共类,并希望将某些内容添加到公共api,如果没有,并且非公共类被删除,那么我将不得不编写代码来进行讨论净赚钱。

为了允许使用Maven在编译时访问此非公共类,我在编译器插件中添加了以下内容:>

 <compilerArgs>
     <arg>--add-exports=java.desktop/sun.awt.shell=ALL-UNNAMED</arg>
 </compilerArgs>

例如

   <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <encoding>UTF-8</encoding>
            <compilerVersion>11</compilerVersion>
            <source>11</source>
            <target>11</target>
            <verbose>true</verbose>
            <fork>true</fork>
            <compilerArgs>
                <arg>--add-exports=java.desktop/sun.awt.shell=ALL-UNNAMED</arg>
            </compilerArgs>
        </configuration>
    </plugin>
© www.soinside.com 2019 - 2024. All rights reserved.