`
Vitas_Wang
  • 浏览: 9721 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

大话 Java IO(一)

    博客分类:
  • java
阅读更多
相信好多人都对java的io类感到抓狂,一个简单的输入输出都要创建n多个对象,完全搞不懂为什么要一层套一层。
如果你也有上面的困惑,那么不妨和我一起究一究为什么Java IO长这样。

我猜Java IO的创建过程是这样的:
先参考一下其它已有编程语言都是怎么创建IO类的。IO输入/输出源各种各样,有键盘输入,有文件输入,有网络输入,有内存输入等等。为了屏蔽这些不同,编程语言都引入了“流"的概念,说白了所有这些IO操作就是字节流流来流去。
这些流又可以分为两大类,输入流和输出流。

于是乎Java 1.0 便也照猫画虎提供了两大类IO类库, InputStream, OutputStream.
有了这两个基类以后,创建者认为基本IO问题就搞定了,如果你需要输入那你就继承InputStream, 如果你需要输出那么你就继承OutputStream.
Java 提供了几种常用输入输出的实现。我们可以直接使用
ByteArrayInputStream 用于从内存的缓冲区读取数据, 如一个线程将数据写入某个缓冲区,另一个线程可以用ByteArrayInputStream读取该缓冲区的数据;
ByteArrayOutputStream, 将内容写入内存的某缓冲区;
public static void main(String[] args) throws IOException{
		ByteArrayInputStream input = new ByteArrayInputStream("memory input test".getBytes());
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		int data = 0;
		while((data = input.read()) != -1){
			output.write(data);
		}
		
		System.out.print(output.toString());
		input.close();
		output.close();
	}

FileInputStream, 用于从文件中读取数据;
FileOutputStream, 用于将内容写入文件。
public static void readFile(String inFile, String outFile) throws IOException{
		try {
			byte[] data = new byte[1];
			FileOutputStream output = new FileOutputStream(outFile);
			FileInputStream input = new FileInputStream(new File(inFile));
			try {
				while(input.available() > 0){
					input.read(data);
					output.write(data);
				}
			}  finally{
				input.close();
				output.close();
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

这些实现都是基于InputStream/OutputStream 的,都是以字节为单位读取/写入数据。
读起来确实难用,byte[]设大了吧,如果数据没呢么多久会写好多null,设小了吧效率不高。
在使用过程中人们就发现很多问题,如文件读取很慢,因为磁盘读取本来就很耗时,以字节为单位和磁盘交互,每次只读取一个字节效率自然太慢了;
如果只是单纯的都一个文件然后写到另一个文件,这个方法还算能用。
但是当要解析里面的数据时就有问题了,不同的数据类型所占用的存储空间也不同,如在某些机子上int占4个byte, double占8个byte, 而在另一些机器上可能所占空间又不同,当我需要读取一个int时我是读取4个byte呢,还是5个byte呢?

此时想解决这个问题有两种方法,一种是将前面的推倒重来,放弃之前的类再写两个新的替代它们;另一个方法就是使用装饰折模式在前面基础上进行修补。
Java选择了后者,它可以简单的装饰一下原有的类,然后和原有类提供完全一样的接口,只是对它的功能稍加装饰,满足现在的需求。
于是针对上面两个问题就有了BufferedInputStream, DataInputStream, BufferedOutputStream, DataOutputStream 来对FileInputStream/FileOutputStream进行装饰。
BufferedInputStream/BufferedOutputStream 就可以使你在读写文件的时候一次读写一批数据,而不是一个byte一个byte读取,大大加强磁盘读写效率;
public static void BufferTest(String inputName, String outputName) throws IOException{
		try {
			byte[] data = new byte[1];
			BufferedInputStream input = new BufferedInputStream(new FileInputStream(new File(inputName)));
			BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(outputName));
			try {
				while(input.available() > 0){
					input.read(data);
					output.write(data);
				}
			}  finally{
				input.close();
				output.close();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

虽然看上去操作和FileInputStream/FileOutputStream没差,但BufferedInputStream/BufferedOutputStream内部其实并不是一次读一个byte,而是每次读得时候预取好多,下次再读可直接从内存得到,大大提升效率。

DataInputStream/DataOutputStream 则可以让你直接按照字符来读写,而不是基于字节,这样我们就不用关心这个整数在这台机子上到底占用几个字节了,InputStream.readInt()直接读取到一个int.
public static void dataInputOutputTest(String fileName) throws FileNotFoundException{
		DataInputStream input = null;
		DataOutputStream output = new DataOutputStream(new FileOutputStream(fileName));
		int a = 10;
		float b = 12;
		String c = "test";
		
		try {
			output.writeInt(a);
			output.writeFloat(b);
			output.writeUTF(c);
			output.flush();
			output.close();
			
			input = new DataInputStream(new FileInputStream(fileName));
			System.out.println(input.readInt());
			System.out.println(input.readFloat());
			System.out.println(input.readUTF());
			input.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


貌似所有问题都解决了,文件copy用字节流,读取字符用DataInputStream, DataOutputStream。
但是DataOutputStream的问题是它写的文件不可读;而且读得顺序必须和写的顺序一模一样,比较适合于固定格式的输入,输出。而我们90%的情况下其实都是在读取String。
Java1.1 发现了这些问题,于是乎对IO又有了一个革命性的改写,我们下回分析
分享到:
评论

相关推荐

    大话JAVA性能优化.pdf

    作者力求做到知识的综合传播,而不是仅仅只针对Java虚拟机调优进行讲解,另外力求每一章节都有实际的案例支撑。具体包括:性能优化策略、程序编写及硬件服务器的基础知识、Java API优化建议、算法类程序的优化建议、...

    大话JAVA:从零基础到数据库、WEB开发.

    大话Java:从零基础到数据库、Web开发以漫画的形式,由浅入深、循序渐进地介绍Java编程的常用技术和方法,内容涵盖了Java基本语法结构、面向对象特征、集合框架体系、异常处理、GUI编程、MySQL数据库、JDBC数据库...

    大话java性能优化 周明耀 完整版

    《大话java性能优化》是周明耀先生的一本深入探讨Java性能调优的专业书籍,其主要内容涵盖了Java程序设计中的各种性能优化策略和技术。这本书旨在帮助开发者理解和掌握如何提升Java应用的运行效率,减少资源消耗,...

    大话java性能优化

    大话java性能优化,大家可以搜一下这本书。这个是完美中文版,建议下载

    大话JAVA性能优化

    但根据标题《大话JAVA性能优化》和描述“虽然有些地方可能过时,但是还是可以一读”以及标签“java 优化”,可以推断出书籍内容可能围绕Java编程语言的性能优化相关知识。基于这些信息,我们可以构建关于Java性能...

    大话Java性能优化.epub

    大话java性能优化,pdf版!

    java版大话西游源码

    《Java版大话西游源码》是一款基于Java编程语言开发的角色扮演游戏(RPG)教程,对于初学者和想要深入理解游戏开发的程序员来说,它提供了丰富的学习资源。这款教程涵盖了多线程技术和自动寻路算法等核心概念,是...

    大话Java性能优化

    作者 力求 做到 知识 的 综合 传播, 而 不是 仅仅 只 针对 Java 虚拟 机 调 优 进行 讲解, 另外 力求 每一 章节 都有 实际 的 案例 支撑。 具体 包括: 性能 优化 策略、 程序 编写 及 硬件 服务器 的 基础 知识...

    大话JAVA性能优化-高清-2016年4月

    大话JAVA性能优化-高清-2016年4月,分享给所有需要的人!

    大话JAVA性能优化 周明耀 PDF

    作者力求做到知识的综合传播,而不是仅仅只针对Java虚拟机调优进行讲解,另外力求每一章节都有实际的案例支撑。具体包括:性能优化策略、程序编写及硬件服务器的基础知识、Java API优化建议、算法类程序的优化建议、...

    大话JAVA:从零基础到数据库、WEB开发

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向...

    【资源免费下载】Java代码积累丨大话设计模式(Java实现版本)、线程协作

    设计模式参考《大话设计模式》 工厂简单模式 创造型模式 工厂方法模式 抽象工厂模式 原型模式 建造者模式 单例模式 结构型模式 队列模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 行为模式(类行为...

    (JAVA)大话类、方法、参数、对象、属性以及面向对象的开发模式.pdf

    (JAVA)大话类、方法、参数、对象、属性以及面向对象的开发模式.pdf

    《JAVA课程设计》--软件系统设计与体系结构讲课代码,讲课PPT,重写的大话设计模式(程杰)分章节对应代码Java代码.zip

    本人十余年JAVA从业经验,精通JAVA高可用、分布式、高并发系统架构设计。有志于做JAVA职业规划、技术提升的可与我联系,交个朋友~ 本人十余年JAVA从业经验,精通JAVA高可用、分布式、高并发系统架构设计。有志于做...

    Java从入门到精通.pdf

    十四万字总结,PDF包含了十四个大模块:Java基础知识,数据结构,算法,Java集合框架,Java8新特性,操作系统,网络原理,Java多线程及并发编程,Java的IO模型及网络编程,JVM,Mysql,JavaWeb和一个仿Tomcat实现的...

    大话JAVA性能优化试读样章高清PDF

    8. 包名命名:包名应该全部使用小写,并且用点分隔符来分隔,每个部分仅包含一个自然语义的英语单词。包名的命名也应使用单数形式,除非类名具有复数含义。 9. 缩写命名:避免使用不规范的缩写,因为这会降低代码的...

    大话西游java游戏后端

    大话西游模拟仿制后端

Global site tag (gtag.js) - Google Analytics