- Java 语言采用流的机制来实现输入/输出。所谓流,就是数据的有序排列。而流可以是从某个源(称为流源,Source of Stream)出来,到某个目的地(称为流汇 ,Sink of Stream)去的。
- 流的分类:
- 流向分:输入流、输出流
- 流源分:字符流、字节流
- 功能分:节点流、处理流
- InputStream 和 OutoutStream 的等级结构
- Reader 和 Writer 的等级结构
1、对象流
ObjectInputStream 和 ObjectOutputStream
案例:通过对象流将对象保存到文件中,再通过对象流读取文件中的内容
- 将对象保存到文件必须实现Serializable序列化接口
package com.cao.demo.lesson01;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Test {
/**
* 保存(写入)
*/
public void saveObj2File() {
int num = 10;
String word = "cao";
User user = new User();
user.setName(word);
user.setAge(num);
//创建流
FileOutputStream fo = null;
ObjectOutputStream oo = null;
try {
fo = new FileOutputStream("C:\\iweb\\1.dat");
oo = new ObjectOutputStream(fo);
//写入
oo.writeInt(num);
oo.writeUTF(word);
oo.writeObject(user);
//刷新缓冲区
oo.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fo != null) {
fo.close();
}
if (oo != null) {
oo.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 读取
*/
public void readObjFromFile() {
FileInputStream fi = null;
ObjectInputStream oi = null;
try {
//创建流
fi = new FileInputStream("C:\\iweb\\1.dat");
oi = new ObjectInputStream(fi);
//读取
int num = oi.readInt();
String word = oi.readUTF();
//强制类型转换
User user = (User) oi.readObject();
//输出
System.out.println(num);
System.out.println(word);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fi != null) {
fi.close();
}
if (oi != null) {
oi.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.saveObj2File();
test.readObjFromFile();
}
}
示例类:
package com.cao.demo.lesson01;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID=100;
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
结果:
C:\Java\jdk1.8.0_181\bin\java.exe...
10
cao
User{name='cao', age=10}
Process finished with exit code 0
2、字节数组流
ByteArrayInputStream 和 ByteArrayOutputStream
-
ByteArrayInputStream
包含了一个内部缓冲区,该缓冲区包含了从流中读取的字节,ByteArrayInputStream
关闭无效,此类中的方法在关闭后还可以调用;ByteArrayOutputStream
此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用toByteArray()
和toString()
获取数据。ByteArrayOutputStream
关闭无效。此类中的方法在关闭此流后仍可被调用。
package com.cao.demo.lesson02;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws IOException {
String word = "hello!";
// 将要存放的数据转成字节数组
byte[] buf = word.getBytes();
// 将字节数组的内容保存到缓冲区
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buf);
int code;
// 每次读取一个字节对应的 unicode 码
while ((code = byteArrayInputStream.read()) != -1) {
System.out.println(code + "->" + (char) code);
}
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
byteArrayOutputStream.write(101);
byteArrayOutputStream.write(102);
byteArrayOutputStream.write('\n');
byteArrayOutputStream.write("abc".getBytes());
byteArrayOutputStream.write('\n');
byte[] a={111,111,111};
byteArrayOutputStream.write(a);
// 获取字节数组流中的内容
// 字符的可以通过 toString 方法获取内容
System.out.println(byteArrayOutputStream.toString());
// 字节的 toByteArray 获取一个字节数组
System.out.println(Arrays.toString(byteArrayOutputStream.toByteArray()));
}
}
104->h
101->e
108->l
108->l
111->o
33->!
ef
abc
ooo
[101, 102, 10, 97, 98, 99, 10, 111, 111, 111]
3、PrintWriter
package com.cao.demo.lesson03;
import java.io.File;
import java.io.PrintWriter;
public class Test {
public static void main(String[] args) {
File file = new File("C:\\iweb\\Test.txt");
PrintWriter printWriter=null;
try{
printWriter=new PrintWriter(file);
printWriter.println("hello word");
// printWriter.write(".....");
printWriter.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
if(printWriter!=null){
printWriter.close();
}
}
}
}
4、 InputStreamReader 和 OutputStreamWriter
API文档说明:InputStreamReader类是从字节流到字符流的桥接器:它使用指定的字符集读取字节并将它们解码为字符。 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节。 为了实现字节到字符的有效转换,可以从基础流中提取比满足当前读取操作所需的更多字节。为了获得最高效率,请考虑在BufferedReader中包装
InputStreamReader 和 OutputStreamWriter:
- InputStreamReader 是字节流通向字符流的桥梁,而OutputStreamWriter 是字符流通向字节流的桥梁。
package com.cao.demo.lesson04;
import java.io.*;
import java.nio.charset.Charset;
public class Test {
public static void main(String[] args) throws IOException {
String src = "C:\\iweb\\Test.txt";
FileReader fileReader = new FileReader(src);
char[] buffer = new char[8];
int len;
while ((len = fileReader.read(buffer)) != -1) {
System.out.println(new String(buffer));
}
fileReader.close();
System.out.println("------------------------");
/**
* 使用InputStreamReader
*/
// 按照字节读取
FileInputStream fileInputStream = new FileInputStream(src);
// 转换流 将字节流转成了字符流 指定编码
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, Charset.forName("GBK"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
fileInputStream.close();
inputStreamReader.close();
bufferedReader.close();
}
}
hellohel
lohellol
------------------------
hellohellohello
5、 通过 URL 读取流
URL 类:代表一个统一资源定位符,它是指向互联网“资源”的指针。
package com.cao.demo.lesson05;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.*;
public class Test {
public static void main(String[] args) throws Exception {
String src="http://qqpublic.qpic.cn/qq_public/0/0-3132403110-66C8E88CD7AEE27765F60FC87ED769F9/0?fmt=gif&size=5093&h=490&w=490&ppv=1";
URI uri=new URI(src);
URL url=uri.toURL();
// String path=url.getPath();
// System.out.println(path);
// System.out.println(url.getFile());
URLConnection urlConnection=url.openConnection();
InputStream inputStream=urlConnection.getInputStream();
FileOutputStream fileOutputStream=new FileOutputStream("C:\\iweb\\王冰冰.gif");
byte[] buff=new byte[1024];
int len;
while ((len=inputStream.read(buff))!=-1){
fileOutputStream.write(buff,0,len);
fileOutputStream.flush();
}
inputStream.close();
fileOutputStream.close();
}
}