Java入门:Java IO入门概括

I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道。在当今这个数据大爆炸时代,I/O 问题尤其突出,很容易成为一个性能瓶颈。

本文的目的是分析 I/O 的内在工作机制,以及java I/O类库的基本架构,以帮助初学者从总体上了解Java I/O。具体各个I/O类库的使用,请读者在遇到实际问题时,结合本文的讲解来理解掌握。

1.社么是I/O

描述Java的I/O机制,我们用从河中抽水的例子来解释读文件的过程。

要将河水抽出来,首先我们需要一个抽水机,然后把抽水机丢到河流里。这里,河水相当于文件,我们需要建立一个抽水机,并将抽水机与河水关联起来:

FileInputStream fis = new FileInputStream("E:/rivier.txt");

fis就是抽水机,E:/rivier.txt就是河水。

设备准备好了,就可以打开水龙头获得水啦,但获得的水需要存放,所以第二步,我们还需要先有一个盛水的容器:

byte[] bottle = new byte[10];

容器bottle是一个byte类型的数组,大小为10.之所以将容器定义为byte数组而不是其它数组类型,是因为我们使用的这个抽水机比较特殊,抽出来的水最小单位就是1个byte(你就当1滴水来理解吧)。

接下来,将容器放到水龙头下面,打开水龙头,就开始将水抽进容器里了。

fis.read(bottle);

这样抽水机fis就抽出了10滴水(10个byte)放到bottle这个容器里面了。然后bottle里的数据就可以任意有我们处置了。

Java为我们提供了两种类型的抽水机,第一种抽水机的名字叫做XXXInputStream,它抽水的单位是字节,当然盛水的容器自然就是字节数组byte[]。

第二种抽水机的名字叫做XXXReader,它抽水的单位是字符,盛水容器就是字符数组char[]。

也就是说,我们如果我们用第一种抽水机XXXInputStream,抽出来的是byte;如果用第二种抽水机XXXReader,抽出来的是char。(有关字节byte和字符char的区别,自己脑补...)

这里的XXX表示抽的水是河水,还是湖水、海水、污水......,即XXX表示数据的来源。如FileInputStream,表示这个抽水机是专门从文件中读取数据的;ByteArrayInputStream,就是专门从字符数组也就是内存中读数据的。

小结一下,要读一个文件,步骤如下:

1. 实例化一个XXXInputStream对象(选择一种抽水机,指定水源)

2. 确定接收数据的对象(准备容器)

3. read()(打开水龙头)

现在,通过上面的抽水机,用户可以从各种地方,按各种大小的被子来得到水。但用户觉得抽水机功能还是弱了点, 如果打开水龙头,就是热水,就是热咖啡就好啦!

显然抽水机已经力不从心了,如果把加热,煮咖啡的功能设计到抽水机里面,那么抽水机会显得太庞杂,也增加了出故障时维修的难度。

所以,我们换一种思路,在抽水机的水龙头下,接一根加热管:

FileInputStream fis = new FileInputStream("e:/yellow_river.txt");//准备好抽水机
ObjectInputStream ois= new ObjectInputStream(fis);//增加一个加热器

这样,只需要调用加热管的水龙头,就可以获得热水啦:

ois.readDouble();//读出来的就是一个double型的数据,不再是byte数据(即抽出的就是热水)

所以,总的来说,在Java中读文件,就像抽水,首先,需要根据读取单位,根据读取源,选择合适的抽水机。如果需要,还可以在抽水机后添加管子,增强功能。

请试着按照排水的例子,描述文件的机制。

2. 实例理解

现在我们结合上面的例子,来理解几个实例。

1)按字节读文件FileInputStream

FileInputStream fis = new FileInputStream("e:/in.txt");   //创建输入流对象(抽水机)
while (fis.available() > 0) {
    byte[] b = new byte[10];   //创建数组(盛水容器)
    int nResult = fis.read(b);   //读数据到数组,并且读到数据时,nResult被赋值为>-1的整数,表示实际读了多少个byte
    if (nResult == -1) //文件中的数据读完了,没数据可读了
        break;
    System.out.println(new String(b));
}
fis.close();      //数据读完了,抽水机需要关掉

