流
流就是一根带有按钮(fr.read();
)的管子 连接文件到程序
读取文档内容:
package com.hbx; import java.io.FileNotFoundException; import java.io.FileReader;//输入输出流 public class bitterdaytj { public static void main(String[] args) throws FileNotFoundException { FileReader fr = new FileReader("文档地址"); int ch = 0; while(ch != -1){ System.out.printf("%c",(char)ch); ch = fr.read(); } fr.close(); } }
流的定义:流就是程序和设备之间嫁接起来的一根用于数据传输的管道,这个管道有很多按钮,不同的按钮可以实现不同的功能。
这根带按钮的用于数据传输的管道就是流
流就是一根管道
节点流与处理流
节点流作为一个特定的数据源(节点)读写数据(如:文件、内存)
处理流是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理位程序提供更为强大的读写功能
节点流:也叫原始流
处理流:也叫包裹流
-
什么叫做流
-
流与类的关系:
-
如果一个类使用做设备和程序之间的数据传输,则这个类有一个新的名字叫做流
-
流一定是类,但类不一定是流
-
-
原始流和包裹流的关系
字节流 | 字符流 | |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
InputStream、OutputStream、Reader、Writer
都是抽象类,或者说都是抽象流,同茶喝那个我们使用的都是它的子类。
以Stream结尾的都是节点流
InputStream流中常用的方法:
-
public int read(byte[] b) throws IOException
-
public int read() throws IOException
-
读取一个字节并以整数形式返回
-
如果读取到输入流的末尾则返回-1
-
字符流不能处理非文本文档的文件 ,字节流可以 例如:图片,视频,MP3;
package bitter02; import java.io.*; public class TestInputStreamOutputStreamCopy { public static void main(String[] args) throws Exception{ FileInputStream fr = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\On HOME\\流\\src\\bitter02\\TestFileReaderWriterCopy.java"); FileOutputStream fw = new FileOutputStream("d:/hbx-1.hahah"); int ch; ch = fr.read(); while(-1 != ch){ fw.write(ch);//把ch字符写入 ch = fr.read(); } fw.flush();//建立一个缓冲区 避免频发读取、写入硬盘。 不刷新出设备是空的 fr.close(); fw.close(); } }
package bitter02; import java.io.*; import java.rmi.server.ExportException; public class TestFileReaderWriterCopy{ public static void main(String[] args) throws Exception { FileReader fr = new FileReader("C:\\Users\\Lenovo\\Desktop\\On HOME\\流\\src\\bitter02\\TestFileReaderWriterCopy.java"); FileWriter fw = new FileWriter("d:/hbx.hahah"); int ch; ch = fr.read(); while(-1 != ch){ fw.write(ch);//把ch字符写入 ch = fr.read(); } fw.flush();//建立一个缓冲区 避免频发读取、写入硬盘。不刷新出设备是空的 fr.close(); fw.close(); } }
package bitter02; import java.io.*; public class TestIO01 { public static void main(String[] args) throws Exception { FileInputStream fr = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\On HOME\\流\\src\\bitter01\\TestIO.java"); int ch; int cnt = 0; ch = fr.read(); while(-1 != ch){ ++cnt; System.out.printf("%c",(char)ch); ch = fr.read(); } System.out.println("该文件字符的个数是:"+cnt); fr.close(); } }
package bitter01; import java.io.*; public class TestIO { public static void main(String[] args) throws Exception { FileReader fr = new FileReader("C:\\Users\\Lenovo\\Desktop\\On HOME\\流\\src\\bitter01\\TestIO.java"); int ch; int cnt = 0; ch = fr.read(); while(-1 != ch){ ++cnt; System.out.printf("%c",(char)ch); ch = fr.read(); } System.out.println("该文件字符的个数是:"+cnt); fr.close(); } }
字节流和字符流的区别
FileInputStream
和 FileOutputStream
可以完成所有格式文件的赋值
FileReader
和 FileWriter
只可以完成文本文件的复制,却无法完成视频格式文件的复制
因为字节不需要解码和编码,将字节串化成字符才存在解码编码的问题
字节流可以从所有格式的设备中读写数据,但字符流只能从文本格式的设备中读写数据
总结:
1. 如果一个字节流把文本文档的内容输出到显示器上,当输出汉字时,就会出现乱码!
**
2. 通过字符流无法完成非文本文件的复制
或者说:
字符流只能处理文本文档
不能处理非文本文件
-
通过字节流可以完成音频格式文件的复制
实际上我们通过字节流可以完成任意格式的复制 没有缓冲区速度慢
缓冲流
-
缓冲流就是带有缓冲区的输入输出流
-
缓冲流可以显著的减少我们对IO访问的次数,保护我们的硬盘!
-
缓冲流本身就是处理流(处理流也叫包裹流),缓冲流必须得依附于节点流(节点流也叫原始流)
-
处理六是包裹在原始节点流上的流,相当于包括在管道上的管道!
缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了效率,同时增加了一些新的方法。
package bitter03; import java.io.*; public class TestInputStreamOutputStreamCopy_2 { public static void main(String[] args) throws Exception{ BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\Lenovo\\Desktop\\On HOME\\resources\\audio\\太傻.mp3")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/hbx.hahah")); byte[] buf = new byte[1024]; int len; len = bis.read(buf);//向buf中写 while(-1 != len){ bos.write(buf,0,len); len = bis.read(buf); } bos.flush(); bos.close(); bis.close(); //输入流和输出流产生联系:依靠buf连接起来 } }
输入流和输出流产生联系:依靠buf
连接起来
如果我们希望用BufferedInputStream
和 BufferedOutputStream
完成“将一个设备中的数据导入另一个设备中”,我们就应该定义一个临时的byte类型的数组,用这个临时数组作为输入流与输出流进行交互的中转枢纽!
BufferedReader
和 BufferedWriter
-
我们只有:
-
BufferedInputStream
-
BufferedOutputStream类
-
BufferedWriter
-
BufferedReader
-
前四个都是包裹流
带缓冲区的字节流处理文件的速度要快于不带缓冲区的字节流
数据流
DataInputStream
能够以一种与机器无关的方式,直接从底层字节输入流读取Java基本类型和String类型的数据。
DataInputStream
是包裹流,必须依附于InputStream
package bitter04_data; import java.io.*; public class TestData { public static void main(String[] args) throws Exception{ ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); long m = 1234567; dos.writeLong(m);//把m变量所代表的1000L在内存中的二级制代码 dos.flush(); byte[] buf2 = baos.toByteArray(); ByteArrayInputStream bais = new ByteArrayInputStream(buf2); long n; DataInputStream dis = new DataInputStream(bais); //dis.readLong(n); error n = dis.readLong(); System.out.println("n = "+n); } }
转换流
package bitter05; import java.io.*; public class TestString { public static void main(String[] args) { String str = null; try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { str = br.readLine(); System.out.println("str "+str); }catch (Exception e){ } } }
如果直接输入回车的话,则:
-
br.readLine()会丢弃回车符,而不是返回回车符,即br.readLine()会遇到回车符时终止读取,并且会把读取到的回车符自动丢掉
-
br.readLine()返回的是“”而不是null,“”表示的是空字符串,null表示空指针,空指针就是空地址,空地址就是不指向任何存储单元的意思。
print流
print流只输出,没有输入
分类:
-
PrintWriter
输出字符 -
PrintStream
输出字节
格式化输出是将一个数据用其字符串的形式输出。
标准输入输出的重定向
package bitter05; import java.io.*; public class TestSys { public static void main(String[] args) throws Exception{ PrintStream ps = new PrintStream("d:/heihei.asd"); System.setOut(ps); System.out.println("哈哈哈"); } }
e.printStackTrace();
默认把错误信息输出到System.err
所关联的设备中
对象的序列化
所谓序列化是指:把一个Object对象直接转化为字节流,然后把这个字节流直接写入本地硬盘中或网络中。
如果要想把某个对象序列化,则必须的实现Serializable
接口