Is there a Java equivalent of GetCompressedFileSize?
我希望获得Java中稀疏文件的准确(即磁盘上的实际大小,而不是包括所有0的正常大小)的度量。
在Windows上的C ++中,将使用
如果没有直接的等效项,我将如何测量稀疏文件中的数据,而不是包括所有零的大小?
为了澄清起见,我希望它能在Linux OS和Windows上都运行备用文件测量,但是我不介意编写两个单独的应用程序!
如果您需要纯Java解决方案,则可以尝试jnr-posix。这是一个示例实现
1 2 3 4 5 6 | 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; |
但是当前该功能不适用于Windows。在解决该问题之前,您必须使用类似于以下平台的代码
-
在Linux上,使用
stat64 系统调用The st_blocks field indicates the number of blocks allocated to the file, 512-byte units. (This may be smaller than st_size/512 when the file has holes.)
-
您也可以运行
stat 命令。分配的块数可以在Blocks 字段中看到,或使用%b 格式说明符打印 -
或使用
du 命令(不带--apparent-size 选项)--apparent-size
- print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like
-
您也可以运行
-
在Windows上,您可以调用
GetCompressedFileSize API-
或者,您也可以使用管理员权限运行
fsutil file layout 以获取有关文件的详细信息。找到$DATA 流。-
如果看到居民|像这样的标志中没有分配群集,则它是一个驻留文件,磁盘上的大小将为0。
1
2
3
4
5
6
7
8
9
10
11
12
13PS 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 -
如果您没有看到常驻标志,请检查分配的大小字段,它是磁盘上文件的大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17PS D:\\> fsutil file layout .\
onresident.txt
********* File 0x000400000000084e *********
File reference number : 0x000400000000084e
File attributes : 0x00000020: Archive
File entry flags : 0x00000000
Link (ParentID: Name) : 0x0005000000000005: HLINK Name : \
onresident.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
-
-
有关更多信息,您可以阅读以下问题
- 如何查询"磁盘大小"文件信息?
- 获取磁盘上文件的大小
如果仅在Windows上执行此操作,则可以使用Java Native Interface编写它
1 2 3 |
并在C / C ++文件中:
1 2 3 4 5 6 7 8 9 10 11 | 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); } |
由于给出了针对Windows的答案。我将尝试提供Linux。
我不确定,但是我认为它将成功(C ++):
1 2 | #include <linux/fs.h> ioctl(file, BLKGETSIZE64, &file_size_in_bytes); |
可以用@Aniket答案(JNI)中描述的相同方式加载