在Java语言中,输入和输出都被称为抽象得流,流可以被看做一组有序的字节集合,及数据在两设备之间的传输。
流的本质是数据传输,根据处理数据类型的不同,流可以分为两大类:字节流和字符流。字节流以字节(8bit)为单位,包含两个抽象类:InputStream,OutputStream.字段流以字符(16bit)为单位,根据码表映射字符,一次可以读取多个字节,它包含两个抽象类:Reader和Writer。字节流和字符流最主要的区别为:字节流在处理输入输出时不会用到缓存,而字符流用到了缓存。Java Io类在设计时采用了Decorator(装饰者)设计模式。(以下图片转自:https://www.cnblogs.com/shitouer/archive/2012/12/19/2823641.html)
各种流得使用场景:
字符流和字节流的主要区别:
1.字节流读取的时候,读到一个字节就返回一个字节;字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。
2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。
下面对各个字节流进行举例
1.FileInputStream和FileOutputStream
对文本进行操作得字符流
public class Test2 {
public static void main(String[] args) {
FileInputStream fi = null;
FileOutputStream fo = null;
try {
fi = new FileInputStream(new File("C:\\Users\\gj\\Desktop\\新建文本文档.txt"));
fo = new FileOutputStream(new File("C:\\Users\\gj\\Desktop\\新建文本文档 (2).txt"));
StringBuilder sb = new StringBuilder();
byte[] b = new byte[1024];
while (fi.read(b) > -1) {
sb.append(new String(b, "UTF-8"));
fo.write(b);
}
System.out.println(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fi != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fo != null) {
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.BufferedInputStream和 BufferedOutStream
带有缓冲区得字节流,在读取数据时,先将数据放到缓冲区中,这样可以减少对数据源的访问,提高程序得运行效率。再写代码的时候,out.txt总是写不进去,后来想起带缓冲区得输出流要记得flush一下。觉得这个流可以用做处理:图片或者压缩包。
public class Test2 {
public static void main(String[] args) {
FileInputStream fi = null;
FileOutputStream fo = null;
BufferedInputStream bs = null;
BufferedOutputStream bo = null;
try {
fi = new FileInputStream(new File("C:\\Users\\gj\\Desktop\\新建文本文档.txt"));
bs = new BufferedInputStream(fi);
fo = new FileOutputStream(new File("C:\\Users\\gj\\Desktop\\out.txt"));
bo = new BufferedOutputStream(fo);
StringBuilder sb = new StringBuilder();
byte[] b = new byte[1024];
int len = 0;
while((len = bs.read(b)) > 0) {
bs.read(b);
sb.append(new String(b,"UTF-8"));
bo.write(b, 0, len);
bo.flush();//要加这个
}
System.out.println(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fi != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fo != null) {
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bo != null) {
try {
bo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bs != null) {
try {
bs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.DataInputStream和DataOutStream
也叫数据流,用来操作基本数据类型。要读取Int类型得值,就用readInt()方法; 读取char类型得值,就用它的readChar()方法。它还可以使用readUTF()方法读取字符串。
public class Test2 {
public static void main(String[] args) {
FileInputStream fi = null;
FileOutputStream fo = null;
DataInputStream ds = null;
DataOutputStream dos = null;
try {
fi = new FileInputStream(new File("C:\\Users\\gj\\Desktop\\新建文本文档.txt"));
ds = new DataInputStream(fi);
fo = new FileOutputStream(new File("C:\\Users\\gj\\Desktop\\新建文本文档.txt"));
dos = new DataOutputStream(fo);
dos.writeDouble(1.0);
dos.writeInt(123);
dos.writeUTF("你好a");
System.out.println(ds.readDouble());
System.out.println(ds.readInt());
System.out.println(ds.readUTF());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fi != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fo != null) {
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ds != null) {
try {
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
打开文档,里面的内容是这样的
字符流举例
1.FileReader和FileWriter
public class Test2 {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(new File("C:\\Users\\gj\\Desktop\\新建文本文档.txt"));
fw = new FileWriter(new File("C:\\Users\\gj\\Desktop\\out.txt"));
char[] buf = new char[1024];
int num = 0;
StringBuilder sb = new StringBuilder();
while ((num = fr.read(buf)) != -1) {
sb.append(new String(buf, 0, num));
fw.write(buf, 0, num);
}
System.out.println(new String(sb.toString().getBytes(), "UTF-8"));// 这里不转乱码
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.BufferedReader和BufferWriter
public class Test2 {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
BufferedReader bf = null;
BufferedWriter bw = null;
try {
fr = new FileReader(new File("C:\\Users\\gj\\Desktop\\新建文本文档.txt"));
fw = new FileWriter(new File("C:\\Users\\gj\\Desktop\\out.txt"));
bf = new BufferedReader(fr);
bw = new BufferedWriter(fw);
String buffer = "";
while ((buffer = bf.readLine()) != null) {
System.out.println(buffer);
bw.write(buffer);
bw.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bf != null) {
try {
bf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}