`
SunnyYoona
  • 浏览: 367299 次
社区版块
存档分类
最新评论

[Java开发之路](8)输入流和输出流

阅读更多


1.Java流的分类

按流向分:
输入流:可以从其中读入一个字节序列的对象称作输入流
输出流:可以向其中写入一个字节序列的对象称作输出流

这些字节序列的来源地和目的地可以是文件,而且通常都是文件,但是也可以是网络连接,甚至是内存块。抽象类InputStream和OutputStream构成了输入和输出类层结构的基础。

按数据传输单位分:
字节流: 以字节为单位传输数据的流
字符流: 以字符为单位传输数据的流

按功能分:
节点流: 用于直接操作目标设备的流
过滤流: 是对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。

2. 读写字节(InputStream和OutputStream)

(1)InputStream类有一个抽象方法:
abstract int read()
这个方法将读入一个字节,并返回读入的字节,或者在遇到输入源结尾时返回-1。在设计具体的输入流时,必须覆盖这个方法以提供适用的功能,例如,在FileInputStream类中,这个方法将从某个文件中读入一个字节。

InputStream类还有若干个非抽象的方法,它们可以读入一个字节数组,或者跳过大量的字节。这些方法都要调用抽象的read方法,因此各个子类都只需覆盖一个方法。

(2)OutputStream类定义了下面的抽象方法:
abstract void write(int b)
它可以向某个输出位置写出一个字节。

(3)read和write方法在执行时都将阻塞直至字节确实被读入或写出。这就意味着如果流不能被立即访问(通常因为网络连接忙),那么当前的线程将被阻塞。这使得在这两个方法等待指定流变为可用的这段时间内,其他的线程就有机会去执行有用的工作。

当你完成对流的读写时,应该通过调用close方法来关闭它,这个调用会释放掉十分有限的操作系统资源。如果一个应用程序打开了过多的流而没有关闭,那么系统资源将被耗尽。关闭一个输出流的同时还会冲刷用于该输出流的缓冲区所有被临时置于缓冲区中,以便用更大的包的形式传递的字符在关闭输出流时都将被送出。如果不关闭文件,那么写出的字节的最后一个包可能将永远也得不到传递。我们可以使用flush方法认为的冲刷这些输出。

即使某个流类提供了使用原生的read和write功能的某些具体方法,应用系统的程序员还是很少使用它们,因为大家感兴趣的数据可能包含数字,字符串和对象,而不是原生字节。

Java提供了众多从基本InputStream和OutputStream类导出的类,这些类使我们可以处理那些以常用格式表示的数据,而不只是字节。

3.流家族

流家族中的成员按照它们的使用方法进行划分,形成了处理字节和字符的两个单独的层次结构。Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。因此JAVA才引入字符流。

java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流。

输入/输出 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

字节方面:InputStream和OutputStream类读写单子个字节或字节数组。要想读写字符串和数字,就需要功能更强大的子类,例如,DataInputStream和DataOutputStream可以以二进制格式读写所有的基本Java类型。

字符方面:对于Unicode文本,可以使用抽象类Reader和Writer的子类。Reader和Writer类的基本方法与InputStream和OutputStream中的方法类似。


4 字节流InputStream和OutputStream



4.1 InputStream抽象类

InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是向程序中输入数据的,且数据单位为字节(8bit);

InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法。Inputstream类中的常用方法:

常用方法 描述
public abstract int read( ) 从输入流中读取下一个字节数据。返回字节使用高位补0的int类型值表示(0-255),若返回值为-1说明没有读取到任何字节,输入流达到尽头。
public int read(byte b[ ]) 从输入流中读取b.length个字节的数据放到字节数组b中。返回值是读取的字节数。如果字节数组的长度为0,不会读取任何字节数据,返回0,否则至少尝试去读取一个字节的数据。如果没有获取到字节数据,表示流到达文件末尾,返回-1。第一个读取的字节存储在b[0],以此类推。
public int read(byte b[ ], int off, int len) 从输入流中读取至多len个字节的数据放到字节数组b中。返回值是读取的实际字节数。如果字节数组的长度为0,不会读取任何字节数据,返回0,否则至少尝试去读取一个字节的数据。如果没有获取到字节数据,表示流到达文件末尾,返回-1。第一个读取的字节存储在b[off],下一个存储在b[off+1],以此类推。
public int available( ) 返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用。注意:虽然很多InputStream的实现类可以正确的返回输入流的总字节数,但是并不是全都都可以。所以使用这个方法的返回值去分配字节大小来容纳输入流的所有数据一定不是一个正确的方法。
public long skip(long n) 忽略输入流中的n个字节,返回值是实际忽略的字节数, 如果为负数,表示没有跳过任何字节数据。
public int close( ) 关闭输入流,释放分配给输入流的系统资源。

InputStream子类:

InputStream的作用是用来表示那些那些从不同数据源产生输入的类。这些数据源包括:
  • 字节数组
  • String对象
  • 文件
  • "管道",工作方式与实际管道相似,从一端进入,从一端输出
  • 一个由其他种类的流组成的序列,以便我们可以将它们收集合并到一个流内
每一种数据源都有相应的InputStream子类。另外,FilterInputStream也属于一种InputStream,为"装饰器"类提供基类,其中"装饰器"类可以把属性或有用的接口与输入流连接在一起。


功能
ByteArrayInputStream 允许将内存中缓冲区当做InputStream使用
StringBufferInputStream 将String转换成InputStream
FileInputStream 用于从文件中读取信息
PipedInputStream 产生用于写入相关PipedOutputStream的数据。实现“管道化”概念。
SequenceInputStream 将两个或者多个InputStream对象转换成单一InputStream
FilterInputStream 抽象类,作为“装饰器”的接口。其中,“装饰器”为其他的InputStream类提供有用的功能。



4.2 OutputSream抽象类

OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。

常用方法 描述
public abstract void write(int b) 将指定字节写入到输出流中。一般是将参数b的低八位(一个字节)写入到输出流中。b的高八位被忽略掉。
public void write(byte[] b) 从字节数组b中向输出流中写入b.length个字节数据。
public void write(byte[] b,int off,int len) 从字节数组b偏移位置为off的开始位置向输出流写入len个字节数据。b[off]是第一个被写入的字节,b[off+len-1]是最后一个被写入的字节。如果b为null,会抛出NullPointer异常;如果off或者len是负数,或者off+len比字节数组b的长度大,则会抛出IndexOutOfBoundsException异常。
public void flush() 清空输出流,并强制将所有缓冲的输出字节被写出。
public void close() 关闭输出流,释放分配给输出流的系统资源。


OutputStream的子类:


该类别的类决定了输出所要去往的目标:字节数组(但不是String,不过你当然可以使用字节数组自己来创建),文件或管道。

功能
ByteArrayOutputStream 在内存中创建缓冲区,所有送往“流”的数据都要放置在此缓冲区。
FileOutputStream 用于将信息写至文件。
PipedOutputStream 任何写入其中的信息都会自动作为PipedInputStream的输出。实现“管道化”概念。
FilterOutputStream 抽象类,作为“装饰器”的接口。其中,“装饰器”为其他的OutputStream类提供有用的功能。

5. 字符流 Reader和Writer

当我们初次看到Reader和Writer类时,可能会以为这是两个用来代替InputStream和OutputStream的类,但实际上不是。尽管一些原始的“流”类库不再使用(如果使用它们,则会收到编译器的警告信息),但是InputStream和OutputStream在以面向字节流形式的IO时仍然可以提供有价值的功能。Reader和Writer则提供了兼容Unicode与面向字符的I/O功能。有时候我们还会把来自"字节"层次结构中的类和来自"字符"层次结构中类结合使用。为了实现这个目标,我们要用到"适配器"(adapter)类:InputStreamReader可以把InputStream转换为Reader,而OutputStream可以把OutputStream转换为Writer

设计Reader和Writer继承层次结构是为了国际化。老的IO流继承层次结构只能支持8位字节流,并且不能很好的处理16位的Unicode字符。设计它的目的就是为了在所有的IO操作中都支持Unicode。

Reader的子类:



Writer的子类:
QQ截图20151229213844.png

6. FileInputStream和FileOutputStream

6.1 FileInputStream

FileInputStream 从文件系统中的某个文件中获得输入字节。



(1)构造方法

构造方法 描述
FileInputStream(String name) 使用由name字符串指定路径名文件创建FileInputStream对象
FileInputStream(File file) 使用由file对象指定路径名的文件创建FileInputStream对象

// FileInputStream(String name)
String path = "D:\\Recommended system.txt";
FileInputStream stream = new FileInputStream(path);
// FileInputStream(File file)
File file = new File(path);
FileInputStream stream2 = new FileInputStream(file);

(2)说明
  • 用于读取诸如图像数据之类的原始字节流。(要读取字符流,请考虑使用 FileReader)
  • 包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。
  • 类本身只是简单地重写那些将所有请求传递给所包含输入流的 InputStream 的所有方法。
  • 其子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。

(3)实例
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class IOUtil {
public static void main(String[] args) {
try {
String path = "D:\\demo.txt";
FileInputStream stream = new FileInputStream(path);
int num = 100;
byte[] buff = new byte[num];
while((stream.read(buff,0,num)) != -1){
System.out.println("NewLine->"+new String(buff));
}//while
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果:

NewLine->Myfatherwasaself-taughtmandolinplayer.Hewasoneofthebeststringinstrumentplayersinour
NewLine->town.Hecouldnotreadmusic,butifheheardatuneafewtimes,hecouldplayit.Whenhewasyo
NewLine->unger,hewasamemberofasmallcountrymusicband.Theywouldplayatlocaldancesandona
NewLine->ccasionswouldplayforthelocalradiostation.Heoftentoldushowhehadauditionedandearneda
NewLine->positioninabandthatfeaturedPatsyClineastheirleadsinger.Hetoldthefamilythatafterhe
NewLine->washiredheneverwentback.Dadwasaveryreligiousman.Hestatedthattherewasalotofdrink
NewLine->ingandcursingthedayofhisauditionandhedidnotwanttobearoundthattypeofenvironment.nk


6.2 FileOutputStream

QQ截图20151229221635.png
(1)构造函数

构造函数 描述
FileOutputStream(String name) 使用由name字符串指定路径名的文件创建一个新的文件输出流。
FileOutputStream(String name,boolean append) 使用由name字符串指定路径名的文件创建一个新的文件输出流。如果append参数为true,那么数据将被添加到文件末尾,而具有相同名字的已有文件不会被删除(末尾添加数据);否则这个方法删除所有具有相同名字的已有文件。
FileOutputStream(File file) 使用由file对象指定路径名的文件创建一个新的文件输出流。
FileOutputStream(File file,boolean append) 使用由file对象指定路径名的文件创建一个新的文件输出流。如果append参数为true,那么数据将被添加到文件末尾,而具有相同名字的已有文件不会被删除(末尾添加数据);否则这个方法删除所有具有相同名字的已有文件。

(2)案例

package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOUtil {
public static void main(String[] args) {
try {
String path = "D:\\from.txt";
String path2 = "D:\\to.txt";
FileInputStream inputStream = new FileInputStream(path);
FileOutputStream outputStream = new FileOutputStream(path2);
int num = 100;
byte[] buff = new byte[num];
// 由文件写至内存
while((inputStream.read(buff,0,num)) != -1){
// 由内存写至文件中
outputStream.write(buff);
}//while
inputStream.close();
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

7. DataInputStream和DataOutputStream

DataInputStream和DataOutputStream是对流的扩展,让我们操作Java基本数据类型更加简单。
数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型。

package com.qunar.io;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOUtil {
public static void main(String[] args) {
try {
String path = "D:\\to.txt";
// 向文件写入操作
FileOutputStream outputStream = new FileOutputStream(path);
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
// 向文件中写入一个Int值
dataOutputStream.writeInt(10);
// 向文件中写入一个Double值
dataOutputStream.writeDouble(0.98);
// 向文件中写入一个Long值
dataOutputStream.writeLong(12l);
// 向文件中写入一个UTF-8编码值
dataOutputStream.writeUTF("我来自西安电子科技大学");
//从文件读取操作
FileInputStream inputStream = new FileInputStream(path);
DataInputStream dataInputStream = new DataInputStream(inputStream);
// 从文件中读取一个Int值
System.out.println("从文件中读取一个Int值:" + dataInputStream.readInt());
// 从文件中读取一个Double值
System.out.println("从文件中读取一个Double值:" + dataInputStream.readDouble());
// 从文件中读取一个Long值
System.out.println("从文件中读取一个Long值:" + dataInputStream.readLong());
// 从文件中读取一个UTF-8编码值
System.out.println("从文件中读取一个UTF-8编码值:" + dataInputStream.readUTF());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

运行结果:

从文件中读取一个Int值:10
从文件中读取一个Double值:0.98
从文件中读取一个Long值:12
从文件中读取一个UTF-8编码值:我来自西安电子科技大学





本人菜鸟,大牛勿喷,有问题,欢迎留言。。。。





分享到:
评论

相关推荐

    实验9 Java输入输出流.doc

    基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java输入输出流;进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、...

    Java的输入与输出.ppt )

    在Java开发环境中,主要是由包java.io中提供的一系列的类和统一的接口来实现数据输入/输出处理。把这些不同类型的输入、输出源抽象为流(Stream)。 流是在输入输出之间流动的数据缓冲区,传送是串行的。 流一般分为...

    完整版 Java基础入门教程 Java程序语言设计 04 IO流 输入输出流(共31页).ppt

    完整版 Java基础入门教程 Java程序语言设计 04 IO流 输入输出流(共31页).ppt 完整版 Java基础入门教程 Java程序语言设计 05 GUI AWT 事件模型(共27页).ppt 完整版 Java基础入门教程 Java程序语言设计 05 GUI GUI...

    Java输入输出流及在网站开发中的应用探讨.pdf

    Java输入输出流及在网站开发中的应用探讨

    Java程序设计基础:控制台输入输出.pptx

    System.in 表示Java标准输入流,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。 Scanner in =new Scanner(System.in); 从控制台获取输入 创建输入流对象in 必须先导入Scanner类 import java.util....

    运用异步输入输出流编写Socket进程通信.rar_java socket _java程序_socket java_进程通信

    在Merlin发布之前,异步输入输出流的应用还只是C,C++程序员的特殊武器 在Merlin中引入异步输入输出机制之后,Java程序员也可以利用它完成很多简洁却是高质量的代码了.本文将介绍怎样使用异步输入输出流来编写Socket...

    java开发手册、java编程和开发

    高级技术篇介绍网络编程的基本知识、输入/输出流的使用和jdbc数据库开发技术。  无论对于java的初学者,还是有一定基础的高级用户,本书都是一本难得的参考书。本书非常适合使用java进行编程和开发的本科生、研究生...

    Java输入、输出流[定义].pdf

    Java输入、输出流[定义].pdf

    IO输入输出流

    IO输入输出流,java的IO使用开发,简单易学。

    Java范例开发大全

    《Java范例开发大全》共22章,内容涉及Java开发环境的搭建、Java基础类型与运算符、条件控制语句、异常处理、数组、字符串、输入输出流、面向对象及其四大特征、内部类与接口、Java常用类、集合、多线程编程、Java...

    java开发手册

    高级技术篇介绍网络编程的基本知识、输入/输出流的使用和JDBC数据库开发技术。, 无论对于Java的初学者,还是有一定基础的高级用户,本书都是一本难得的参考书。本书非常适合使用Java进行编程和开发的本科生、研究生...

    Java开发技术大全(500个源代码).

    MySequenceIn.java 顺序输入流示例 ObjectFileTest.java 序列化对象示例 ReadAndWrite.java 读入和写出数据 ReadAndWriteFile.java 读入数据写出到文件 Student.java 定义一个用来序列化的类 ThreadIn.java ...

    JAVA开发邮件跟踪代码

    流式输入输出是一种常见的输入和输出方式,输入流代表从外部设备流入到计算机内存的数据序列,输出流代表从计算机内存流向外部设备的数据序列。它的最大特点是,数据的获取和发送是沿着数据序列的顺序进行,每一个...

    精通Java:JDK、数据库系统开发Web开发(实例代码)

    第16章 I/O输入输出流 第17章 线程 第18章 网络程序设计 第19章 国际化和本地化 第20章 泛型程序设计 第21章 访问数据库 第22章 获取XML数据 第23章 处理电子邮件 第24章 JSP技术应用 第5篇 综合案例 第25章 汉诺塔...

    java-io-guide:Java中的Java IO(输入和输出流)指南

    本指南的源代码无缺陷,并使用JDK 8进行编译和执行。 Java I / O基础 文件处理示例 File示例列表,显示了使用Java I / O创建,读取,写入,修改文件以及获取文件信息的方法。 使用BufferInputStream读取文件 使用...

    第十二章输入输出流-java程序设计ppt讲义.ppt

    第十二章输入输出流-java程序设计ppt讲义.ppt

    java源码包---java 源码 大量 实例

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    用Java实现的图片加密程序

    Java IO 图片加密,使用Java的stream流进行文件的读写,实现图片的加密和解密!

    Java的IO流讲解代码: File 类、RandomAccessFile 类、字节流(文件字节流、缓冲字节流、基本数据类型

    它包含了常见的IO类和方法的使用示例,旨在帮助理解和掌握Java中的输入输出操作。 包含: File 类、RandomAccessFile 类、字节流(文件字节流、缓冲字节流、基本数据类型字节流、打印流、对象序列化流、字节数组流)...

    java开源包8

    最大限度地减少时间和费用开发自定义的DSL(领域特定语言在Java)要求。 日志服务器 Apache Flume.tar Flume 是一个分布式、可靠和高可用的服务,用于收集、聚合以及移动大量日志数据,使用一个简单灵活的架构,就...

Global site tag (gtag.js) - Google Analytics