`

Java I/O -- Byte Stream

    博客分类:
  • Java
 
阅读更多

Java I/O库的设计原则

• Java的I/O库提供了一个称做链接的机制,可以将一个流与另一个流首尾相接,形成一个流管道的链接。这种机制实际上是一种被称为Decorator(装饰)设计模式的应用。

• 通过流的链接,可以动态的增加流的功能,而这种功能的增加是通过组合一些流的基本功能而动态获取的。

• 我们要获取一个I/O对象,往往需要产生多个I/O对象,这也是Java I/O库不太容易掌握的原因,但在I/O库Decorator模式的运用,给我们提供了实现上的灵活性。

 

流的概念

Java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文件或相连的网络。流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同。Java中流的实现是在java.io包定义的类层次结构内部的。

 

流的分类

节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。

过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。

 

输入/输出流的概念

输入/输出时,数据在通信通道中流动。所谓“数据流(stream)”指的是所有数据通信通道之中,数据的起点和终点。信息的通道就是一个数据流。只要是数据从一个地方“流”到另外一个地方,这种数据流动的通道都可以称为数据流。

 

输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流”(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流” ( 数据从程序外流向程序)。

 

输入/输出类

• 在java.io包中提供了60多个类(流)。

• 从功能上分为两大类:输入流和输出流。

• 从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。

• 字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和

Writer

 

字节流和字符流

• Java 2 定义了两种类型的流:字节流和字符流。字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流读取或写入二进制数据。

字符流(character stream)为字符的输入和输出处理提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效。

• Java的原始版本(Java 1.0)不包括字符流,因此所有的输入和输出都是以字节为单位的。Java 1.1中加入了字符流的功能

• 需要声明:在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法。

• 字节流类(Byte Streams) 字节流类用于向字节流读写8位二进制的字节。一般地,字节流类主要用于读写诸如图象或声音等的二进制数据。

• 字符流类(Character Streams) 字符流类用于向字符流读写16位二进制字符。

 

 

流的分类

• 两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。

Byte Streams           Character Streams          
InputStream Reader
OutputStream Writer

 

 

 

 

 

字节流

• 字节流类为处理字节式输入/输出提供了丰富的环境。一个字节流可以和其他任何类型的对象并用,包括二进制数据。这样的多功能性使得字节流对很多类型的程序都很重要。

• 字节流类以InputStream 和OutputStream为顶层类,他们都是抽象类(abstract)

• 抽象类InputStream和 OutputStream定义了实现其他流类的关键方法。最重要的两种方法是read()和write(),它们分别对数据的字节进行读写。两种方法都在InputStream 和OutputStream中被定义为抽象方法。它们被派生的流类重写

• 每个抽象类都有多个具体的子类,这些子类对不同的外设进行处理,例如磁盘文件,网络连接,甚至是内存缓冲区。

• 要使用流类,必须导入java.io包

 

InputStream

• 三个基本的读方法

abstract int read() :读取一个字节数据, 并返回读到的数据,如果返回-1,表示读到了输 入流的末尾。

int read(byte[] b) :将数据读入一个字节 数组,同时返回实际读取的字节数。如果返回-1, 表示读到了输入流的末尾。

int read(byte[] b, int off, int len) :将数 据读入一个字节数组,同时返回实际读取的字节 数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指 定读取的最大字节数。

• 其它方法

long skip(long n) :在输入流中跳过n个字节,并返 回实际跳过的字节数。

int available() :返回在不发生阻塞的情况下,可读 取的字节数。

void close() :关闭输入流,释放和这个流相关的系 统资源。

void mark(int readlimit) :在输入流的当前位置放 置一个标记,如果读取的字节数多于readlimit设置的值, 则流忽略这个标记。

void reset() :返回到上一个标记。

boolean markSupported() :测试当前流是否支持 mark和reset方法。如果支持,返回true,否则返回 false。

• 该类的所有方法在出错条件下引发一个IOException 异常

• 通过打开一个到数据源(文件、内存或网络端口上的数据)的输入流,程序可以从数据源上顺序读取数据。

• InputStream中包含一套字节输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的InputStream子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输入方法来实现对相应外设的输入操作。

• InputStream 类 子 类 对 象 自 然 也 继 承 了InputStream类的方法。常用的方法有:读数据的方法 read() , 获取输入流字节数的方法available(),定位输入位置指针的方法skip()、reset()、mark()等。

 

 

OutputStream

• 三个基本的写方法

abstract void write(int b) :往输出流中写入一个字节。

void write(byte[] b) :往输出流中写入数组b中的所有字节。

void write(byte[] b, int off, int len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。

• 其它方法

void flush() :刷新输出流,强制缓冲区中的输出字节被写出。

void close() :关闭输出流,释放和这个流相关的系统资源。

• OutputStream是定义了流式字节输出模式的抽象类。该类的所有方法返回一个void 值并且在出错情况下引发一个IOException异常。

• 通过打开一个到目标的输出流,程序可以向外部目标顺序写数据

• OutputStream中包含一套字节输出流需要的方法,可以完成最基本的输出数据到输出流的功能。当Java程序需要将数据输出到外设时,可根据数据的不同形式,创建一个适当的OutputStream子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输出方法来实现对相应外设的输出操作。

• OutputStream类子类对象也继承了OutputStream类的方法。常用的方法有:写数据的方法write(),关闭流方法close()等。

 

 

字节流InputStream和OutputStream类的类层次

 

 

文件的读写

• Java提供了一系列的读写文件的类和方法。在Java中,所有的文件都是字节形式的。Java提供从文件读写字节的方法。而且,Java允许在字符形式的对象中使用字节文件流。

• 两个最常用的流类是FileInputStream和FileOutputStream,它们生成与文件链接的字节流。为打开文件,你只需创建这些类中某一个类的一个对象,在构造方法中以参数形式指定文件的名称

• 当你对文件的操作结束后,需要调用close( )来关闭文件。

– void close( ) throws IOException

 

FileInputStream(文件输入流)

输入流

• 读数据的逻辑为:

open a stream

while more information

read information

close the stream

• FileInputStream 类创建一个能从文件读取字节的InputStream 类,它的两个常用的构造方法如下

– FileInputStream(String filepath)

– FileInputStream(File fileObj)

– 它们都能引发FileNotFoundException异常。这里,filepath 是文件的全称路径,fileObj是描述该文件的File对象。

• 为读文件,可以使用在FileInputStream中定义的read( )方法。

– int read( ) throws IOException

• 该方法每次被调用,它仅从文件中读取一个字节并将该字节以整数形式返回。当读到文件尾时,read( )返回-1。该方法可以引发IOException异常

示例程序InputStreamTest1.java

package com.fairy.io2;

import java.io.FileInputStream;
import java.io.InputStream;

/*
 * 读数据的逻辑
 * 1.open a stream 
 * 2.while more information 
 * 3.read information 
 * 4.close the stream
 */
public class InputStreamTest1 {
	public static void main(String[] args) throws Exception {
		InputStream is = new FileInputStream("C:/file1.txt");

		byte[] buffer = new byte[200];

		int length;

		while (-1 != (length = is.read(buffer, 0, 200))) {
			String str = new String(buffer, 0, length);

			System.out.println(str);
		}

		is.close();
	}
}

 

FileOutputStream(文件输出流)

输出流

• 写数据的逻辑为:

open a stream

while more information

write information

close the stream

• FileOutputStream 创建了一个可以向文件写入字节的类OutputStream,它常用的构造方法如下

– FileOutputStream(String filePath)

FileOutputStream(File fileObj)

FileOutputStream(String filePath, boolean append)

• 它们可以引发IOException或SecurityException异常。这里filePath是文件的全称路径,fileObj是描述该文件的File对象。如果append为true,文件以追加模式打开,即新写入的字节将附加在文件的末尾,而不是从头开始

• FileOutputStream的创建不依赖于文件是否存在。在创建对象时FileOutputStream在打开输出文件之前创建它。这种情况下你试图打开一个只读文件,会引发一个IOException异常

• 向文件中写数据,需用FileOutputStream定义的write()方法。它的最简单形式如下

– void write(int byteval) throws IOException

– 该方法按照byteval指定的数向文件写入字节。尽管byteval作为整数声明,但仅低8位字节可以写入文件。如果在写的过程中出现问题,一个IOException被引发

示例程序OutputStreamTest1.java

package com.fairy.io2;

import java.io.FileOutputStream;
import java.io.OutputStream;

/*
 * 写数据的逻辑:
 * 1.open a stream
 * 2.while more information
 * 3.write information
 * 4.close the stream
 */
public class OutputStreamTest1 {
	public static void main(String[] args) throws Exception {
		OutputStream os = new FileOutputStream("C:/file2.txt", true);

		String str = "Hello World";

		byte[] buffer = str.getBytes();

		os.write(buffer);

		os.close();
	}
}

 

ByteArrayInputStream(字节数组输入流)

• ByteArrayInputStream是把字节数组当成源的输入流。该类有两个构造方法,每个构造方法需要一个字节数组提供数据源

– ByteArrayInputStream(byte array[ ])

– ByteArrayInputStream(byte array[ ], int start, int numBytes)

– 这里,array是输入源。第二个构造方法创建了一个InputStream类,该类从字节数组的子集生成,以start指定索引的字符为起点,长度由numBytes决定

示例程序ByteArrayInputStreamTest1.java

package com.fairy.io2;

import java.io.ByteArrayInputStream;

public class ByteArrayInputStreamTest1 {
	public static void main(String[] args) throws Exception {
		String temp = "Hello World";

		byte[] b = temp.getBytes();

		ByteArrayInputStream is = new ByteArrayInputStream(b);

		for (int i = 0; i < 2; i++) {
			int c;

			while (-1 != (c = is.read())) {
				if (0 == i) {
					System.out.println((char) c);
				} else {
					System.out.println(Character.toUpperCase((char) c));
				}
			}

			System.out.println();

			is.reset();
		}

		is.close();
	}
} 

ByteArrayOutputStream(字节数组输出流) 

• ByteArrayOutputStream是一个把字节数组当作输出流的实现。ByteArrayOutputStream 有两个构造方法

– ByteArrayOutputStream( )

– ByteArrayOutputStream(int numBytes)

– 在第一种形式里,一个32位字节的缓冲区被生成。第二个构造方法生成一个numBytes大小的缓冲区。缓冲区保存在ByteArrayOutputStream的受保护的buf成员里。缓冲区的大小在需要的情况下会自动增加。缓冲区保存的字节数是由ByteArrayOutputStream的受保护的count域保存的 

示例程序ByteArrayOutputStreamTest1.java

package com.fairy.io2;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class ByteArrayOutputStreamTest1 {
	public static void main(String[] args) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		String str = "Hello World";

		byte[] buffer = str.getBytes();

		baos.write(buffer);

		byte[] result = baos.toByteArray();

		for (byte b : result) {
			System.out.print((char) b + " ");
		}
		
		OutputStream os = new FileOutputStream("bytearray.txt");
		baos.writeTo(os);
		
		baos.close();
		os.close();
	}
}

– writeTo:将此字节数组输出流的全部内容写入到指定的输出流参数中

– reset:将此字节数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有输出。通过重新使用已分配的缓冲区空间,可以再次使用该输出流。

 

 


过滤流

• 在InputStream类和OutputStream类子类中,FilterInputStream和FilterOutputStream过滤流抽象类又派生出DataInputStream和DataOutputStream数据输入输出流类等子类。

• 过滤流的主要特点是在输入输出数据的同时能对所传输的数据做指定类型或格式的转换,即可实现对二进制字节数据的理解和编码转换。

• 数据输入流DataInputStream中定义了多个针对不同类型数据的读方法,如readByte() 、 readBoolean() 、

readShort()、readChar()、readInt()、readLong()、readFloat()、readDouble()、readLine()等。

• 数据输出流DataOutputStream中定义了多个针对不同类型数据的写方法, 如 writeByte() 、writeBoolean() 、

writeShort()、writeChar()、writeInt()、writeLong()、writeFloat()、writeDouble()、writeChars()等。

• 过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。

• 类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。

示例程序DataStreamTest1.java

package com.fairy.io2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class DataStreamTest1 {
	public static void main(String[] args) throws Exception {
		DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
				new FileOutputStream("data.txt")));

		byte b = 3;
		int i = 12;
		char ch = 'a';
		float f = 3.3f;

		dos.writeByte(b);
		dos.writeInt(i);
		dos.writeChar(ch);
		dos.writeFloat(f);

		dos.close();

		DataInputStream dis = new DataInputStream(new BufferedInputStream(
				new FileInputStream("data.txt")));

		System.out.println(dis.readByte());
		System.out.println(dis.readInt());
		System.out.println(dis.readChar());
		System.out.println(dis.readFloat());
		
		dis.close();
	}
}

 

基本的流类

• FileInputStream和FileOutputStream

节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。

• BufferedInputStream和 BufferedOutputStream

过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。

• DataInputStream和DataOutputStream 过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数 据类型的功能。

• PipedInputStream和PipedOutputStream

管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有 用,必须同时构造管道输入流和管道输出流。


示例程序BufferedOutputStreamTest1.java

package com.fairy.io2;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class BufferedOutputStreamTest1 {
	public static void main(String[] args) throws Exception {
		BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream("buffered.txt"));

		bos.write("http://www.google.com".getBytes());

		bos.close();
	}
}
 

 

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 85.6 KB
分享到:
评论

相关推荐

    Java I/O 第二版

    OReilly.Java.I.O.2nd.Edition.May.2006 Java的io包主要包括: 1. 两种流:字节流(byte Stream)和字符流(character stream),这两种流不存在所谓的谁代替谁、谁比谁高级之说,它们互为补充,只是侧重点不同...

    Java I/O层次结构详解

    - **流(Stream)**:Java I/O中的流分为字节流(Byte Stream)和字符流(Character Stream)。字节流处理单个字节的数据,如InputStream和OutputStream家族;字符流处理Unicode字符,如Reader和Writer家族。 - **...

    Java I/O详细笔记

    ### Java I/O详细笔记 #### 一、流的分类 Java I/O系统主要涉及四种基本的流分类方式:根据数据流动的方向、数据处理的类型、流处理的源以及是否使用了缓冲机制。 **1. 按数据流动方向** - **输入流(Input ...

    java基础之I/O流

    I/O流分为两大类:字符流(Character Stream)和字节流(Byte Stream),每类又分为输入流(Input Stream)和输出流(Output Stream)。下面将详细解释这些概念以及它们在Java中的应用。 1. 字节流: - 输入流:...

    怎么使用I/O编程???

    Java的I/O类库还区分了字节流(Byte Stream)和字符流(Char Stream)。字节流处理的数据单位是字节,适用于所有类型的数据,如图像、音频等非文本数据。字符流基于Unicode编码,更适合处理文本数据。常见的字节流类...

    accii码表(包括扩展)以及Java I/O

    Java提供了丰富的I/O类库,包括字节流(Byte Stream)和字符流(Character Stream)。字节流处理原始的8位字节数据,而字符流则以Unicode字符为单位进行操作,更适用于文本处理。 1. 字节流: - InputStream和...

    java I/0实现

    根据数据处理方式的不同,Java I/O流主要分为两大类:字节流(Byte Stream)和字符流(Character Stream)。字节流处理单个字节的数据,而字符流则处理Unicode字符序列。这两类流都有输入流和输出流之分,分别由四个...

    Java课程设计报告书-学生版-1_I/O流与文件课程设计_

    在Java编程语言中,I/O流(Input/Output Stream)是处理数据输入和输出的核心机制。本课程设计报告书——“Java课程设计报告书-学生版-1_I/O流与文件课程设计_”旨在帮助学生深入理解并掌握如何在Java中进行文件操作...

    Java IO.pdf

    - **流(Stream)的概念**:Java 的所有输入输出(I/O)设施都是基于流的,流提供了一种简单的方式来读写不同类型的二进制数据。 - **四种主要流类别**: - 字节流(Byte Streams) - 字符流(Character Streams) - 输入...

    Java文件输入输出(I/O)流.pdf

    Java I/O系统是基于流(Stream)的概念构建的,流可以被视为数据的有序序列,既可以是从内存到硬盘的写入,也可以是从硬盘到内存的读取。在Java中,文件被看作是字节流,这意味着文件中的数据以字节为单位进行传输。...

    Java开发核心技术-下.doc

    Java的I/O系统是建立在流(Stream)的概念上的,允许数据从不同来源(如键盘、文件、网络)到不同目的地(屏幕、文件、网络)进行串行化传输。在Java的核心库`java.io`中,提供了丰富的类和接口来支持各种I/O操作,...

    第8章JavaIO第8章JavaIO第8章JavaIO第8章JavaIO第8章JavaIO第8章JavaIO

    Java I/O流基于stream的概念,提供了处理数据输入和输出的方法。I/O流分为两大类:字节流(Byte Streams)和字符流(Character Streams)。字节流处理8位字节的数据,而字符流处理16位Unicode字符。java.io包包含了...

    JDK输入/输出流详解(非常细)

    Java I/O 流可以根据它们的用途进一步划分为节点流(Node Stream)和过滤流(Filter Stream)。 - **节点流**:直接与一个特定的I/O设备进行交互,例如文件或网络连接。节点流是数据流动的起始点或终点,比如`...

    JAVA课件Java IO.ppt

    首先,Java I/O的核心概念是“流”(Stream)。流可以被视为数据的流动通道,它可以从数据源(DataSource)读取信息到程序(Program),也可以将程序中的信息写入数据目的地(ProgramDataDest)。流分为两大类:字节...

    Java文件上传下载

    Java文件上传和下载是通过Servlet API实现的,涉及HTTP请求的处理、文件I/O操作以及HTTP响应头的设置。在实际项目中,还需要考虑安全性(如防止文件覆盖、非法文件类型上传等)和性能优化(如使用多线程、缓存等)。...

    tomcat文件上传下载、删除

    总结,Tomcat文件上传、下载和删除涉及的主要知识点包括HTTP协议、Servlet API、文件I/O操作以及权限管理。在实际应用中,开发者需要根据具体需求选择合适的方法和技术,并注意处理可能出现的各种异常情况。通过不断...

    java io 2nd

    在Java中,I/O操作是通过流(Stream)来实现的。流可以被想象为一个数据的通道,可以是字节流,也可以是字符流。字节流主要用来处理二进制数据,而字符流则用于处理文本数据。 - **字节流与字符流**:Java I/O库...

    IODemo.zip

    首先,Java I/O流分为两大类:字节流(Byte Stream)和字符流(Character Stream)。字节流处理单个字节的数据,适用于所有类型的数据,包括图片、音频等非文本数据。而字符流则处理Unicode字符,主要用于文本数据。...

    Java语言程序设计完整版资料.ppt

    在Java中,I/O(Input/Output)主要用于处理数据的传输,包括从控制台、文件、网络接口等数据源读取和向这些地方写入数据。I/O操作通常以流的形式进行,数据按照一定的顺序依次读取或写入。 一、I/O基本概念 1. ...

Global site tag (gtag.js) - Google Analytics