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

来源:互联网 发布:纳什体测数据 编辑:程序博客网 时间:2024/05/16 10:15

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
感觉没有变化