一、序言

IO操作,才程序中比较普遍,JAVA 中提出了IO/NIO 的概念,也一直在说NIO 比IO快,一直不知道原因,就想memcache 和ehcache 比较优劣一样,这些东西得自己看看如何实现的,才 知道区别,从而才知道优劣以及试用范围,而不仅仅是“听说”!这里我可以先了解下JAVA 如何操作IO的。

二、代码示例

我们先看看简单文件操作:

// 这是将文件转换成输入流的的一种方式,获得了流我们就能干很多事

FileInputStream in = new FileInputStream(new File("...file"));

再看看FileInputStream 的源码:

public FileInputStream(File file) throws FileNotFoundException {

String name = (file != null ? file.getPath() : null);

// 安全管理器,这里暂时不说

SecurityManager security = System.getSecurityManager();

if (security != null) {

// 检查是否可以按这名字读取

security.checkRead(name);

}

if (name == null) {

throw new NullPointerException();

}

// 获得文件描述,这个JDK 未公布

fd = new FileDescriptor();

// 打开文件,这是个native 方法,我们可以用openjdk 看看里面

open(name);

}

在FileInputStream.c下可以找到方法

// open 方法

JNIEXPORT void JNICALL

Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {

fileOpen(env, this, path, fis_fd, O_RDONLY);

}

OK。我们从该文件上面的引用io_util_md.c找到实现:

void

fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)

{

jlong h = winFileHandleOpen(env, path, flags);

if (h >= 0) {

// 设置fd 的值

SET_FD(this, h, fid);

}

}

在上面文件里面可以看到:winFileHandleOpen,

jlong

winFileHandleOpen(JNIEnv *env, jstring path, int flags)

