- 浏览: 386593 次
最新评论
[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的子类:
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
(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编码值:我来自西安电子科技大学
|
本人菜鸟,大牛勿喷,有问题,欢迎留言。。。。
相关推荐
2. **字符流**:字符流处理Unicode字符数据,分为字符输入流(Reader)和字符输出流(Writer)。Reader的基类是`java.io.Reader`,Writer的基类是`java.io.Writer`。比如,`FileReader`用于读取字符文件,`...
Java中的输入流与输出流是Java I/O体系的重要组成部分,它们是Java程序进行数据传输的基础。在Java中,I/O操作被设计为流(Stream)的形式,流是数据的有序序列,可以是从内存到磁盘、从一个文件到另一个文件、甚至从...
Java输入输出流是Java编程中一个非常重要的概念,主要用于数据的读取和写入操作,包括文本文件和二进制文件。在实验9中,主要目的是理解和掌握I/O流的分类,以及如何进行文本和二进制文件的读写。 I/O流在Java中被...
字节流分为输入流(InputStream)和输出流(OutputStream)。InputStream是所有字节输入流的基类,而OutputStream是所有字节输出流的基类。 - **字符流**:专为处理文本数据设计,基于Unicode编码,每个字符为两个...
在IT行业中,输入流(InputStream)和输出流(OutputStream)是Java.IO库中的核心概念,它们用于处理数据的读取和写入。标题提到的"一个输入流写到多个输出流"是一个常见的需求,特别是在并发编程和数据传输场景中。...
Java的输入输出流(Input/Output Stream)是Java.io包...总的来说,理解并熟练运用Java的输入输出流是Java开发中不可或缺的一部分,它能帮助我们有效地读取、写入和传输各种类型的数据,从而实现程序与外部世界的交互。
通过这两个实验,我们可以了解到Java IO流的基本使用步骤:创建输入流对象,创建对应类型的输出流对象,然后通过读写方法进行数据传输,最后记得关闭流资源以释放系统资源。 此外,Java还提供了更高级的流,如`...
它们都有输入流(InputStream/Reader)和输出流(OutputStream/Writer)的区别,分别负责数据的读取和写入。 2. **字节流**:InputStream和OutputStream是所有字节流的基类,如FileInputStream和FileOutputStream...
**输入流(InputStream和Reader)** - InputStream是所有字节输入流的基类,例如: - ByteArrayInputStream:从字节数组中读取数据。 - FileInputStream:从文件中读取字节数据。 - FilterInputStream和...
1. 字节流:Java的字节流主要由两个基类InputStream和OutputStream构成,它们分别代表所有的输入流和输出流的父类。InputStream处理字节数据的读取,例如 FileInputStream,用于读取文件;OutputStream则负责字节...
Java的I/O流分为两大类:字节流(Byte Stream)和字符流(Character Stream),并根据数据流向的不同,又可以分为输入流(InputStream和Reader)和输出流(OutputStream和Writer)。 1. 字节流 字节流主要处理字节...
Java输入输出流(I/O流)是Java编程语言中用于处理数据输入和输出的重要机制。在Java中,I/O流允许程序与外部源(如键盘、显示器、文件、网络连接等)交换数据。本实例将深入讲解如何使用Java I/O流进行文件的读取和...
- **字节流**:InputStream和OutputStream是所有字节输入流和输出流的基类。例如FileInputStream和FileOutputStream用于文件的读写。 - **字符流**:Reader和Writer是所有字符输入流和输出流的基类。例如...
### Java输入输出流详解 #### 一、Java IO 概述 在计算机程序设计中,输入输出(Input/Output,简称IO)是非常重要的一个概念。它涉及到程序如何与外部世界进行数据交换,最常见的外部设备包括磁盘存储和网络通信等...
流的层次结构包括了InputStream、OutputStream、Reader和Writer这四个抽象基类,它们分别作为所有字节输入流、字节输出流、字符输入流和字符输出流的基类。此外,还有更具体的子类,如FileInputStream和...
本文将深入探讨Java中的文件输入流(FileInputStream)和文件输出流(FileOutputStream)的使用,以及如何利用它们实现文件的复制和粘贴功能。 首先,让我们了解什么是文件输入流(FileInputStream)和文件输出流...
- **InputStream** 和 **OutputStream**: 这是所有输入流和输出流类的基类,分别代表数据的读取和写入。 - **Reader** 和 **Writer**: 这是处理字符流的基类,适用于文本数据传输。 2. **字节流和字符流** - ...
- 基础流:InputStream和OutputStream是最基本的字节输入流和输出流接口,它们提供读写单个字节的方法。 - 处理流:BufferedInputStream和BufferedOutputStream是处理流,用于提高读写性能,通过内部缓冲区来批量...
在Java中,输入和输出操作通过流(Stream)进行,这些流分为字节流和字符流两大类,每类又包含输入流和输出流。 **字节流** 字节流处理的是8位的字节数据,它主要用于处理二进制数据,如图像、音频文件等。Java的...