java.io内的流类型都分别继承这四种抽象流类型:InputStream,OutputStream,Reader,Writer。
以字节为单位的输入流的超类,InputStream提供了接口从输入流中读取字节数据。
内部缓冲区是一个字节数组,本质是通过字节数组来是实现的。
能够实现多线程间的管道通信。
是DataInputStream和BufferedInputStream的超类。
用来装饰其他输入流,允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型。
作用是为另一个输入流添加缓冲功能。
通常用于对文件进行读取操作。
File不仅仅表示文件,也可以表示目录,它的超类是Object。
用来表示开放文件,开放套接字等。
和ObjectOutputStream一起来对基本数据或对象进行持久存储。
OutputStream是以字节为单位的输出流的超类,提供了write()函数从输出流中读取字节数据。
写入ByteArrayOutputStream的数据被写入到一个byte数组,缓冲区会随着数据的不断写入而自动增长,可使用toByteArray()和toString()获取数据。
和PipedInputStream一起使用,能实现多线程间的管道通信。
是DataOutputStream,BufferedOutputStream和PrintStream的超类
用来装饰其他的输出流,允许应用程序以与机器无关方式向底层写入基本Java数据类型。
作用是为另一个输出流添加缓冲功能。
用来装饰其他输出流,为其他输出流添加功能,方便的打印各种数据值
通常用于向文件进行写入操作。
它和ObjectInputStream一起对基本数据或者对象的持久存储。
Reader是以字符为单位的输入流的超类,它提供了read()接口来取字符数据。
用于读取字符数组,继承于Reader。操作的数据是以字符为单位。
它和PipedWriter一起可以通过管道进行进程间的通讯,在使用管道通信时,必须将PipedWriter和PipedReader配套使用。
作用是为另一个输入流添加缓冲功能。
它是字节流通向字符流的桥梁。
构造函数:
InputStreamReader(InputStream in)
创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, Charset cs)
创建使用给定字符集的 InputStreamReader。
InputStreamReader(InputStream in, CharsetDecoder dec)
创建使用给定字符集解码器的 InputStreamReader。可以指定字符编码格式 。
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。
通常用于对文件进行读取操作。
Writer是以字符为单位的输出流的超类,它提供了writer()函数,进行对字符的写。
用于读取字符数组,继承于Writer,操作数据的单位是字符。
它和PipedReader一起是可以通过管道进行线程间的通讯,在使用管道通信时,必须将PipedReader和PipedWriter配套使用。
作用是为另一个输出流添加缓冲功能。
是字节通向字符流的桥梁。
用来装饰其他输出流,能为其他的输出流添加功能。
(1)FileReader继承于InputStreamReader,而InputStreamReader依赖于InputStream,因为InputStreamReader的构造函数是以InputStream为参数,传人InputStream会在InputStreamReader内部通过转码,将字节转换成字符。
(2)FileWriter继承于OutputStreamWriter,而OutStreamWriter依赖于OutputStream,因为OutputStreamWriter的构造函数是以OutputStream为参数,我们传人OutputStream会在OutputStreamWriter内部通过转码,将字节转换成字符。
是可以从一个特定的数据源(节点)读写数据的流(例如文件,内存)。
可以从或向一个特定的地方(节点)读写数据。如FileReader.
是“连接”在已经存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
处理流分类:
常用的处理流有:缓冲流,转换流,数据流,对象流,打印流。
要套接在相应的字节流之上,对读写的数据提供了缓冲功能,提高了读写的效率,同时也增加了一些更方便方法。
由于带了缓冲功能,所以就写数据的时候需要使用flush方法。
import java.io.*;
public class TestBufferStream{
public static void main(String[] args){
try{
BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\Java\\IO\\dat.txt"));//在对写文件的字节流上套接上缓冲流
BufferedReader br=new BufferedReader(new FileReader("F:\\Java\\IO\\dat.txt"));//在对读文件的字节流上套接上缓冲流
String s=null;
for(int i=1;i<=100;i++){
s=String.valueOf(Math.random());//通过随机函数给s赋值
bw.write(s); //将s写入到dat.txt文件中
bw.newLine(); //写入一个分行符。缓冲流比较好用的方法就是可以写入或读取一行的数据。
}
bw.flush(); //使内存中的所有数据立刻写出,不再缓冲。
while((s=br.readLine())!=null){ //按行读取文件内容
System.out.println(s);
}
bw.close(); //关闭处理流同时关闭里面的节点流。
br.close();
}
catch(IOException e){
e.printStackTrace();
}
}
}
用与字节数据到字符数据之间的转化。InputStreamReader需要和InputStream套接,OutputStreamWriter需要和outputStream套接。
DataInputStream 和DataOutputStream 提供将基础数据类型写入到文件中,或者读取出来,这个流的用处还是很大的,如果没有这种流的话,有一个long,本身只占8个字节,如果我要写入到文件,需要转成字符串,然后在转成字符数组,那空间会占用很多,但是有了这种流之后就很方便了,直接将这8个字节写到文件就可以了,既节约了内存空间也使程序写起来更加方便简单。但是读取的时候需要注意了,根据读取的数据类型,指针会往下移,所以你读的顺序必须要和写的顺序一致才能完成你正确的需求。否则就相当与把数据拆分了。
import java.io.*;
public class TestDataStream{
public static void main(String[] args){
ByteArrayOutputStream baos=new ByteArrayOutputStream(); //建一个节点流。
DataOutputStream dos=new DataOutputStream(baos); //在节点流上接一根数据流“管道” try{
dos.writeDouble(Math.random()); //double型 ,占8个字节
dos.writeBoolean(true); //boolean型,占一个字节
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available()); //输出流中总的可用字节数--9
DataInputStream dis=new DataInputStream(bais); //同样在输出流的外面接上数据流“管道”
System.out.println(dis.readDouble()); //直接读出double型的数
System.out.println(dis.readBoolean()); //直接读出boolean型
dos.close();
dis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
java.io中专门提供用于打印的流,这类流在写入的时候有自动flush的功能,所以不需要每打印一个东西都flush一次。
import java.io.*;
public class TestPrintStream1{
public static void main(String[] args){
PrintStream ps=null;
try{
FileOutputStream fos=new FileOutputStream("F:\\Java\\IO\\log.dat");//创建输出流,指定输出地点
ps=new PrintStream(fos); //在流外面包装打印流
}catch(IOException e){
e.printStackTrace();
}
if(ps!=null){
System.setOut(ps); //将系统的打印设置成打印流ps
}
int ln=0;
for(char c=0;c<=60000;c++){
System.out.print(c+" "); //不在打印到dos窗口,输出流直接打印到指定文件中
if(ln++>=100){
System.out.println();ln=0;
}
}
}
}
package task_scheduling;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
public class FileUtil {
/**
* 读文件 返回字符串
* @param url
* 文件地址,如:"/sdcard/test.txt"
* @return
* @throws IOException
*/
public static String readFile(String url) throws IOException {
// 读取
String str = ""; // 读取到的内容
File urlFile = new File(url);
InputStreamReader isr = new InputStreamReader(new FileInputStream(urlFile), "UTF-8");
BufferedReader br = new BufferedReader(isr);
String mimeTypeLine = null;
while ((mimeTypeLine = br.readLine()) != null) {
str = str + mimeTypeLine;
}
System.out.println("FileUtil读取内容:" + str);
return str;
}
/**
* 写文件,成功返回true
* @param filePath 文件地址
* @param sourceString 待写入字符串
* @return
*/
public static boolean writeFile(String filePath, String sourceString){
//写入
try{
System.out.println("写入文件信息:" + sourceString);
byte[] sourceByte = sourceString.getBytes();
if(null != sourceByte){
File file = new File(filePath); //文件路径(路径+文件名)
if (!file.exists()) { //文件不存在则创建文件,先创建目录
file.createNewFile();
}
FileOutputStream outStream = new FileOutputStream(file); //文件输出流用于将数据写入文件
outStream.write(sourceByte);
outStream.close(); //关闭文件输出流
}
}catch(Exception e){
System.out.println("写入失败");
return false;
}
System.out.println("写入成功");
return true;
}
}