流的概念:
在程序中所有的数据都是以流的方式进行传输和保存的,程序需要数据的时候就要使用输入流读数据,程序保存数据时就要使用输出流。
java流类图结构:
IO流的类型:
1.根据处理的数据类型分为:字节流、字符流。
2.根据数据流向分为:输出流、输入流。
字节流()
输入字节流(InputStream):
1.InputStream是所有输入字节流的父类。
2.FileInputStream、StringBufferInputStream、ByteArrayInputStream分布是是从文件、StringBuffer、Byte数组中读取数据。
3.PipedInputStream是与其他线程共用的管道中读取数据。
3.ObjectInputStream 和所有FilterInputStream 的子类都是装饰流。
InputStream的方法:
1.int read():简单读方法返回一个int值,它是从流里读出的一个字节。如果遇到文件结束则返回-1。
2.int read(byte []):将数据读入到字节数组中,并返回所读的字节数。
3.int read(byte[], int offset,int length) 将数据读入到字节数组中,并返回所读的字节数。Offset是数组的偏移量,length是读取的长度。
void close() 你完成流操作之后,就关闭这个流。如果你有一个流所组成的栈,使用过滤器流,就关闭栈顶部的流。这个关闭操作会关闭其余的流。
int available() 这个方法报告立刻可以从流中读取的字节数。在这个调用之后的实际读操作可能返回更多的字节数。
skip(long) 这个方法丢弃了流中指定数目的字符。之后,就关闭这个流。如果你有一个流所组成的栈,使用过滤器流,就关闭栈顶部的流。这个关闭操作会关闭其余的流。
输出字节流(OutputStream):
1.OutputStream是所有出字节流的父类。
2.FileOutputStream、ByteArrayInputStream分布是是从文件、Byte数组中写入数据。
3.PipedOutputStream是与其他线程共用的管道中写入数据。
4.ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。
OutputStream的方法:
1.void write(int )
2.void write(byte [])
3.void write(byte [], int, int)这些方法写输出流。和输入一样,总是尝试以实际最大的块进行写操作。
void close() 当你完成写操作后,就关闭输出流。如果你有一个流所组成的栈,就关闭栈顶部的流。这个关闭操作会关闭其余的流。
void flush() 有时一个输出流在积累了若干次之后才进行真正的写操作。flush()方法允许你强制执行写操作。
字节流对应图:
字符流()
输入字符流(Reader):
1.Reader是所有输入字符流的父类。
2.CharArrayReader、StringReader分布是是从文件、StringBuffer读取数据。
3.PipedReader是与其他线程共用的管道中读取数据。
3.ObjectReader和所有FilterReader 的子类都是装饰流。
Reader的方法:
1.int read()
2.int read(char[])
3.int read(char[], int offset, int length) 简单读方法返回一个int值,它包含从流里读出的一个字符或者-1,其中-1表明文件结束。其它两种方法将数据读入到字符数组中,并返回所读的字符数。第三个方法中的两个int参数指定了所要填入的数组的子范围。
void close()
boolean ready()
void skip (long)
boolean markSupported()
void mark(int)
void reset() 这些方法与InputStream中的对应方法相似。
输出字符流(Write):
1.Write是所有出字节流的父类。
2.CharArrayWriter、StringWriter分布是是从文件、StringBuffer读取数据。
3.PipedWriter是与其他线程共用的管道中写入数据。
4.ObjectWriter 和所有FilterWriter 的子类都是装饰流。
Writer的方法
1.void write(int c)
2.void write(char [])
3.void write(char [], int offset, int length)
4.void write(String string)
5.void write(String string, int offset, int length)
void close()
void flush()
所有这些方法与OutputStream中的方法类似。
字符流对应图:
转换流:
1.InputStreamReader:字节流转换到字符流。
2.OutputStreamWriter:字符流转换到字节流。
转换流主要是用于编码转换操作上。
高效流:(实际为装饰类)
1字节的高效流
1.1BufferedInputStream (增强字节输入流的功能,以及增添了新的功能,可以对InputStream以及其子类进行功能增强)
1.2BufferedOutputStream (增强字节输出流的功能,以及增添了新的功能,可以对OutputStream以及其子类进行功能增强)2字符的高效流
2.1BufferedReader (增强字符输入流的功能,以及增添了新的功能,可以对Reader以及其子类进行功能增强)
2.2BufferedWriter (增强字符输出流的功能,以及增添了新的功能,可以对Writer以及其子类进行功能增强)
打印流:
1.PrintStream 字节打印流:
为其他输出流添加了打印功能,使它们能够方便地打印各种数据值表示形式。
2.PrintWriter 字符打印流: 为字符输出流打印对象的格式化表示形式。
选择IO流的思路:
1.InputStream、Reader、Write、OutputStream都是抽象类,本身不能创建实例,选择它的子类。
2.按处理源和目的选择:输入流、输出流。
3.按操作的文件类型选择:字符流、字节流。
4.是否要用高效的的方法。
实例:
1.复制纯文本文件。(因为是纯文本文件,可以用字节流也可以用字符流,但是用字符流效率跟高。)
import java.io.*;
public class IoCharDemo
{
public static void copy_1() throws Exception //通过字符数组的方式复制,异常就没有细节处理通过抛向Exception。
{
FileWriter fw = new FileWriter("StringTest_副本.java"); //复制的目的文件,如果没有此文件,就会创建此文件,有此文件就会覆盖此文件。
FileReader fr = new FileReader("StringTest.java"); //复制的源文件,如果此文件没有会抛出异常。
int nlength = 0;
char[] buff = new char[1024]; //定义接受字符数组。
while ((nlength=fr.read(buff)) != -1) //当read方法返回-1时就表示文件全部读取完毕。
{
fw.write(buff, 0, nlength); //向目的文件写入字符数组中的字符。
fw.flush();
System.out.print(new String(buff ,0, nlength));
}
fw.close(); //关闭流资源。
fr.close(); //关闭流资源。
}
public static void copy_2() throws Exception //通过缓冲区的方式复制,异常就没有细节处理通过抛向Exception,它比字符数组复制的方法高效。
{
FileWriter fw = new FileWriter("StringTest_副本1.java");
FileReader fr = new FileReader("StringTest_副本.java");
BufferedWriter bw = new BufferedWriter(fw); //写入的缓冲区操作对象。
BufferedReader br = new BufferedReader(fr); //读取的缓冲区操作对象。
String line = null ;
while((line=br.readLine())!=null) //把读取的字符串放入到临时字符串变量中,如果读到为null,意味这行读取完毕。
{
bw.write(line); //把临时字符串写入到文件中
bw.newLine(); //换行
bw.flush();
}
bw.close(); //关闭流对象,也关闭了fw、fr这两个对象。
br.close();
}
public static void main(String[] args) throws Exception
{
copy_1(); //字符数组的方式复制
copy_2(); //用高效的缓冲区方法复制
}
}
2.复制map3(因为是媒体文件所以只能使用字节流)。
import java.io.*;
public class IoByteDemo
{
public static void copy_1() throws Exception //通过读取字节数组的方式复制,在读取文件时,文件不存在的时候会抛出异常,这里异常抛出处理。
{
FileInputStream fis = new FileInputStream("张敬轩 - 吻得太逼真.mp3"); //读取文件
FileOutputStream fos = new FileOutputStream("张敬轩 - 吻得太逼真_副本.mp3"); //写入文件
int nLength = 0;
byte[] buff = new byte[1024]; //定义一个字节数组接受读取到的字节。
while((nLength=fis.read(buff))!= -1) //read返回-1时意味着文件读取完毕。
{
fos.write(buff,0,nLength); //写入文件
fos.flush(); //刷新写入流。
}
fos.close(); //关闭两个流对象。
fis.close();
}
public static void copy_2()throws Exception
{
FileInputStream fis = new FileInputStream("张敬轩 - 吻得太逼真_副本.mp3");
FileOutputStream fos = new FileOutputStream("张敬轩 - 吻得太逼真_副本1.mp3");
BufferedInputStream bis = new BufferedInputStream(fis); //创建输入流的缓冲区输入对象。
BufferedOutputStream bos = new BufferedOutputStream(fos); //创建输出流的缓冲区输出对象。
int nLength = 0;
while((nLength=bis.read())!=-1) //当返回的是-1的时候意味文件读取完毕。
{
bos.write(nLength); //写入文件。
}
fos.close(); //关闭流对象,其实就是关闭fis、fos两个流对象。
fis.close();
}
public static void main(String[] args) throws Exception
{
copy_1(); //用字节数组的方法复制
copy_2(); //用高效的缓冲区方法复制
}
}
3.转换流操作。
import java.io.*;
public class IoChangeDemo
{
public static void change() throws Exception
{
FileInputStream fin = new FileInputStream("a.txt"); //通过字节流输入流方式读取文件。
InputStreamReader in = new InputStreamReader(fin,"gbk"); //字节按gbk编码转换为字符。
BufferedReader br = new BufferedReader(in); //用高效的方法读取字符。
FileOutputStream fos = new FileOutputStream("b.txt"); //通过字节输出流方式写入文件。
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8"); //字符按照utf-8编码转换为字节。
BufferedWriter bw = new BufferedWriter(osw); //用高效的方法写入字符。
String line = null;
while((line=br.readLine()) != null)
{
bw.write(line);
bw.flush();
}
br.close();
bw.close();
}
public static void main(String[] args) throws Exception
{
change();
}
}
4.打印流操作(分别打印控制台输入的字符、字符的编码值)
<span style="font-size:12px;">import java.io.*;
public class IoPrintDemo
{
public static void chPrint() throws Exception //控制台打印键盘输入的字符。
{
InputStream in = System.in; //获取键盘录入对象
InputStreamReader isr = new InputStreamReader(in); //将字节流对象转换为字符流对象。
BufferedReader br = new BufferedReader(isr); //用高效的方法读取字符。
PrintWriter pw = new PrintWriter(System.out); //设置控制台输出。
String line = null;
while((line=br.readLine())!=null)
{
pw.write(line); //写入字符。
pw.flush();
if(line.equals("over")) //如果字符为“over”,结束程序。
break;
System.out.println();
}
pw.close();
br.close();
}
public static void byPrint() throws Exception //控制台打印输入的字符的编码值。
{
InputStream in = System.in; //获取键盘录入对象
InputStreamReader isr = new InputStreamReader(in); //将字节流对象转换为字符流对象。
BufferedReader br = new BufferedReader(isr); //用高效的方法读取字符。
PrintStream ps = new PrintStream(System.out); //设置控制台输出。
String line = null;
while((line=br.readLine())!=null)
{
for(byte b: line.getBytes("gbk")) //把字符串转为字节数组遍历打印。
{
ps.println(b);
}
}
ps.close();
br.close();
}
public static void main(String[] args) throws Exception
{
chPrint();//打印字符。
byPrint();//打印字符的编码值。
}
}</span>