缓冲自带缓冲区、可以提高字节流、字符流读写数据的性能
字节缓冲流:
- 字节缓冲输入流:BufferedInputStream
- 字节缓冲输出流:BufferedOutputStream
字符缓冲流
- 字符缓冲输入流:BufferedReader
- 字符缓冲输出流:BufferedWriter
字节缓冲输入流
- BufferedInputStream,提高字节输入流读取数据的性能,读写功能上并无变化。
- 自带了8KB缓冲池,直接从缓冲池中读取数据,所以性能较好
字节缓冲输出流
- BufferedOutputStream,提高字节输出流读取数据的性能,读写功能上并无变化
- 自带了8KB缓冲池,数据直接写入到缓冲池中,写数据性能极高
构造器 | 说明 |
public BufferedInputStream(InputStream is) | 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能 |
public BufferedOutputStream(OutputStream os) | 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提写数据的性能 |
// 1 创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("a.txt");
// 把字节输入流包装为缓冲字节输入流
InputStream bis = new BufferedInputStream(is)
// 2 创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("a1.txt");
// 把字节输出流包装成缓冲字节输出流
OutputStream bos = new BufferedOutputStream(os);
try(){
// 3 定义一个字节数组转移数据
byte[] buffer = new byte[1024]
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(buffer, 0, len);
}
}catch(Exception e){
e.printStackTrace();
}
/**
目标:利用字节流的复制统计各种写法形式下缓冲流的性能执行情况。
复制流:
(1)使用低级的字节流按照一个一个字节的形式复制文件。
(2)使用低级的字节流按照一个一个字节数组的形式复制文件。
(3)使用高级的缓冲字节流按照一个一个字节的形式复制文件。
(4)使用高级的缓冲字节流按照一个一个字节数组的形式复制文件。
源文件:D:\原视频.avi
目标文件:D:\
*/
public class ByteBufferTimeDemo {
private static final String SRC_FILE = "D:\\原视频.avi";
private static final String DEST_FILE = "D:\\";
public static void main(String[] args) {
// copy01(); // 1、低级字节流一个一个字节的复制 (慢的让人无法忍受,直接淘汰)
copy02(); // 2、低级字节流一个一个字节数组复制 (较慢,不推荐使用)
// copy03(); // 3、高级流一个一个字节的复制(很慢,直接淘汰)
copy04(); // 4、高级流一个一个字节数组的复制(飞快,推荐使用)
}
private static void copy04() {
long start = System.currentTimeMillis();
try (
// 1、创建一个字节输入流管道与原视频接通
InputStream is = new FileInputStream(SRC_FILE);
// 2、创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE + "4.avi");
// a、把低级的字节输入流包装成高级的缓冲字节输入流:自带8KB的缓冲池
InputStream bis = new BufferedInputStream(is);
// b、把低级的字节输出流包装成高级的缓冲字节输出流
OutputStream bos = new BufferedOutputStream(os);
){
// 3、使用数组拷贝
int len;
byte[] buffer = new byte[1024];
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer,0 , len);
}
}catch (Exception e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节数组复制耗时:" + (end - start) / 1000.0 + "s");
}
private static void copy03() {
long start = System.currentTimeMillis();
try (
// 1、创建一个字节输入流管道与原视频接通
InputStream is = new FileInputStream(SRC_FILE);
// 2、创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE + "3.avi");
// a、把低级的字节输入流包装成高级的缓冲字节输入流:自带8KB的缓冲池
InputStream bis = new BufferedInputStream(is);
// b、把低级的字节输出流包装成高级的缓冲字节输出流
OutputStream bos = new BufferedOutputStream(os);
){
// 3、定义一个变量记录每次读取的一个字节
int ch;
while ((ch = bis.read()) != -1) {
bos.write(ch);
}
}catch (Exception e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节复制耗时:" + (end - start) / 1000.0 + "s");
}
private static void copy02() {
long start = System.currentTimeMillis();
try (
// 1、创建一个字节输入流管道与原视频接通
InputStream is = new FileInputStream(SRC_FILE);
// 2、创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE + "2.avi");
){
// 3、使用数组拷贝
int len;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
os.write(buffer,0 , len);
}
}catch (Exception e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("低级流一个一个字节数组复制耗时:" + (end - start) / 1000.0 + "s");
}
private static void copy01() {
long start = System.currentTimeMillis();
try (
// 1、创建一个字节输入流管道与原视频接通
InputStream is = new FileInputStream(SRC_FILE);
// 2、创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream(DEST_FILE + "1.avi");
){
// 3、定义一个变量记录每次读取的一个字节
int ch;
while ((ch = is.read()) != -1) {
os.write(ch);
}
}catch (Exception e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("低级流一个一个字节复制耗时:" + (end - start) / 1000.0 + "s");
}
}
字符缓冲输入流
- BufferedReader,提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能
- 字符缓冲流自带8K缓冲区,提高了原始字符流读数据的性能
字符缓冲输出流
- BufferedWriter提高字符输出流写数据的性能,多了换行功能
- 字符缓冲流自带8K缓冲区
构造器 | 说明 |
public BufferedReader(Reader r) | 可以把低级的字符输入流包装成一个高级的缓冲字符的输入流管道,从而提高字符输入流读数据的性能 |
public BufferedWriter(Writer w) | 可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能 |
新增功能
方法 | 说明 |
public String readLine() | 读取一行数据返回,如果读取没有完毕,但是并没有行可读返回null |
public void newLine() | 字符输出流,换行操作 |
InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流
构造器 | 说明 |
public InputStreamReader(InputStream is) | 可以把原始的字节流按照代码默认编码转换成字符输入流,几乎不用,与默认得FileReader一样 |
public InputStreamReader(InputStream is, String charset) | 可以把原始得字节流按照指定编码转换成字符输入流,这样字符流中得字符就不乱码了 |
// 提交文件的原始字节流(GBK)
InputStream is = new FileInputStream("a.txt");
// 把字节输入流转换成字符输入流
Reader isr = new InputStreamReader(is, "GBK");
// 把字符输入流包装成缓冲字符输入流
BufferReader br = new BufferReader(isr);
// 编码一致情况
Reader fr = new FileReader("a.txt");
BufferedReader br = new BufferedReader(fr);
把字节输出流按照指定编码转换成字符输出流
构造器 | 说明 |
public OutputStreamWriter(OutputStream os) | 可以把原始的字节输出流按照代码默认编码转换成字符输出流UTF-8 |
public OutputStreamWriter(OutputStream os, String charset) | 把原始字节输出流按照指定编码转换成字符输出流 |
// 1、指定写出去的字符是:GBK。
OutputStream os = new FileOutputStream("a.txt");
// 2、自己指定字节写出去
//os.write("我爱你".getBytes("GBK"));
// os.close();
// 3、新方案:把字节输出流指定编码转换成字符输出转换流
Writer osw = new OutputStreamWriter(os, "GBK");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("abc我爱你中国!");
bw.close();
把对象数据存入到文件中(对象必须实现序列化接口)
构造器 | 说明 |
public ObjectOutputStream(OutputStream out) | 把低级字节输出流包装成高级的对象字节输出流 |
方法 | 说明 |
public final void writeObject(Object obj) | 把对象写出去到对象序列流的文件中 |
public static void main(String[] args) throws Exception {
// 1、创建一个对象
Student s = new Student("赵四", 21);
// 2、对象序列化:使用ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
// 3、直接开始序列化
oos.writeObject(s);
// 4、资源释放
oos.close();
System.out.println("对象序列化完成~~");
}
public class Student implements Serializable{
...
}
以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象
构造器 | 说明 |
public ObjectInputStream(InputStream out) | 把低级字节输入流包装成高级的对象字节输入流 |
方法 | 说明 |
public Object readObject() | 把存储到磁盘文件中的对象数据恢复成内存中的对象返回 |
public static void main(String[] args) throws Exception {
// 1、创建一个对象字节输入流管道与源文件接通
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
// 2、对象反序列化
Student s = (Student) ois.readObject();
System.out.println(s);
ois.close();
补充
transient 修饰成员变量不参与序列化
private transient String passWord;
打印流可以实现方便、高效的打印数据到文件中
PrintStream
构造器 | 说明 |
public PrintStream(OutputStream os) |
打印流直接通向字节输出流管道 |
public PrintStream(File f) |
打印流直接通向文件对象 |
public PrintStream(String filepath) |
打印流直接通向文件路径 |
方法 | 说明 |
public void print(Xxx xx) |
打印任意类型的数据出去 |
PrintWriter
构造器 | 说明 |
public PrintWriter(OutputStream os) |
打印流直接通向字节输出流管道 |
public PrintWriter (Writer w) |
打印流直接通向字符输出流管道 |
public PrintWriter (File f) |
打印流直接通向文件对象 |
public PrintWriter (String filepath) |
打印流直接通向文件路径 |
方法 | 说明 |
public void print(Xxx xx) |
打印任意类型的数据出去 |
PrintStream和PrintWriter的区别
- 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)
- PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。
- PrintWriter继承自字符输出流Writer,支持写字符数据出去。
输出语句重定向:打印流的一种应用,把输出语句的输入到文件中
PrintStream ps = new PrintStream("文件地址")
System.setOut(ps);
其实是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用。
作用:
- Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
- 属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。
构造器 | 说明 |
void load(InputStream inStream) |
从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) |
从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) |
将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) |
将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
public Object setProperty(String key, String value) |
保存键值对(put) |
public String getProperty(String key) |
使用此属性列表中指定的键搜索属性值 (get) |
public Set |
所有键的名称的集合 (keySet()) |
// 需求:使用Properties把键值对信息存入到属性文件中去。
Properties properties = new Properties();
properties.setProperty("admin", "123456");
// 存入到文件中去
/**
参数一:保存的管道
参数二:保存信息的描述
**/
properties.store(new FileWriter("a.properties"), "lucky");
// 需求:从属性文件中读取键值对信息
Properties properties = new Properties();
// 加载属性文件中的键值对信息到properties中去
properties.load(new FileReader("a.properties"));
Set keys = properties.stringPropertyNames();
// 1、读取属性文件的信息到Properties集合中去
Properties properties = new Properties();
properties.load(new FileReader("io-app2/src/people.txt"));
// 2、将admin密码改为123
if(properties.containsKey("admin")) {
properties.setProperty("admin", "123");
}
// 3、存储到文件中
properties.store(new FileWriter("a.txt"), "hhhhh!");
commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils
String readFileToString(File file, String encoding) |
读取文件中的数据, 返回字符串 |
void copyFile(File srcFile, File destFile) |
复制文件。 |
void copyDirectoryToDirectory(File srcDir, File destDir) |
复制文件夹。 |
// 1.完成文件复制!
IOUtils.copy(new FileInputStream("a.jpeg"),new FileOutputStream("b.jpeg"));
// 2.完成文件复制到某个文件夹下!
FileUtils.copyFileToDirectory(new File("a.jpeg"), new File("D:/"));
// 3.完成文件夹复制到某个文件夹下!
FileUtils.copyDirectoryToDirectory(new File("D:\\a") , new File("D:\\b"));
// 删除文件夹
FileUtils.deleteDirectory(new File("D:\\b"));
// JDK1.7 自己也做了一些一行代码完成复制的操作:New IO的技术
Files.copy(Path.of("a.jpeg"), Path.of("b.jpeg"));