2)按字符读文件FileReader:

FileReader rdFile = new FileReader("e:/in.txt");   //实例化文件输入流对象(抽水机)
while (rdFile.ready()) {   //输入流是否准备好读(抽水机是否准备好抽水)
    char[] chIn = new char[10];   //准备容器
    int nResult = rdFile.read(chIn);   //读数据
    if (nResult == -1) //如果没有读到数据
、     break;
    System.out.println(chIn);
}
rdFile.close();  //不抽水了,关掉抽水机

FileReader满足XXXReader命名规则,从名字可以判断是按字符来读数据,并且数据来源是文件。

3.带缓冲区的读

还是用抽水的例子来讲解什么是缓冲区。我们在使用水的时候,可以有两种方法,一种是每次要用水,就去打开水龙头,等着它将容器装满。第二种方法是,家里有一个大水缸,先将大水缸装满,每次用水的时候,直接去水缸里取。当水缸里的谁不够用时,再打开水龙头将大水缸放满。

不考虑水存放时间长了会变质的影响,显然第二种方法效率高。

文件通常放在磁盘等设备中,读写速度远没有内存的速度快。上面FileInputStream或FileReader每次执行read()方法,都会去硬盘读取一次。如果事先将文件中的数据读取一定大小到内存中,以后每次read(),从这块内存中读,就会减少硬盘的读写次数,效率高得多。如果这块内存中的数据不够用了,再去硬盘继续读数据把这块内存填满,后面继续使用这块内存。这块内存就是缓冲区。

用法示例:

FileReader rdFile = new FileReader("e:/in.txt"); //创建字符文件输入流对象
BufferedReader brdFile = new BufferedReader(rdFile);  //创建一个BufferedReader对象
String strLine;
while ((strLine = brdFile.readLine()) != null) {
    System.out.println(strLine);
}
brdFile.close();   

例子中,将rdFile这个FileReader对象包装在BufferedReader对象brdFile里,直接操作brdFile对象,就可以实现带缓冲功能的读操作了。

同样,按字节读可以使用BufferedInputStream类来对InputSteam进行包装。

4. I/O体系结构

我们已经了解了Java I/O 系统,并学会了一些简单的I/O操作,接下来请打开Java Doc,让我们看看Sun公司是怎样通过面向对象的思想,设计I/O系统的。

总结一下:

1.InputStream和OutputStream是按字节读写数据的抽象类,是所有字节输入输出流的基类。

2. Reader和Writer是按字符读写数据的抽象类,是所有字符输入输出流的基类。

3. 继承它们的都是针对特定数据源的“抽水机”或“排水机”,提供了read和write的基本实现。

4. 构造方法一般都需要提供数据源。

时间: 2024-10-07 10:48:17

Java入门:Java IO入门概括的相关文章

Java使用Protocol Buffers入门四步骤

Protocol Buffers(简称protobuf)是谷歌的一项技术,用于将结构化的数据序列化.反序列化,经常用于网络传输. 这货实际上类似于XML生成和解析,但protobuf的效率高于XML,不过protobuf生成的是字节码,可读性比XML差.类似的还有json.Java的Serializable等. protobuf支持各种语言.本文以Java为例,简单介绍protobuf如何使用.其他语言使用方法类似. 首先需要下载: http://download.csdn.net/downlo

Java的多线程 简单入门

Java的多线程 简单入门 首先可以先搞清楚什么是程序.进程.线程,以及它们之间的关系: 定义: 一 程序只是一组指令的有序集合,它是静态的 二 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位: 三 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程: 进程与线程区别与联系 (

【Java】Java网络编程菜鸟进阶:TCP和套接字入门

Java网络编程菜鸟进阶:TCP和套接字入门 JDK 提供了对 TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)这两个数据传输协议的支持.本文开始探讨 TCP. TCP 基础知识 在“服务器-客户端”这种架构中,服务器和客户端各自维护一个端点,两个端点需要通过网络进行数据交换.TCP 为这种需求提供了一种可靠的流式连接,流式的意思是传出和收到的数据都是连续的字节,没有对数据量进行大小限制.