{

const DWORD access =

(flags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :

(flags & O_WRONLY) ? GENERIC_WRITE :

GENERIC_READ;

const DWORD sharing =

FILE_SHARE_READ | FILE_SHARE_WRITE;

const DWORD disposition =

/* Note: O_TRUNC overrides O_CREAT */

(flags & O_TRUNC) ? CREATE_ALWAYS :

(flags & O_CREAT) ? OPEN_ALWAYS :

OPEN_EXISTING;

const DWORD maybeWriteThrough =

(flags & (O_SYNC | O_DSYNC)) ?

FILE_FLAG_WRITE_THROUGH :

FILE_ATTRIBUTE_NORMAL;

const DWORD maybeDeleteOnClose =

(flags & O_TEMPORARY) ?

FILE_FLAG_DELETE_ON_CLOSE :

FILE_ATTRIBUTE_NORMAL;

const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose;

HANDLE h = NULL;

if (onNT) {

WCHAR *pathbuf = pathToNTPath(env, path, JNI_TRUE);

if (pathbuf == NULL) {

/* Exception already pending */

return -1;

}

h = CreateFileW(

pathbuf, /* Wide char path name */

access, /* Read and/or write permission */

sharing, /* File sharing flags */

NULL, /* Security attributes */

disposition, /* creation disposition */

flagsAndAttributes, /* flags and attributes */

NULL);

free(pathbuf);

} else {

WITH_PLATFORM_STRING(env, path, _ps) {

h = CreateFile(_ps, access, sharing, NULL, disposition,

flagsAndAttributes, NULL);

} END_PLATFORM_STRING(env, _ps);

}

if (h == INVALID_HANDLE_VALUE) {

int error = GetLastError();

if (error == ERROR_TOO_MANY_OPEN_FILES) {

JNU_ThrowByName(env, JNU_JAVAIOPKG "IOException",

"Too many open files");

return -1;

}

throwFileNotFoundException(env, path);

return -1;

}

return (jlong) h;

}

好吧,上面代码我也搞不明白- -,但是这几句代码:

h = CreateFileW(

pathbuf, /* Wide char path name */

access, /* Read and/or write permission */

sharing, /* File sharing flags */

NULL, /* Security attributes */

disposition, /* creation disposition */

flagsAndAttributes, /* flags and attributes */

NULL);

以及

WITH_PLATFORM_STRING(env, path, _ps) {

h = CreateFile(_ps, access, sharing, NULL, disposition,

flagsAndAttributes, NULL);

我的理解是,这里通过CreateFileW方法,创建了一个类似文件描述的结构,然后通过CreateFile调windows 下面的底层方法,填充这个结构的数据,那么这个文件对象就能被我们上层对象识别了,就能是获取里面的资源。

OK,我们现在创建了对文件之间的连接,拿到文件流对象之后,来看看我们常用的read 方法。

// 对字节的操作

public native int read() throws IOException;

private native int readBytes(byte b[], int off, int len) throws IOException;

在FileInputStream.c 里面同样可以找到

JNIEXPORT jint JNICALL

Java_java_io_FileInputStream_read(JNIEnv *env, jobject this) {

return readSingle(env, this, fis_fd);

}

JNIEXPORT jint JNICALL

Java_java_io_FileInputStream_readBytes(JNIEnv *env, jobject this,

jbyteArray bytes, jint off, jint len) {

return readBytes(env, this, bytes, off, len, fis_fd);

}

继续看io_util.c 里面:

jint

readSingle(JNIEnv *env, jobject this, jfieldID fid) {

jint nread;

char ret;

FD fd = GET_FD(this, fid);

if (fd == -1) {

JNU_ThrowIOException(env, "Stream Closed");

return -1;

}

// 看出是一个一个的读取,fd 表示刚才文件描述的一种结构

nread = IO_Read(fd, &ret, 1);

if (nread == 0) { /* EOF */

return -1;

} else if (nread == JVM_IO_ERR) { /* error */

JNU_ThrowIOExceptionWithLastError(env, "Read error");

} else if (nread == JVM_IO_INTR) {

JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);

}

return ret & 0xFF;

}

关于IO_Read 的东西,在io_util_md.h 有定义:

/*

* HPI是一个与主机通信的并行接口

* Route the routines through HPI

*/

#define IO_Write JVM_Write

#define IO_Sync JVM_Sync

#define IO_Read JVM_Read

#define IO_Lseek JVM_Lseek

#define IO_Available JVM_Available

#define IO_SetLength JVM_SetLength

关于JVM_Read 我在jvm.h 里面看到

/*

// 从文件里面读取 a char array

* Read data from a file decriptor into a char array.

* // 文件的来源

* fd the file descriptor to read from.

// 读出来的存放位置

* buf the buffer where to put the read data.

// 读的字节数

* nbytes the number of bytes to read.

*

* This function returns -1 on error, and 0 on success.

*/

JNIEXPORT jint JNICALL

JVM_Read(jint fd, char *buf, jint nbytes);

然后在jvm.cpp 里面找到

关于这段代码,大神告诉我是宏定义,关于C和C++ 的东西,我已经无力回天啦。

当然我们知道了介绍,可以理解这里会让调系统的read 方法。

这可以参考:“操作系统read 的原理实现”,google 一下很多,这里就不解释了

jvm.cpp 里面有很多关于IO这块的,可以去看看,但是都是 宏定义。。

关于linux 下的这些代码,还有涉及一下阻塞等东西,以后在去研究一下操作系统的东西吧。

JVM_LEAF(jint, JVM_Read(jint fd, char *buf, jint nbytes))

JVMWrapper2("JVM_Read (0x%x)", fd);

//%note jvm_r6

return (jint)os::restartable_read(fd, buf, nbytes);

JVM_END

小结:

1.本想了解下底层怎么操作的,但是大概了解下了,最终到read  或者write 的时候,一些基础知识不够,还是不能透彻,但是也足够我们大致了解了。

2.按上面的思路可以看出大概的思路,虽然没写write 的过程,但是最终都是通过流,或者说字符数组在内存里面的一些操作进行,包括我们用装饰器模式搞了很多其他流,基本原理一样,仅仅为了方便加了额外的功能。

3. 有不对的地方还请指出,仅仅是个人学习,分享作用

java底层 文件操作,java底层是怎样对文件操作的相关推荐

  1. java底层 文件操作,java底层是怎的对文件操作的

    一.序言 IO操作,才程序中比较普遍,JAVA 中提出了IO/NIO 的概念,也一直在说NIO 比IO快,一直不知道原因,就想memcache 和ehcache 比较优劣一样,这些东西得自己看看如何实 ...

  2. java链表集合_Java底层基于链表实现集合和映射--集合Set操作详解

    本文实例讲述了Java底层基于链表实现集合和映射--集合Set操作.分享给大家供大家参考,具体如下: 在Java底层基于二叉搜索树实现集合和映射中我们实现了底层基于二叉搜索树的集合,本节就底层如何基于 ...

  3. java nio底层实现_Java NIO 底层原理

    一.概念说明 1.内核态(内核空间)和用户态(用户空间)的区别和联系? 用户空间是用户进程所在的内存区域,系统空间是操作系统所在的内存区域.为了保证内核的安全,处于用户态的程序只能访问用户空间,而处于 ...

  4. 探索Java日志的奥秘:底层日志系统-log4j2

    前言 log4j2是apache在log4j的基础上,参考logback架构实现的一套新的日志系统(我感觉是apache害怕logback了). log4j2的官方文档上写着一些它的优点: 在拥有全部 ...

  5. Java原子类中CAS的底层实现,java高级面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  6. 【你好面试官】008 Java内存模型指volatile底层原理详解、多处理器原子操作实现原理

    微信公众号:你好面试官 这里没有碎片化的知识,只有完整的知识体系. 专注于系统全面的知识点讲解,面试题目解析; 如果你觉得文章对你有帮助,欢迎关注.分享.赞赏. ###前言 二蛋几天没有收到面试通知, ...

  7. Java锁--Lock实现原理(底层实现)

    Lock完全用Java写成,在java这个层面是无关JVM实现的. 在java.util.concurrent.locks包中有很多Lock的实现类,常用的有ReentrantLock.ReadWri ...

  8. Java的NIO之ByteBuffer底层分析

    类ByteBuffer是Java nio程序经常会用到的类,也是重要类 ,我们通过源码分析该类的实现原理. 一.ByteBuffer类的继承结构 public abstract class ByteB ...

  9. java 运算符输入_java-运算符,IO输入输出,文件操作

    Java 运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 ...

  10. java 追加写入hdfs_java操作之HDFS-创建-删除目录-读写文件-追加写文件

    Hadoop文件操作之HDFS,创建.删除目录,读写文件,追加写文件 package hadoop.hadoop_demo; import java.io.InputStream; import ja ...

最新文章

  1. 实战篇:Security+JWT组合拳 | 附源码
  2. angularJS 路由加载js controller 未定义 解决方案
  3. linux下jetty简单配置
  4. 读《大型网站技术架构:核心原理与案例分析》第一章:大型网站架构演化
  5. java中的内存泄漏
  6. C++ __gnu_pbds(hash,可并堆,平衡树)
  7. 【BZOJ】1649: [Usaco2006 Dec]Cow Roller Coaster(dp)
  8. 阿里云服务器排坑指南
  9. 【 全干货 】5 分钟带你看懂 Docker ! 1
  10. VR--VIVE-SteamVR API
  11. Spring Security Oauth2 (二) 代码 授权码模式
  12. 大企业中,Java面试官最爱问的问题集锦(2)
  13. 抖音极速版—–青龙面板
  14. c语言 从文件中读取车牌,输入一个车牌号写入文件,找出所有后四位是一个完全平方数的车牌号并输出
  15. 浅谈数据与网络安全--对网络安全的基础知识了解
  16. 消息推送之百度云推送Android集成与用法
  17. Excel工作表事件(2)- Change事件
  18. 移动端本地 H5 秒开
  19. 写给程序员看的面向对象摄影技巧
  20. scala学习复习笔记超详细(变量)

热门文章

  1. 【手写字母识别】基于matlab GUI ELMAN+BP神经网络手写大写字母(A-O)识别【含Matlab源码 785期】
  2. 【数字信号调制】基于matlab GUI PCM编码调制【含Matlab源码 453期】
  3. 【优化求解】基于matlab粒子群算法求解货物配装优化问题【含Matlab源码 414期】
  4. shell错位_shell脚本出错!来大神指出错误出处!!!!
  5. python安装及运行环境_Python 安装及环境搭建
  6. webpack 加载html模板,Webpack:从html模板加载图像
  7. karma看fits文件软件操作汇总【第三个维度的变化】【查看某个范围的RMS值】
  8. java futuretask 状态_6.3 FutureTask基本操作总结 - JAVA 并发知识点总结
  9. xml 标签带有号php,php操作xml入门之xml基本介绍及xml标签元素
  10. com app.html,downloadApp.html