« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9698752 建立时间:2004年12月20日 |

| |
[jvm]未公开的mustang核心秘密(一):java的FileSystem  原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2007/6/11 14:26:54 |
mustang提供得到硬盘空间的函数,这个我以前使用jni实现过,不过打算看看sun是如何做的java codeFile f = new File("e:/");// prints the volume size in bytes. System.out.println(f.getTotalSpace());// prints the total free bytes for the volume in bytes. System.out.println(f.getFreeSpace());// prints an accurate estimate of the total free (and available) bytes// on the volume. This method may return the same result as 'getFreeSpace()' on// some platforms. System.out.println(f.getUsableSpace());调用File.java,打开File.java发现static private FileSystem fs = FileSystem.getFileSystem();public long getTotalSpace() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); sm.checkRead(path); } return fs.getSpace(this, FileSystem.SPACE_TOTAL); }调用了FileSystem这是java没有公开的一个类,JavaDoc API没有。打开FileSystem.java,发现这是一个抽象类,里面没有实现。 /** * Return the FileSystem object representing this platform's local * filesystem. */ public static native FileSystem getFileSystem();这个是最重要的,打开jdk的源码#include <windows.h>#include "jni.h"#include "jni_util.h"
extern jboolean onNT;extern void initializeWindowsVersion();
JNIEXPORT jobject JNICALL Java_java_io_FileSystem_getFileSystem(JNIEnv *env, jclass ignored){ initializeWindowsVersion(); if (onNT) { return JNU_NewObjectByName(env, "java/io/WinNTFileSystem", "()V"); } else { return JNU_NewObjectByName(env, "java/io/Win32FileSystem", "()V"); }}看来调用了WinNTFileSystem和Win32FileSystem打开上面两个类的代码,发现 Win32FileSystem extends FileSystem,class WinNTFileSystem extends Win32FileSystem我们要看的代码在Win32FileSystem中实现了 /* -- Disk usage -- */ public long getSpace(File f, int t) { if (f.exists()) { File file = (f.isDirectory() ? f : f.getParentFile()); return getSpace0(file, t); } return 0; } private native long getSpace0(File f, int t);Win32FileSystem_md.c代码JNIEXPORT jlong JNICALL Java_java_io_Win32FileSystem_getSpace0(JNIEnv *env, jobject this, jobject file, jint t){ jlong rv = 0L; WITH_NATIVE_PATH(env, file, ids.path, path) { ULARGE_INTEGER totalSpace, freeSpace, usableSpace; if (GetDiskFreeSpaceEx(path, &usableSpace, &totalSpace, &freeSpace)) { switch(t) { case java_io_FileSystem_SPACE_TOTAL: rv = long_to_jlong(totalSpace.QuadPart); break; case java_io_FileSystem_SPACE_FREE: rv = long_to_jlong(freeSpace.QuadPart); break; case java_io_FileSystem_SPACE_USABLE: rv = long_to_jlong(usableSpace.QuadPart); break; default: assert(0); } } } END_NATIVE_PATH(env, path); return rv;}GetDiskFreeSpaceEx 函数• GetDiskFreeSpaceEx 可检索有关该对象存储或其他存储位置信息。• GetDiskFreeSpaceEx 函数定义如下: BOOL GetDiskFreeSpaceEx( LPCWSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfFreeBytes );• lpDirectoryName 是目录或通用命名约定 (UNC) 路径要检索存储信息的名称。 如果为 NULL, lpDirectoryName 调用返回对象存储信息。 • 其他三个参数是 出 参数, 它们返回以下信息: • lpFreeBytesAvailableToCaller : 返回的可用于调用函数字节数。• lpTotalNumberOfBytes : 返回存储设备的大小。• TotalNumberOfFreeBytes : 返回的可用字节数。
• 这些参数是指向结构键入包含两个 DWORD 字段, LowPart 和 HighPart ULARGE_INTEGER 。 此结构允许 GetDiskFreeSpaceEx 回到值更大存储设备。• 非 ZERO 返回代码指示成功。 ZERO 返回代码指示失败。long_to_jlong干嘛用的,jlong_md.h有说明#ifndef _WIN32_JLONG_MD_H_#define _WIN32_JLONG_MD_H_
/* Make sure ptrdiff_t is defined */#include <stddef.h>
#define jlong_high(a) ((jint)((a)>>32))#define jlong_low(a) ((jint)(a))#define jlong_add(a, b) ((a) + (b))#define jlong_and(a, b) ((a) & (b))#define jlong_div(a, b) ((a) / (b))#define jlong_mul(a, b) ((a) * (b))#define jlong_neg(a) (-(a))#define jlong_not(a) (~(a))#define jlong_or(a, b) ((a) | (b))#define jlong_shl(a, n) ((a) << (n))#define jlong_shr(a, n) ((a) >> (n))#define jlong_sub(a, b) ((a) - (b))#define jlong_xor(a, b) ((a) ^ (b))#define jlong_rem(a,b) ((a) % (b))
/* comparison operators */#define jlong_ltz(ll) ((ll) < 0)#define jlong_gez(ll) ((ll) >= 0)#define jlong_gtz(ll) ((ll) > 0)#define jlong_eqz(a) ((a) == 0)#define jlong_eq(a, b) ((a) == (b))#define jlong_ne(a,b) ((a) != (b))#define jlong_ge(a,b) ((a) >= (b))#define jlong_le(a,b) ((a) <= (b))#define jlong_lt(a,b) ((a) < (b))#define jlong_gt(a,b) ((a) > (b))
#define jlong_zero ((jlong) 0)#define jlong_one ((jlong) 1)#define jlong_minus_one ((jlong) -1)
/* For static variables initialized to zero */#define jlong_zero_init ((jlong) 0)
#ifdef _WIN64#define jlong_to_ptr(a) ((void*)(a))#define ptr_to_jlong(a) ((jlong)(a))#else/* Double casting to avoid warning messages looking for casting of *//* smaller sizes into pointers */#define jlong_to_ptr(a) ((void*)(int)(a))#define ptr_to_jlong(a) ((jlong)(int)(a))#endif
#define jint_to_jlong(a) ((jlong)(a))#define jlong_to_jint(a) ((jint)(a))
/* Useful on machines where jlong and jdouble have different endianness. */#define jlong_to_jdouble_bits(a)#define jdouble_to_jlong_bits(a)
#define jlong_to_int(a) ((int)(a))#define int_to_jlong(a) ((jlong)(a))#define jlong_to_uint(a) ((unsigned int)(a))#define uint_to_jlong(a) ((jlong)(a))#define jlong_to_ptrdiff(a) ((ptrdiff_t)(a))#define ptrdiff_to_jlong(a) ((jlong)(a))#define jlong_to_size(a) ((size_t)(a))#define size_to_jlong(a) ((jlong)(a))#define long_to_jlong(a) ((jlong)(a))
#endif感觉没有变化 |
|
|