`

FileInputStream 源码分析

阅读更多
java.io.FileInputStream是从文件系统中获取一个文件的原始字节。如果要读取字符流,可以用java.io.FileReader。

public class FileInputStream extends InputStream {

	private FileDescriptor fd;

	private FileChannel channel = null;

	// 调用参数为File的构造函数
	public FileInputStream(String name) throws FileNotFoundException {
		this(name != null ? new File(name) : null);
	}

	// 获取文件的路径并检查权限
	// 实例化FileDescriptor并赋给fd
	// 打开文件(native方法)
	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();
		}
		fd = new FileDescriptor();
		open(name);
	}

	// 检查权限和输入是否为空
	// 把参数对象赋给fd
	public FileInputStream(FileDescriptor fdObj) {
		SecurityManager security = System.getSecurityManager();
		if (fdObj == null) {
			throw new NullPointerException();
		}
		if (security != null) {
			security.checkRead(fdObj);
		}
		fd = fdObj;
	}

	// 根据文件名打开指定的文件
	private native void open(String name) throws FileNotFoundException;

	// 读取1个字节的数据,如果没有输入,则该方法阻断
	public native int read() throws IOException;

	// 从off位置开始,读取len长度字节的数据到字节数组b中
	private native int readBytes(byte b[], int off, int len) throws IOException;

	// 读取所有的字节到字节数组b中,如果输入不可用,则该方法阻断
	public int read(byte b[]) throws IOException {
		return readBytes(b, 0, b.length);
	}

	// 读取len长度的字节到字节数组b中,如果len不为0并且输入不可用,则该方法阻断,如果为0则返回0
	public int read(byte b[], int off, int len) throws IOException {
		return readBytes(b, off, len);
	}

	// 从输入流中跳过并丢弃 n 个字节的数据。
	//出于各种原因,skip 方法最终跳过的字节数可能更少一些,甚至可能为 0。如果 n 为负,则抛出 IOException,即使 InputStream 超类的 skip 方法在这种情况下没有执行任何操作。返回实际跳过的字节数。 
	//此方法跳过的字节可能多于底层文件中剩余的字节。这不会产生异常,并且跳过的字节数可能包括底层文件的 EOF(文件结束符)之后的一些字节数。如果试图在跳过末尾之后读取流,那么会返回指示文件末尾的 -1。 
	public native long skip(long n) throws IOException;

	// 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
	// 在某些情况下,非阻塞的读取(或跳过)操作在执行很慢时看起来受阻塞,例如,在网速缓慢的网络上读取大文件时
	public native int available() throws IOException;

	// 关闭流并且释放所有和这个流关联的系统资源
	public void close() throws IOException {
		if (channel != null)
			channel.close();
		close0();
	}

	// 返回表示到文件系统中实际文件的连接的FileDescriptor对象,该文件正被当前的FileInputStream实例所使用
	public final FileDescriptor getFD() throws IOException {
		if (fd != null) return fd;
		throw new IOException();
	}

	// 返回和这个流关联的唯一FileChannel对象
	// 返回的文件通道的初始位置和从文件中当前读取的字节数相等。从这个流中读取字节会让通道的位置增加。改变通道的位置,通过显式的的或者读取,会改变流的文件位置。
	public FileChannel getChannel() {
		synchronized (this) {
			if (channel == null)
			channel = FileChannelImpl.open(fd, true, false, this);
			return channel;
		}
	}

	private static native void initIDs();

	private native void close0() throws IOException;

	static {
		initIDs();
	}

	// 确保没有对象和当前流关联时,调用close()方法来释放资源
	protected void finalize() throws IOException {
		if (fd != null) {
			if (fd != fd.in) {
				close();
			}
		}
	}
}
分享到:
评论

相关推荐

    android联系人APP源码剖析

    首先,Android联系人APP源码剖析这一标题表明本文将重点讲解Android平台上联系人管理应用的源码,尤其是基于Android 2.3版本进行的分析。通过这种剖析,开发者可以更好地理解如何定制及使用源码,以构建或优化联系人...

    java常用类库源码

    源码分析可以揭示它们如何存储和操作元素,以及在不同场景下哪种数据结构更优。例如,ArrayList基于数组实现,适合随机访问;而LinkedList基于链表,适合频繁插入和删除。 2. **IO流**:Java.IO包提供了对输入/输出...

    corejava 源码

    源码分析可以帮助我们理解如何有效地使用异常处理来增加程序的健壮性。 4. **集合框架**:Java集合框架是处理对象集合的重要工具,包括List、Set、Queue等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现...

    Java1.6源码

    源码分析可以揭示它们的内部数据结构和操作算法,比如`ArrayList`的动态数组扩容策略,`HashMap`的哈希表实现。 3. **多线程**:`java.lang.Thread`类和`java.util.concurrent`包提供了多线程编程的支持。通过源码...

    Java核心技术第8版源码

    通过源码分析,可以深入理解类的设计原则和面向对象编程的核心概念。 2. **类和对象**:Java是面向对象的语言,学习如何定义和使用类,以及类之间的继承、封装和多态性至关重要。源码中会包含许多示例,展示如何...

    JDK_AIP1.7源码.rar

    源码分析能帮助我们理解这些数据结构的底层实现,如扩容策略、查找效率等。 5. **IO与NIO** - JDK 1.7包含传统的IO流和非阻塞I/O(NIO)系统,如`BufferedReader`、`FileInputStream`以及`Channels`和`Selectors`...

    Java记事本程序Notebook源码

    源码分析可以帮助我们深入理解Java GUI(图形用户界面)编程以及事件处理机制。 1. **Java基础** - Java是一种跨平台的面向对象的编程语言,它的“一次编写,到处运行”特性使得代码可以在不同操作系统上运行。 -...

    poi3.17 源码 亲测可用

    Apache POI 3.17的源码分析可以帮助开发者深入理解内部实现,例如: - 如何高效地解析二进制或XML结构。 - 内存管理和流处理策略,以处理大型文件。 - 公式计算的实现,包括如何解析和执行Excel公式。 - 表样式和...

    Android SqliteManager 源码.rar

    《深入解析Android SqliteManager源码》 在Android开发中,SQLite数据库是广泛使用的轻量级数据库,它为应用程序...同时,源码分析还能帮助开发者理解Android系统框架和SQLite数据库的底层原理,提升整体的编程技能。

    Java zip压缩包查看程序源码

    Java是一种广泛使用的...通过分析和学习这个Java zip压缩包查看程序的源码,你可以深入了解Java对zip文件的操作,这对进行文件处理或打包应用的开发非常有价值。同时,这也是提升你的Java I/O和文件处理技能的好机会。

    上传下载所需要的包及源码

    10. **源码分析**:压缩包中的源码示例可能涵盖了上述所有或部分知识点,通过阅读和理解这些代码,开发者可以学习如何在实际项目中实现文件的上传和下载功能。 总的来说,这个压缩包提供了一个学习和实践Java文件...

    饮食分析毕设源码.zip

    这篇文档将深入解析“饮食分析毕设源码.zip”这个计算机毕业设计项目,主要基于Java编程语言。这个项目的核心目标是开发一个系统,能够对个人的饮食习惯进行分析,为用户提供健康饮食建议。我们将探讨该项目可能包含...

    Android代码-乐看播放器源码.zip

    通过对乐看播放器的源码分析,开发者不仅可以学习到Android多媒体播放的实现细节,还能掌握到如何构建高性能、高可用性的播放应用,这对于提升个人技能和解决实际问题具有极大的帮助。在实践中不断探索,才能更好地...

    android FileTest源码.rar

    【标题】"Android FileTest源码分析" 在Android开发中,理解文件操作是至关重要的,因为这涉及到数据存储、资源管理以及用户交互等核心功能。FileTest是一个用于演示和测试Android系统中文件I/O操作的示例项目。...

    jdk src 源码 压缩包提取

    源码分析是提升编程技能的关键步骤,它能帮助我们更好地理解Java语言的工作机制,比如类加载、垃圾回收、并发控制等核心概念。在源码中,你可以看到`java.lang`、`java.util`、`java.io`等包中的各种基础类是如何...

    Java 中的FileReader和FileWriter源码分析_动力节点Java学院整理

    `FileReader`进一步将`FileInputStream`转换为`InputStreamReader`,`InputStreamReader`是字符流的基类,它负责将字节流解码为字符流,这个过程通常涉及字符编码的转换。默认情况下,`InputStreamReader`使用平台的...

    java入门学习源码

    源码可能涉及FileInputStream、FileOutputStream、BufferedReader、BufferedWriter等的使用,以及Channel、Selector和Buffer的NIO操作。 通过分析"Java入门学习源码"中的JavaProject,初学者可以逐步掌握上述知识点...

    Java传输文件(附有源码)

    总结来说,"Java传输文件"是一个综合性的主题,它结合了文件I/O、网络编程、多线程、源码分析和安全性等多个方面。通过学习这些知识点,开发者能够构建出高效且安全的文件传输解决方案。提供的源码和jar文件为实践和...

    数据存储源码

    在Android开发中,数据存储是不可或缺的一部分,它用于持久化应用程序的数据,以便在应用程序关闭后仍然可以访问。这个“数据存储源码”提供了...通过分析这个源码,初学者可以更好地理解和实践Android的数据存储功能。

    幻灯片的实现 JAVA 有界面 附源码

    11. **源码分析**:MyImage.java文件很可能是项目的主类,包含JFrame的定义、组件的创建、事件监听器的注册以及程序逻辑。源码分析可以帮助理解如何将上述概念整合到实际代码中。 在这个项目中,开发人员需要编写...

Global site tag (gtag.js) - Google Analytics