未公开的mustang核心秘密(一):java的FileSystem 

本文详细解析了Java中获取硬盘空间的方法,通过跟踪源码,介绍了如何利用JNI调用Windows API来获取硬盘总空间、可用空间等信息。

mustang提供得到硬盘空间的函数,这个我以前使用jni实现过,不过打算看看sun是如何做的
java code
File 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
感觉没有变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值