- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在使用 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
所以我正在寻找一种替代方法:
我需要 isLocal() 的原因是我的程序重命名文件,并且用户可以选择将路径长度限制为 259 个字符,因为较长的长度会导致 Windows 资源管理器出现问题,但如果他们正在修改远程驱动器,则不会通常为了执行此要求,我将向问题添加更多详细信息。
例如,如果音乐文件位于 Windows 使用的本地驱动器上,应用程序会重命名它们,那么他们可能希望强制执行该限制。但如果它是网络驱动器,他们可能不会,因为文件通常存储在 Nas 上,并且他们只能通过 Windows 访问文件,因为我的应用程序可以在 Windows 上运行,但不能在 Nas 上运行。
最佳答案
目前标准 Java API 中我需要的功能似乎没有替代品(在 Windows 上识别路径是远程还是本地)。
因此,选择是继续使用将来可能不存在的非公共(public)类,还是编写黑客代码来与将来可能会更改的操作系统命令( net
)进行交互。
所以实用的解决方案是我继续使用非公共(public)类,并希望在公共(public)API中添加一些东西,如果不是并且非公共(public)类被删除,那么我将不得不编写代码此时与网络交谈。
为了允许在编译时使用 Maven 访问这个非公共(public)类,我在编译器插件中添加了以下内容
<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>
不幸的是,这个解决方案在 java 17 以后失败了,我查看了 sun shell 类,看看是否可以复制它们,sun.awt.shell 没问题,但 Windows 实现依赖于非 java 库
static {
// Load library here
sun.awt.windows.WToolkit.loadLibraries();
}
所以这是一个问题。
创建了以下内容,但仅仅依靠猜测是不可靠的
public class WindowsFilesystemType
{
public static final String WINDOWS_SHELL_ATTRIBUTES = "Attributes";
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 local drive, only works for Windows machine
*
* TODO unreliable since moved to Java 17
*
* @param newPath
*
* @return true if this a local drive
*/
public static boolean isLocal(String newPath)
{
//If not a windows fs unlikely to be local drive
if(!isNTFSOrFAT32(newPath))
{
return false;
}
//Mapped \\ must be network drive ?
Path root = Paths.get(newPath).getRoot();
if (root.toString().startsWith("\\"))
{
return false;
}
//Low drive letter assume local
root = Paths.get(newPath).getRoot();
if (
(root.toString().equals("C:\\"))||
(root.toString().equals("D:\\"))||
(root.toString().equals("E:\\"))||
(root.toString().equals("F:\\"))
)
{
return true;
}
//Assume network then if higher drive letter
return false;
}
}
关于java - Java 11 上 ShellFolder.getShellFolder() 的替换或使用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61139440/
我目前正在使用 ShellFolder.getShellFolder() 来确定特定路径是位于本地驱动器(直接连接到 Windows 计算机)还是远程驱动器。 package com.jthink.s
我是一名优秀的程序员,十分优秀!