java htmlparser 简单使用入门

请尊重本人的工作成果,转载请留言,并说明转载地址,谢谢.地址如下: http://blog.csdn.net/fukainankai/article/details/27710883 前几节中,我们利用GDI+在窗口中绘制了各种各样的图形.图像,这一节,我们将会将这些图像保存成简单图像.所谓简单图像,指的是bmp/jpg/png等图像或者单帧的gif图像.保存成多帧的gif图像稍微复杂一点,本节中暂时不做说明.保存成动态的tiff文件也比较简单,但这里也不做说明,下次有机会和gif一起介绍. 另

Java网络编程从入门到精通(4):DNS缓存

在通过DNS查找域名的过程中,可能会经过多台中间DNS服务器才能找到指定的域名,因此,在DNS服务器上查找域名是非常昂贵的操作.在Java中为了缓解这个问题,提供了DNS缓存.当InetAddress类第一次使用某个域名(如www.csdn.net)创建InetAddress对象后,JVM就会将这个域名和它从DNS上获得的信息(如IP地址)都保存在DNS缓存中.当下一次InetAddress类再使用这个域名时,就直接从DNS缓存里获得所需的信息,而无需再访问DNS服务器. DNS缓存在默认时将永

Redis入门 – Jedis存储Java对象 - (Java序列化为byte数组方式)

Redis入门 – Jedis存储Java对象 - (Java序列化为byte数组方式) 原文地址:http://alanland.iteye.com/admin/blogs/1600685(欢迎转载 - 转载请保留该原文链接) 07/19/12 03:08:05 PM 在Jedis开发中,我们很多时候希望直接把一个对象放到Redis中,然后在需要的时候取出来.Redis的key和value都支持二进制安全的字符串,存储Java对象不是问题,下面我们看一下如何来实现. 1要存储的对象 现在写一个

怎样学习JAVA,JAVA入门方法

Java如今已经是全球编程语言排民第一的语言,运用广泛,前景广阔,现在学习java,将来就业,升职加薪都会有保障.那么如何学习java,想要学习java,java的入门方法是什么? 入门要一步一步完成,需要在途中为自己确立一个一个的目标来完成.下面为大家介绍一下,依照这样的目标完成,相信你一定会成为高手! 学习java如何入门?做好以下这些点,入门更快,学习java更轻松. 1.你需要精通面向对象分析与设计(OOA/OOD).涉及模式(GOF,J2EEDP)以及综合模式.你应该十分了解UML,尤

kafka入门java例子

1,生产者 import java.util.Properties; import kafka.javaapi.producer.Producer; import kafka.producer.KeyedMessage; import kafka.producer.ProducerConfig; public class TestProducer { public static void main(String[] args) { Properties props = new Propertie

零基础小白入门Java免费视频教程推荐—小猿圈

Java语言作为世界上使用最多的开发语言,企业庞大的需求量让每年进入Java开发领域的人不减反增.对于零基础小白来讲如何学习Java开发语言是入门的第一个难题.本文小猿圈主要给零基础小白入门Java开发技术推荐一个靠谱的Java免费视频教程. 零基础小白入门Java免费视频教程推荐-小猿圈 关于Java基础入门视频教程的选择,网上有各种各样的解说,也有各式各样的视频教程,那么我们究竟应该如何选择Java免费视频教程呢?如何才能挑选到合适自己的Java基础入门视频教程呢? 许多想通过观看Java视

java的String类入门

java的String类入门 1. 概述 只要是用双引号括起来的都叫字符串 String类在包java.lang.String中,只要是java.lang中的包,在写程序时都不需要import进来 字符串的内容一旦创建,将不可再改变,是一个常量 正是因为字符串不可改变,所以字符串是可以共享使用的.想想如果共享的东西大家可以随便修改,用一次残一次,谁还想去共享呀,想想都恶心,共享单车大家都可以用,就代表用的时候可以随便糟蹋它,拆它??? 字符串效果上相当于是char[]字符数组,但是底层原理是by