【问题标题】:How does java source code ultimately interact with files?java源代码最终如何与文件交互?
【发布时间】:2015-02-27 02:06:18
【问题描述】:

我一直想知道 java 编译器/解释器如何设法提供字节码/源代码与文件输入和输出之间的交互。

我知道 InputStream 和 OutputStream 是所有文件 i/o 类的超类,但是在阅读它们之后,它们没有提供基本文件交互方法(read() 和 write(byte b))的实现。我最初的想法是,也许编译器会将这些方法转换为仅在这种情况下发生的某些字节码操作(从文件返回一个字节或将一个字节写入文件),但这可能不正确。

如果 Java 被编译成汇编,那么我理解某个指令将被翻译成特定于平台的文件 i/o 代码(例如 cout

谁能赐教?

【问题讨论】:

  • 对于内存(字节数组)流、文件输出流或网络流,write(int) 的常见实现是什么?某些操作有native 代码,因此并非所有内容都由JVM处理。
  • 最终 I/O 确实涉及与运行 JVM 的操作系统交互的特定于平台的本机代码。
  • 顺便说一句:对于 NIO(.2) (docs.oracle.com/javase/8/docs/api/java/nio/package-summary.html) 类,InputStreamOutputStream 类不是所有文件 I/O 的超类(但这些实现可能还包含特定于平台的native 实现。)

标签: java file-io bytecode


【解决方案1】:

InputStreamOutputStream 类本身不提供任何实现。它们都是抽象类,需要派生类来提供实现。比如InputStreamis an abstract methodread()方法:

public abstract int read() throws IOException

现在,派生类可以以它认为合适的任何方式提供实现,但是您是正确的,低级操作(例如需要访问系统调用的操作)最终需要一些引导代码,而这些代码不能仅在纯 Java 中实现.

例如,如果您查看source code for FileInputStream,您会看到它的read() 方法被声明为原生:

public
class  FileInputStream extends InputStream
{
    /* (...) */

    public native int read() throws IOException;

    /* (...) */
}

由于FileInputStream 是一个核心Java 类,JVM 可能会采取一些捷径,但实现本机方法的典型方式是通过Java Native Interface (JNI)。 JNI 使得提供用不同语言(例如 C)编写的 Java 方法的实现成为可能。

这一切如何结合在一起?当您编译一个使用FileInputStreamread() 方法的类时,就编译器而言,您只是使用某个类的某些方法,字节码将与任何其他方法和类相同.在运行时,当你的调用被执行时,之前加载了 FileInputStream 类的 JVM 知道你正在调用的方法是一个本地方法,并调用它的本地实现。

【讨论】:

    【解决方案2】:

    和所有的类一样,因为它们不是接口,所以会发生在方法上会有一个invokevirtual,没有别的(JVM中有5个调用操作码:invokevirtualinvokeinterfaceinvokespecialinvokestaticinvokedynamic)。

    现在,当然,JRE 肯定会有一些native 方法来处理操作系统级别的东西(例如在处理File*Streams 时);重要的是,实际的*Stream 实现可能因操作系统而异,也可能因 JRE 和 JRE 而异。重要的是该方法按照合同规定的方式执行。

    之后,在运行时,JIT 可能会用更高效的代码(甚至本机代码)替换它。但是InputStreamOutputStream 和其他类一样;这些细节与 Java 开发人员无关,但对 JDK 开发人员当然至关重要;)

    【讨论】:

      【解决方案3】:

      文件 I/O 由操作系统提供。在 Linux 上编写文件与在 Windows 上编写文件的工作方式不同。即使是像 C 这样的低级语言通常也会在标准库中提供一个抽象层以使其看起来相同,但是为任一平台生成的二进制代码调用完全不同的操作系统函数。这意味着任何文件 I/O 最终都是操作系统特定的任务。 Java 中的操作系统抽象由 Java 虚拟机提供。

      所有 Java 标准类(如 java.io.FileOutputStream)的实现都随您的操作系统特定的 Java 虚拟机(当您在 java.com 上单击“免费 Java 下载”时获得的软件)一起提供。 JVM可以在Java中实现这些类的方法,也可以选择实现一个方法native其中looks like this

      这意味着该方法是用编写 JVM 的编程语言实现的。当类执行必须通过调用操作系统(如文件 IO)提供的操作时,它只能在本地实现。

      【讨论】:

        猜你喜欢
        • 2018-07-16
        • 2011-01-28
        • 2016-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多