重要的流总览
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream |
重点流!!
FileInputStream && FileOutputStream
//文件输入流 文件输入流
//不带缓冲区的FileInputStream && FileOutputStream
public class BlogTest {
// 写文件
@Test
public void test1(){
FileOutputStream fos = null;
try {
fos = new FileOutputStream("Numbers");
for (int i = 0; i < 50; i++) {
fos.write((char)(Math.random() * 100));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 读文件
@Test
public void test2(){
FileInputStream fis = null;
try {
fis = new FileInputStream("Numbers");
int ch;
while ((ch = fis.read()) != -1) {
System.out.println(ch);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
BufferedReader && BufferedWriter
public class BlogTest {
// 输出
@Test
public void test2(){
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter("Numbers2");
bw = new BufferedWriter(fw);
for (int i = 0; i < 26; i++) {
bw.write('a' + i);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//Reader
@Test
public void test1(){
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader("Numbers2");
br = new BufferedReader(fr);
String ch;
while ((ch = br.readLine()) != null) {
System.out.println(ch);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
利用BufferedXX进行文件复制
@Test
public void copy(){
FileReader fr = null;
BufferedReader br = null;
FileWriter fw = null;
BufferedWriter bw = null;
try {
fr = new FileReader("cruel_summer.txt");
br = new BufferedReader(fr);
fw = new FileWriter("copy_cruel_summer.txt");
bw = new BufferedWriter(fw);
String s;
while ((s = br.readLine()) != null){
bw.write(s);
bw.newLine();
}
} 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();
}
}
}
}
节点流和缓冲流复制大文件效率对比
先说结论:复制文件时使用缓冲流反而慢, 用节点流快
//缓冲流
@Test
public void exer2() { // 使用缓冲流反而慢, 用节点流快
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
long l1 = System.currentTimeMillis();
try {
fis = new FileInputStream("day24.zip");
bis = new BufferedInputStream(fis);
fos = new FileOutputStream("test2.zip");
bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[8192];
int n;
while ((n = bis.read(buffer)) != -1) {
bos.write(buffer, 0, n);// 实际读了n个, 写n个字节
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long l2 = System.currentTimeMillis();
System.out.println("使用BufferedInputStream : " + (l2 - l1));
}
//节点流
@Test
public void exer1() {
FileInputStream fis = null;
FileOutputStream fos = null;
long l1 = System.currentTimeMillis();
try {
fis = new FileInputStream("day24.zip");
fos = new FileOutputStream("test3.zip");
byte[] buffer = new byte[8192];
int n;
while ((n = fis.read(buffer)) != -1) {
fos.write(buffer, 0, n);// 实际读了n个, 写n个字节
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long l2 = System.currentTimeMillis();
System.out.println("使用inputStream : " + (l2 - l1));
}
原因是 : BufferedXXX流里本身就有一个缓冲区,来回缓冲效率反而不高.
InputStreamReader && OutputStreamWriter
转换流 :
- InputStreamReader 字节流->字符流, 解码
- 在转换时可以指定编码方式
- OutputStreamWriter 字节流->字符流, 编码
- 在转换时可以指定编码方式
// 读取ArrayList.java文件, 写成另一个文件ArrayList_utf8.java
@Test
public void test23() {
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader buf = null;
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bufw = null;
try {
fis = new FileInputStream("ArrayList.java");
isr = new InputStreamReader(fis, "gbk"); // 指定编码方式
buf = new BufferedReader(isr);
fos = new FileOutputStream("ArrayList_utf8.java");
osw = new OutputStreamWriter(fos, "utf8");
bufw = new BufferedWriter(osw);
String s;
while ((s = buf.readLine()) != null) {
System.out.println(s);
bufw.write(s);
bufw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (buf != null) {
try {
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufw != null) {
try {
bufw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test21() {
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter buf = null;
try {
fos = new FileOutputStream("转换流写文本");
//osw = new OutputStreamWriter(fos); // 转换时以默认编码方式
osw = new OutputStreamWriter(fos, "gbk"); // 转换时以gbk编码
buf = new BufferedWriter(osw);
buf.write("alsdkjfalksjfdlkajsdf");
buf.newLine();
buf.write("来一些汉字");
buf.newLine();
buf.write("134234234234234");
buf.newLine();
buf.write("来一些汉字2");
buf.newLine();
buf.write("来一些汉字3");
buf.newLine();
buf.write("来一些汉字4");
buf.newLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (buf != null) {
try {
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ObjectInputStream && ObjectOutputStream
需求: 先写随机个随机整数,再写随机个随机long型整数
思路:在文件内先写入随机数的个数当做标识.
@Test
public void test2() {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("随机数");
ois = new ObjectInputStream(fis);
// 不知道有多少个随机数
int count = ois.readInt();
for (int i = 0; i < count; i++) {
int i1 = ois.readInt();
System.out.println(i1);
}
System.out.println("*****************************");
int count2 = ois.readInt();
for (int i = 0; i < count2; i++) {
long l = ois.readLong();
System.out.println(l);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test1() {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream("随机数");
oos = new ObjectOutputStream(fos);
int rand = (int)(Math.random() * 100);
oos.writeInt(rand); // 先写整数个数
for (int i = 0; i < rand; i++) { // 实际再写整数
oos.writeInt((int)(Math.random() * 100));
}
int rand2 = (int)(Math.random() * 100);
oos.writeInt(rand2); // 写long个数
for (int i = 0; i < rand2; i++) {
oos.writeLong((int)(Math.random() * 10000));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
序列化 && 反序列化
-
对象序列化 : 把对象在GC区中的数据写入输出流 ObjectOutputStream writeObject
要想序列化的对象的类必须实现Serializable接口
静态属性和transient修饰的成员不能被序列化.
-
反序列化 : 把输入流中的数据还原成对象