【问题标题】:Is there a Java equivalent of GetCompressedFileSize?是否有与 GetCompressedFileSize 等效的 Java?
【发布时间】:2013-02-06 17:46:01
【问题描述】:

我希望获得 Java 中稀疏文件的准确(即磁盘上的实际大小,而不是包含所有 0 的正常大小)的测量结果。

在 Windows 上的 C++ 中,可以使用 GetCompressedFileSize。我还没有想到如何在 Java 中做到这一点?

如果没有直接的等价物,我将如何测量稀疏文件中的数据,而不是包括所有零的大小?

为澄清起见,我希望在 Linux 操作系统和 Windows 上运行稀疏文件测量,但我不介意编写两个单独的应用程序!

【问题讨论】:

  • 我假设您的平台是 Windows?
  • 嗨迈克尔,我已经编辑了我的问题来回答这个问题。谢谢
  • 我已经为 Linux 添加了一个答案,虽然我不确定是否 100%
  • @Robᵩ 我不认为这是重复的,因为编辑后的问题需要 Windows 和 linux 的解决方案,所以它不能只调用 Win32 函数。

标签: java filesize sparse-file on-disk compressed-files


【解决方案1】:

如果您想要纯 Java 解决方案,您可以尝试jnr-posix。这是example implementation

import jnr.posix.*;

final POSIX p = POSIXFactory.getPOSIX();
final int S_BLKSIZE = 512; // from sys/stat.h
final FileStat stat = p.stat("/path/to/file");
final long bytes = stat.blocks() * S_BLKSIZE;

但是目前函数won't work for Windows。在解决此问题之前,您必须使用以下特定于平台的代码

  • 在 Linux 上使用 stat64 系统调用

    st_blocks 字段表示分配给文件的块数,以 512 字节为单位。 (当文件有洞时,这可能小于 st_size/512。)

    • 您也可以运行stat 命令。分配块的数量可以在Blocks 字段中看到,或使用%b 格式说明符打印
    • 或者使用du command(没有--apparent-size选项)

      --表观尺寸

      • 打印外观尺寸,而不是磁盘使用情况;尽管表观大小通常较小,但由于(“稀疏”)文件中的漏洞、内部碎片、间接块等原因,它可能会更大
  • 在 Windows 上,您可以调用 GetCompressedFileSize API

    • 或者,您也可以使用管理员权限运行 fsutil file layout 以获取有关文件的详细信息。找到$DATA 流。

      • 如果您看到 居民 |在这样的标志中没有分配集群,那么它是一个常驻文件,磁盘上的大小将为 0。

        PS C:\Users>  fsutil file layout .\desktop.ini
        
        ********* File 0x000800000003dbde *********
        File reference number   : 0x000800000003dbde
        File attributes         : 0x00000026: Hidden | System | Archive
        File entry flags        : 0x00000000
        Link (ParentID: Name)   : 0x001f0000000238c8: HLINK Name   : \Users\desktop.ini
        ...
        Stream                  : 0x080  ::$DATA
            Attributes          : 0x00000000: *NONE*
            Flags               : 0x0000000c: Resident | No clusters allocated
            Size                : 174
            Allocated Size      : 176
        
      • 如果您没有看到 resident 标志,请检查 Allocated Size 字段,这是文件在磁盘上的大小

        PS D:\>  fsutil file layout .\nonresident.txt
        
        ********* File 0x000400000000084e *********
        File reference number   : 0x000400000000084e
        File attributes         : 0x00000020: Archive
        File entry flags        : 0x00000000
        Link (ParentID: Name)   : 0x0005000000000005: HLINK Name   : \nonresident.txt
        ...
        Stream                  : 0x080  ::$DATA
            Attributes          : 0x00000000: *NONE*
            Flags               : 0x00000000: *NONE*
            Size                : 1,520
            Allocated Size      : 4,096
            Extents             : 1 Extents
                                : 1: VCN: 0 Clusters: 1 LCN: 1,497,204
        

有关更多信息,您可以阅读以下问题

【讨论】:

    【解决方案2】:

    如果你是单独在 Windows 上做,你可以用 Java Native Interface 来写

    class NativeInterface{
       public static native long GetCompressedFileSize(String filename);
    }
    

    在 C/C++ 文件中:

    extern "C"
    JNIEXPORT jlong JNICALL Java_NativeInterface_GetCompressedFileSize
      (JNIEnv *env, jobject obj, jstring javaString)
    {
        const char *nativeString = env->GetStringUTFChars(javaString, 0);
     
        char buffer[512];
        strcpy(buffer, nativeString);
        env->ReleaseStringUTFChars(javaString, nativeString);
        return (jlong) GetCompressedFileSize(buffer, NULL);
    }
    

    【讨论】:

      【解决方案3】:

      自从给出了针对 windows 的答案。我会尝试为 Linux 提供。

      我不确定,但我认为它会成功(C++):

      #include <linux/fs.h>
      ioctl(file, BLKGETSIZE64, &file_size_in_bytes);
      

      这可以按照@Aniket 答案 (JNI) 中描述的相同方式加载

      猜你喜欢
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2013-06-07
      • 2010-12-19
      • 2012-03-15
      相关资源
      最近更新 更多