JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流相关的知识,希望对你有一定的参考价值。
文章目录
1.关于流的体系分类
1.1输入和输出
输入(input):把电脑硬盘上的文件(数据)读到程序中;进行数据的read操作.
输出(output):从程序向外部设备写入数据,即数据的write操作.
输入和输出都是相对于程序的操作.
1.2输入流和输出流
按数据的传输方向分为:输入流,输出流.
输入流:从程序中读取;
输出流:从程序向外写入.
1.3字节流和字符流
按流的数据单位(编码格式)分为:字节流,字符流.
字节流:以字节为单位. 所有以Stream结尾的类.(可以读写二进制文件,主要处理音频、图片、歌曲、字节流,处理单元为1个字节。)
字符流:以字符为单位,所有以Reader和Writer结尾的类.(主要处理字符或字符串,只能读取纯文本文件,字符流处理单元为1个字符。字节流将读取到的字节数据,去指定的编码表中获取对应文字)
- InputStream和OutputStream的子类都是字节流;
- Reader和Writer的子类都是字符流.
1.4节点流和处理流
按封装类型(功能)不同流分为节点流,处理流.
节点流:如果流封装的是某种特定的数据源,如文件、字符串、字符串数组等,则称为节点流。
处理流:如果流封装的是其它流对象,称为处理流。处理流提供了缓冲功能,提高读写效率,同时增加了一些新的方法。
2.字节流
java.io.InputStream ;这个类直接继承Object类;它是输入字节流的所有类的超类.
java.io.OutputStream;也是直接继承Object类;它是字节输出流的所有类的超类。 输出流接收输出字节并将其发送到某个接收器。
字节流中常用类
字节输入流 FileInputStream
字节输出流 FileOutputStream
字节输入流 FileInputStream与字节输出流 FileOutputStream
构造方法
FileInputStream构造方法
常用的有两种
构造方法 | 注释 |
---|---|
FileInputStream(File file) | 通过打开与实际文件的连接创建一个 FileInputStream 对象,该文件由文件系统中的 File对象 file命名 |
FileInputStream(String name) | 通过打开与实际文件的连接来创建一个 FileInputStream 对象,该文件由文件系统中的路径名 name命名 |
在创建FileInputStream对象时,指定要输入(读取)的文件;文件不存在就会抛出异常.
FileOutputStream构造方法
构造方法 | 注释 |
---|---|
FileOutputStream(File file) | 创建文件输出流以写入由指定的 File对象表示的文件 |
FileOutputStream(String name) | 创建文件输出流以指定的名称写入文件 |
在创建FileOutputStream对象时,指定要输出(写入的)目标文件,若文件不存在则会自动创建.但是文件夹不会自动创建.
简单的读写方法
输入流的读取方法
- public int read( )
从该输入流读取一个字节的编码值。每read一次就会读取一个字节;返回它的编码值; 以整数的形式返回(0~255),当读到文件内容末尾时,就返回-1.
使用时需要抛出异常.
例如:读取这个文件;其中,汉字是以utf-8编码的.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) {
try {
FileInputStream fis=new FileInputStream("F:/JAVAIO流练习使用的文件夹/文本文件.txt");
int r0=fis.read();
System.out.println(r0);//读取 a 97
int r1=fis.read();
System.out.println(r1);//读取 字 第一个字节 229
int r2=fis.read();
System.out.println(r2);//读取 字 第二个字节 173
int r3=fis.read();
System.out.println(r3);//读取 字 第三个字节 151
int r4=fis.read();
System.out.println(r4);//读取 母 第一个字节 230
int r5=fis.read();
System.out.println(r5);//读取 母 第二个字节 175
int r6=fis.read();
System.out.println(r6);//读取 母 第三个字节 141
int r7=fis.read();
System.out.println(r7);//读取 A 65
int r8=fis.read();
System.out.println(r8);//读取到末尾 ,返回 -1
int r9=fis.read();
System.out.println(r9);//读取到末尾 ,返回 -1
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
在输出时使用while循环,就会简便很多.
//可使用while循环读取;
int r=0;
while ((r=fis.read())!=(-1)){
System.out.println(r);
}
输出流的写入方法
- public void write(int b)
将指定的字节(向输出流中写入一个字节数据,该字节数据为参数b的低8位)写入此文件输出流,读取一个字节就会写入一个字节.
输入流和输出流中都有关闭流的方法
- public void close( )
关闭此文件输出流并释放与此流相关联的任何系统资源。
关闭传输通道(流的对象);释放系统资源;
一段简单完整的字节流输入输出:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//创建FileInputStream对象时,指定要输入的文件;当文件不存在,会抛异常.
fis=new FileInputStream("F:/JAVAIO流练习使用的文件夹/文本文件.txt");
//创建FileOutputStream对象时,指定要输出的目标文件;当文件不存在时;会自动创建输出的目标文件,
fos=new FileOutputStream("F:/JAVAIO流练习使用的文件夹/写入文本.txt");
//可使用while循环读取;
int r=0;//记录每次读到的字节值;
while ((r=fis.read())!=(-1)){
System.out.println(r);
fos.write(r);//向指定的文件输出字节;
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}finally {
//关闭传输通道(流的对象);释放系统资源;
try {
if(fis!=null)
fis.close();
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在关闭流之后才可进行文件的删除操作.
在日常练习中,在抛出异常时;可以选择声明异常;但是实际的项目中是不允许此类处理方法的.
高效读写
输入流的读取方法
- public int read( byte[ ] b)
该方法每次从输入流中读取一个byte数组的长度个字节;返回的是数组中实际传入的内容个数;当读取结束时返回值为-1;
输出流的写入方法
- public void write(byte[ ] b,int off,int len)
向外输出一个byte数组个字节,从数组的指定位置开始;写入指定长度的内容.
例如:将一个含有16字节内容的文本文件写入到一个空的文本文件中.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo04 {
//练习使用,仅声明异常;
public static void main(String[] args) throws IOException {
//创建FileInputStream对象;
FileInputStream fis=new FileInputStream("F:/JAVAIO流练习使用的文件夹/字节流练习文档1.txt");
//创建FileOutputStream对象;
FileOutputStream fos=new FileOutputStream("F:/JAVAIO流练习使用的文件夹/字节流练习文档2.txt");
//创建一个长度为10的byte数组;相当于一个缓冲区;
byte[] bytes=new byte[10];
int length=0;
//该方法每次从输入流中读取一个byte数组的长度个字节;返回的是数组中实际传入的内容个数;当读取结束时返回值为-1;
while((length=fis.read(bytes))!=-1){
//向外输出一个byte数组个字节,从数组的指定位置开始;写入length个的内容.
fos.write(bytes,0,length);
}
//关闭流;
fis.close();
fos.close();
}
}
3.字节缓冲流
按着流的封装类型分为节点流和处理流.
上面的字节流也是一种节点流.
而处理流封装的是其他流的对象.
那么封装字节流对象的即为字节缓冲流.
字节缓冲流:不是直接对文件进行读取或写入,仅仅是包装节点流,提供额外的缓冲功能.
常用类:
缓冲字节输入流 BufferedInputStream.
缓冲字节输出流 BufferedOutputStream.
构造方法
缓冲字节输入流BufferedInputStream
构造方法 | 注释 |
---|---|
public BufferedInputStream(InputStream in) | 创建一个 BufferedInputStream并保存其参数,输入流 in ;默认缓冲区字节长度8192(8KB) ,(private static int DEFAULT_BUFFER_SIZE = 8192;) |
public BufferedInputStream(InputStream in,int size) | 创建 BufferedInputStream;可输入指定size来指定缓冲区大小,并保存其参数,输入流 in |
缓冲字节输出流BufferedOutputStream
构造方法 | 注释 |
---|---|
public BufferedOutputStream(OutputStream out) | 创建一个新的缓冲输出流,以将数据写入指定的底层输出流;缓冲区默认长度8192个字节 |
public BufferedOutputStream(OutputStream out,int size) | 创建一个新的缓冲输出流,可以指定的缓冲区大小将数据写入指定的底层输出流 |
//例如:对一个文件的复制粘贴;
import com.sun.istack.internal.NotNull;
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws IOException {
//创建节点输入流对象;指定要读取的文件;
FileInputStream fis=new FileInputStream("F:/鲁大师.exe");
//创建输入处理流;
BufferedInputStream bis=new BufferedInputStream(fis);
//创建节点输出流对象,指定写入的文件;
FileOutputStream fos=new FileOutputStream("F:/JAVAIO流练习使用的文件夹/鲁大师.exe");
//创建输出处理流;
BufferedOutputStream bos=new BufferedOutputStream(fos);
/* //方式1:效率过慢;
int r=0;
//方法public int read();需要一个字节一个字节放到输入缓冲区;
// 默认的8192个字节空间装满(内容结束)后;再统一读取到程序中;
while((r=bis.read())!=-1){
//方法public void write(int b);需要一个字节一个字节放到输出缓冲区;
//默认的8192个字节空间装满(内容结束)后;再统一从程序向外写入目标文件;
bos.write(r);
}*/
//方式2:比较高效的读写;
//由于缓冲区的空间就是个数组;这里再创建一个相当于是双重数组;
//实际上是使用了字节输入输出的高效读写方法;将字节放到字节中,一部分一部分地传进缓冲区;
byte[] bytes=new byte[3072];
//方法public int read(byte[] b);
//每read一次就读了3072个字节的的内容;然后放到输入缓冲区;
//注意:当这个定义的数组大于缓冲区的空间时,缓冲区会失效;内容会直接读取到程序中;
//而不是先存到缓冲区;
int length=0;
while((length=bis.read(bytes))!=-1){
//方法public void write(byte[] b, int off, int len)
//当调用write方法时;先会判断输出缓冲区是否装满;装满后就从程序向目标文件写入;
bos.write(bytes,0,length);
}
//刷新输出缓冲区;
//public void flush()
bos.flush();
//关闭缓冲流;
bis.close();
bos.close();
}
}
方式1中:
用到的方法.
- public int read( );
需要一个字节一个字节放到输入缓冲区;
每次判断默认的8192个字节空间(或者指定的空间)装满后;再统一读取到程序中; - public void write(int b);
需要一个字节一个字节放到输出缓冲区;
每次判断默认的8192个字节空间(或者指定的空间)装满后;再统一从程序向外写入目标文件; - public void flush( )
刷新输出缓冲区.
方式2中:
用到的方法:
-
public int read(byte[ ] b);
读取多个字节,存到一个byte数组中,再进入输入缓冲区;判断当缓冲区装满时就全部读取到程序中;当定义的数组空间大于缓冲区默认的8192字节(或者自己指定的大小)空间;缓冲区就会失效;这时,文件会直接一个数组一个数组地读取到程序中去.
-
public int read(byte[ ] b);
写入多个字节,存到一个byte数组中,再进入输入缓冲区,判断当缓冲区装满时就全部写入目标文件;当定义的数组空间大于缓冲区默认的8192字节(或者自己指定的大小)空间;缓冲区就会失效;这时,文件会直接一个数组一个数组地写入目标文件.
以上是关于JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流的主要内容,如果未能解决你的问题,请参考以下文章