如何区分没有扩展名的空文件和java中的目录?

How to differentiate between an empty file that has no extension and a directory in java?

假设我有一个包含两个元素的 zip 文件:elem1(由 linux 命令 touch elem1 创建)和 elem2(由 linux 命令 mkdir elem2 创建)

现在,在 java 中,我使用以下代码提取 zip

的内容
// ...
// Suppose we have a valid inputStream on a zip file
// ...

ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry entry = zipInputStream.getNextEntry();

while (entry != null) {
    int entrySize = (int) entry.getSize();
    File file = Paths.get(extractPath).resolve(entry.getName()).toFile();
    if (/*Condition to detect a directory*/) {
        System.out.println("This is a directory");
        FileUtils.forceMkdir(file);
    } else if (/*Condition to detect an empty file*/) {
        System.out.println("This is an empty file");
    } else {
        System.out.println("This is something else");
    }

    entry = zipInputStream.getNextEntry();
}

我想指定正确的条件来检测 entry 是一个目录,还是一个没有扩展名的空文件。知道这些条目仍在内存中并且不存在于文件系统中,命令 file.isDirectory() 总是 returns false;所以我不能不使用它来检查目录。

有什么想法吗?

我创建了一个空文件夹和一个没有扩展名的空文件,并使用以下代码对其进行了评估:

public static void main(String[] args) {
    String path = System.getProperty("user.home") + File.separator + "Desktop" + File.separator;
    File file = new File(path + "EmptyFile");
    File folder = new File (path + "EmptyFolder");
        
    System.out.println("Is 'folder' a folder? " + (Files.isDirectory(folder.toPath())? "Yes" : "No" ));
    System.out.println("Is 'file' a folder? " + (Files.isDirectory(file.toPath())? "Yes" : "No" ));
}

(不足为奇)结果:

Is 'folder' a folder? Yes
Is 'file' a folder? No

之所以可行,是因为函数 Files.isDirectory(...) 查看操作系统设置的文件属性,以确定正在检查的项目是“文件夹”还是仅仅是“文件”。我的假设是 Zip 程序不包含此类元数据(甚至 Windows zip 也不包含)。因此,不能使用Files.isDirectory(...)函数执行“isDirectory”测试。我的快速研究发现,执行此操作的方法(我有点震惊)是检查文件名并检查名称是否以文件分隔符结尾。事实上,这就是 ZipEntry.isDirectory() 的工作原理。

Windows 压缩不允许尝试压缩空文件夹(其他软件可能允许?)。但是,我能够使用 7-zip 包含空目录。这不是唯一的区别。当使用 Windows zip 创建 zip 时,isDirectory() 测试失败,因为文件被完全跳过。因此,为了使其正常工作,使用 Windows 附带的 zip 软件以外的 zip 软件创建 zip 文件。那么,

public static void main(String[] args) throws IOException {
    String path = System.getProperty("user.home") + File.separator + "Desktop" + File.separator;
    FileInputStream inputStream = new FileInputStream(path + "Desktop.zip");
    ZipInputStream zipInputStream = new ZipInputStream(inputStream);
    ZipEntry entry = zipInputStream.getNextEntry();

    while (entry != null) {
        File file = Paths.get(entry.getName()).toFile();
            
        if (entry.isDirectory()) {
            System.out.println(entry.getName() + " is a directory");
        } else if (file.getName().endsWith(".lnk")) {
            System.out.println(file.getName() + " is a shortcut");
        } else {
            System.out.println(entry.getName() + " is a file");
        }
            entry = zipInputStream.getNextEntry();
    }
    zipInputStream.close();
}

我的输出:

EmptyFile is a file
EmptyFolder/ is a directory
How We Test Wireless Routers _ PCMag_files/ is a directory
How We Test Wireless Routers _ PCMag_files/00hSyhn9j5PNrcOot1tMzz9.1578945749.fit_lim.size_100x100.png is a file
...
etc

最后一点……显然,如果 ZipEntry 不是目录,它就是文件。因此,不需要 else if。也就是说,除非您想区分文件类型。在上面的例子中,我想检查一个特定的文件是否是一个快捷方式。请记住,这不是必需的。该逻辑应该只测试 isDirectory 的条目,如果测试失败,它只是一个文件。