IO流详解
1. IO流概述和分类
1.1 IO流概述
- IO:输入/输出 (Input/Output)
- 流:是一种抽象概念,是对数据传输的总称,也就是说数据在设备之间的传输称为流,流的本质是数据传输
- IO流就是用来处理设备之间的传输问题:
常见的应用:文件传输,文件复制,文件下载
1.2 IO流的分类
- 按照数据的流向:
输入流:读数据 输出流:写数据 - 按照数据类型分类:
字节流 (InputStream,OutputStream):字节输入流,字节输出流 字符流 (Reader,Writer):字符输入流,字符输出流 - 区别:
字节流可以处理所有类型文件,但字符流只能处理纯文本文件 ,所以如果是纯文本文件,优先考虑字符流,如果不知道使用哪一种,就使用字节流
2.字节流
2.1 字节流概述
字节流抽象基类:
-
InputStream :这个抽象类是表示字节输入流的所有类的超类 - 已知直接子类: AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream -
OutputStream :这个抽象类时表示字节输出流的所有类的超类 -已知直接子类: ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream -
子类名特点:子类名称都是以父类名称作为后缀
常用的几个子类的分类: 文 件 :FileInputStream 、 FileOutputStrean 数 组 :ByteArrayInputStream 、 ByteArrayOutputStream 管 道 :PipedInputStream 、PipedOutputStream 缓冲流:BufferedInputStrean 、BufferedOutputStream 数据流: DataInputStream 、DataOutputStream
2.2 字节流写出数据
如何向文件写数据?向文件写数据就是将数据写出,必然用的是字节输出流,而像文件写数据,用的就是字节输出流抽象类的子类FileOutputStream.
步骤
- 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象写数据的方法
- 关闭资源(关闭此文件输出流并是否与此流相关联的任何系统资源)
代码示例
package IO;
import java.io.*;
public class Demo01 {
public static void main(String[] args) {
FileOutputStream fout = null;
try {
fout = new FileOutputStream("Demo01.txt");
fout.write(65);
String str=" Happy new year!";
fout.write(str.getBytes());
fout.write(str.getBytes(),2,8);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节流写数据实现换行: - windows:\r\n - Linux:\n - mac:\r
字节流写数据实现追加: public FileOutputStream(File file, boolean append) 创建一个文件输出流写入指定的 File对象表示的文件。如果第二 true,然后字节将被写入到文件的末尾而不是开头。
字节流写数据加异常处理
2.3字节流读入数据
字节流写入的基类是InputStream,如果是操作文件,应该用它的子类FileInputStream
步骤
- 创建字节流输入对象
- 调用字节输入流对象的读数据方法
- 释放资源
代码示例
package IO;
import java.io.*;
public class Demo02 {
public static void main(String args[]) {
FileInputStream fis=null;
try {
fis = new FileInputStream("Demo01.txt");
int b;
System.out.print("方式一:");
while((b=fis.read())!=-1) {
System.out.print((char)b);
}
System.out.println();
fis = new FileInputStream("Demo01.txt");
byte by[]=new byte[30];
int len;
while((len=fis.read(by))!=-1) {
System.out.println("方式二:"+new String(by,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.4 字节缓冲流
BufferedInputStream :创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。BufferedOutputStream :该类实现缓冲输出流,通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层的系统调用。- 这两个流主要用来提高读写数据的效率
BufferedInputStream(InputStream in) 创建一个 BufferedInputStream和保存它的参数,输入流 in,供以后使用 BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,将数据写入到指定的基本输出流中。
字节缓冲流仅仅提供字节缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
代码示例
package IO;
import java.io.*;
public class Demo03 {
public static void main(String[] args) {
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try {
bos=new BufferedOutputStream(new FileOutputStream("Demo03.txt"));
bis=new BufferedInputStream(new FileInputStream("Demo03.txt"));
bos.write("hello world".getBytes());
bos.close();
int len;
byte b[]=new byte[1024];
while((len=bis.read(b))!=-1)
{
System.out.print(new String(b,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(bis!=null)
bis.close();
if(bos!=null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.字符流
3.1 为什么出现字符流
3.2字符流概述
字节流抽象基类:
-
Reader :这个抽象类是表示字节输入流的所有类的超类 - 已知直接子类: BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader -
Writer :这个抽象类时表示字节输出流的所有类的超类 -已知直接子类: BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter -
子类名特点:子类名称都是以父类名称作为后缀
常用的几个子类的分类: 文 件 :FileReader 、 FileWriter 数 组 :CharArrayReader 、 CharArrayReader 管 道 :PipedReader 、PipedWriter 缓冲流:BufferedReader 、 BufferedWriter 转换流:InputStreamReader 、OutputStreamReader
3.3字符流写数据
步骤跟之前一样,这里用代码演示五种写数据的方式
package IO;
import java.io.*;
public class Demo05 {
public static void main(String[] args) {
OutputStreamWriter osw= null;
try {
osw=new OutputStreamWriter(new FileOutputStream("Demo04.txt"));
char cbuf[]= {'b','e','a','t','u','f','u','l'};
osw.write(cbuf, 1, 5);
osw.write(65);
osw.write(cbuf);
String str="hello";
osw.write(str);
osw.write(str,1,2);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(osw!=null)
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.4字符流读数据
这里用代码演示读数据的两种方式
package IO;
import java.io.*;
public class Demo07 {
public static void main(String[] args) {
InputStreamReader isr=null;
int c;
try {
isr=new InputStreamReader(new FileInputStream("Demo04.txt"));
while((c=isr.read())!=-1) {
System.out.print((char)c);
}
System.out.println();
isr=new InputStreamReader(new FileInputStream("Demo04.txt"));
char []cbuf=new char[1025];
while((c=isr.read(cbuf))!=-1) {
System.out.print(new String(cbuf,0,c));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(isr!=null)
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.5 字符缓冲流
字符缓冲流
BufferedWriter :将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区的大小,或者可以接受默认大小,默认值足够大,可以用于大多数用途BufferedReader :从字符输入流读取文本,缓冲字符,以提供数组,字符和行的高效读取,可以指定缓冲区大小,默认值足够大,可以用于大多数用途
BufferedWriter(Writer out) BufferedReader(Reader in)
代码示例
package IO;
import java.io.*;
public class Demo08 {
public static void main(String[] args) {
BufferedWriter bw=null;
BufferedReader br=null;
try {
bw= new BufferedWriter(new FileWriter("Demo08.txt"));
br= new BufferedReader(new FileReader("Demo08.txt"));
bw.write("hello");
bw.write("world");
bw.close();
int c;
while((c=br.read())!=-1) {
System.out.print((char)c);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(br!=null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if(bw!=null)
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
|