IO流
缓冲字节流
package com.itheima.io.bytebuffer;
import java.io.*;
/**
目标:使用字节缓冲流完成数据的读写操作。
*/
public class ByteBufferDemo01 {
public static void main(String[] args) {
try (
InputStream fin = new FileInputStream("day10-io\\src\\a.txt");
//将原始字节输入流包装成缓冲字节输入流
InputStream bin = new BufferedInputStream(fin);
OutputStream fout = new FileOutputStream("day10-io\\src\\b.txt");
//将原始字节输出流包装成缓冲字节输出流
OutputStream bout = new BufferedOutputStream(fout)
){
byte[] bytes = new byte[1024];
int len;
while ((len = bin.read(bytes)) != -1) {
bout.write(bytes,0,len);
}
System.out.println("复制完成");
}catch (Exception e){
e.printStackTrace();
}
}
}
性能对比
package com.itheima.io.bytebuffer;
import java.io.*;
/**
目标:利用字节流的复制统计各种写法形式下缓冲流的性能执行情况。
复制流:
(1)使用低级的字节流按照一个一个字节的形式复制文件。
(2)使用低级的字节流按照一个一个字节数组的形式复制文件。
(3)使用高级的缓冲字节流按照一个一个字节的形式复制文件。
(4)使用高级的缓冲字节流按照一个一个字节数组的形式复制文件。
源文件:H:\JavaLearning\document\JavaSE课程\进阶\day08、日志框架、阶段项目\视频\06、首页、登录、客户操作页、商家操作页.avi
目标文件:H:/
小结:
使用高级的缓冲字节流按照一个一个字节数组的形式复制文件,性能好,建议开发使用!
*/
public class ByteBufferDemo02 {
private static final String FILE = "H:\\JavaLearning\\document\\JavaSE课程\\进阶\\day08、日志框架、阶段项目\\视频\\06、首页、登录、客户操作页、商家操作页.avi";
private static final String TARGET = "H:\\";
public static void main(String[] args) {
//原始字节流按数组复制时间:19.062s
copy01();
//字节缓冲流按数组复制时间:1.302s
copy02();
//copy03();救命,实在是太慢了
//字节缓冲流按字节复制时间:28.66s
copy04();
}
private static void copy01() {
long startTime = System.currentTimeMillis();
try (
InputStream fin = new FileInputStream(FILE);
OutputStream fout = new FileOutputStream(TARGET+"1.avi")
){
byte[] bytes = new byte[1024];
int len;
while ((len = fin.read(bytes)) != -1) {
fout.write(bytes,0,len);
}
System.out.println("复制完成");
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("原始字节流按数组复制时间:"+(endTime-startTime)/1000.0+"s");
}
private static void copy02() {
long startTime = System.currentTimeMillis();
try (
InputStream fin = new FileInputStream(FILE);
//将原始字节输入流包装成缓冲字节输入流
InputStream bin = new BufferedInputStream(fin);
OutputStream fout = new FileOutputStream(TARGET+"2.avi");
//将原始字节输出流包装成缓冲字节输出流
OutputStream bout = new BufferedOutputStream(fout)
){
byte[] bytes = new byte[1024];
int len;
while ((len = bin.read(bytes)) != -1) {
bout.write(bytes,0,len);
}
System.out.println("复制完成");
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("字节缓冲流按数组复制时间:"+(endTime-startTime)/1000.0+"s");
}
private static void copy03() {
long startTime = System.currentTimeMillis();
try (
InputStream fin = new FileInputStream(FILE);
OutputStream fout = new FileOutputStream(TARGET+"3.avi")
){
int len;
while ((len = fin.read()) != -1) {
fout.write(len);
}
System.out.println("复制完成");
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("原始字节流按字节复制时间:"+(endTime-startTime)/1000.0+"s");
}
private static void copy04() {
long startTime = System.currentTimeMillis();
try (
InputStream fin = new FileInputStream(FILE);
//将原始字节输入流包装成缓冲字节输入流
InputStream bin = new BufferedInputStream(fin);
OutputStream fout = new FileOutputStream(TARGET+"4.avi");
//将原始字节输出流包装成缓冲字节输出流
OutputStream bout = new BufferedOutputStream(fout)
){
int len;
while ((len = bin.read()) != -1) {
bout.write(len);
}
System.out.println("复制完成");
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("字节缓冲流按字节复制时间:"+(endTime-startTime)/1000.0+"s");
}
}
缓冲字符输入流
package com.itheima.io.charbuffer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
/**
目标:学会使用缓冲字符输入流提高字符输入流的性能,新增了按照行读取的方法(经典代码)
*/
public class BufferedReaderDemo {
public static void main(String[] args) {
try(
//创建一个文件字符输入流与源文件接通
Reader fr = new FileReader("day10-io/src/a.txt");
//将低级字符输入流包装成缓冲字符输入流
BufferedReader br = new BufferedReader(fr)
) {
/* //1k字符
char[] chars = new char[1024];
int len;
while ((len = br.read(chars)) != -1) {
String s = new String(chars,0,len);
System.out.println(s);
}*/
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
缓冲字符输出流
package com.itheima.io.charbuffer;
import java.io.*;
/**
目标:缓冲字符输出流的使用,学会它多出来的一个功能:newLine();
*/
public class BufferedWriteDemo {
public static void main(String[] args) {
try (
//创建一个文件字符输入流与源文件接通
Writer fw = new FileWriter("day10-io/src/b.txt",true);
//将低级字符输入流包装成缓冲字符输入流
BufferedWriter br = new BufferedWriter(fw)
) {
//写一个字符出去
br.write('a');
br.write(33);
br.write('程');
//换行
br.newLine();
//写一个字符串出去
br.write("昨日之深渊,今日之浅谈");
br.newLine();
//写一个字符数组出去
char[] arr = {'嗨','害','嗨'};
br.write(arr);
br.newLine();
//写字符串的一部分出去
br.write("爱滴魔力转圈圈",2,5);
br.newLine();
//写字符数组的一部分出去
br.write(arr,1,2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
案例
package com.itheima.io.charbuffer;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
/**
* 案例:
* 读取《出师表》并排序
* 输出到新文件中
*/
public class CharBufferCase {
public static void main(String[] args) {
try(
Reader fr = new FileReader("day10-io\\src\\csb.txt");
BufferedReader br = new BufferedReader(fr);
Writer fw = new FileWriter("day10-io/src/newcsb.txt");
BufferedWriter bw = new BufferedWriter(fw)
) {
ArrayList<String> list = new ArrayList<>();
String s;
while ((s = br.readLine()) != null) {
list.add(s);
}
ArrayList<String> t = new ArrayList<>();
Collections.addAll(t,"一","二","三","四","五","陆","柒","八","九","十","十一");
Collections.sort(list,(o1, o2) -> t.indexOf(o1.substring(0,o1.indexOf(".")))-t.indexOf(o2.substring(0,o2.indexOf("."))));
for (String s1 : list) {
bw.write(s1);
bw.newLine();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
字符输入转换流
package com.itheima.io.transferstream;
import java.io.*;
/**
目标:字符输入转换流InputStreamReader的使用。
字节流 字符流
字节输入流 字节输出流 字符输入流 字符输出流
InputStream OutputStream Reader Writer (抽象类)
FileInputStream FileOutputStream FileReader FileWriter(实现类)
BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter(实现类,缓冲流)
InputStreamReader OutputStreamWriter
字符输入转换流InputStreamReader:
-- 作用:可以解决字符流读取不同编码乱码的问题。
也可以把原始的字节流按照指定编码转换成字符输入流
-- 构造器:
public InputStreamReader(InputStream is):可以使用当前代码默认编码转换成字符流,几乎不用!
public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)
小结:
字符输入转换流InputStreamReader:作用:可以解决字符流读取不同编码乱码的问题。
public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)
*/
public class InputStreamReaderDemo {
public static void main(String[] args) {
try(
//该文件编码为:GBK,代码编码:UTF-8
InputStream fin = new FileInputStream("day10-io/src/newcsb.txt");
//将原始字节流转换成GBK编码的字符流
Reader isr = new InputStreamReader(fin,"GBK");
BufferedReader br = new BufferedReader(isr)
) {
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
字符输出转换流
package com.itheima.io.transferstream;
import java.io.*;
/**
目标:字符输出转换OutputStreamWriter流的使用。
字节流 字符流
字节输入流 字节输出流 字符输入流 字符输出流
InputStream OutputStream Reader Writer (抽象类)
FileInputStream FileOutputStream FileReader FileWriter(实现类)
BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter(实现类,缓冲流)
InputStreamReader OutputStreamWriter
字符输出转换流:OutputStreamWriter
-- 作用:可以指定编码把字节输出流转换成字符输出流。
可以指定写出去的字符的编码。
-- 构造器:
public OutputStreamWriter(OutputStream os) : 用当前默认编码UTF-8把字节输出流转换成字符输出流
public OutputStreamWriter(OutputStream os , String charset):指定编码把字节输出流转换成字符输出流
小结:
字符输出转换流OutputStreamWriter可以指定编码把字节输出流转换成字符输出流。
从而实现指定写出去的字符编码!
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) {
try(
OutputStream fos = new FileOutputStream("day10-io/src/a.txt",true);
//将字节输出流转换成以GBK编码的字符输出流
Writer osw = new OutputStreamWriter(fos,"GBK");
BufferedWriter bw = new BufferedWriter(osw)
) {
bw.write("莫西莫西");
bw.write("摩多摩多");
bw.newLine();
}catch (Exception e){
e.printStackTrace();
}
}
}
序列化
对象字节输出流
package com.itheima.io.serializable;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
* 对象序列化
* 使用对象字节输出流将对象存储到文件中去
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) {
//创建一个对象
Student s = new Student("时帆", 23, "222333");
try(
//创建一个对象字节输出通道连接目标文件
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("day10-io/src/b.txt"))
) {
//将对象写入文件中
oos.writeObject(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
对象字节输入流
package com.itheima.io.serializable;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* 对象反序列化
* 使用对象字节输入流将文件中的对象数据恢复成内存中的Java对象
*/
public class ObjectInputStreamDemo {
public static void main(String[] args) {
try(
//创建一个对象字节输入流通道对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day10-io/src/b.txt"))
) {
//读取对象
Student stu = (Student) ois.readObject();
System.out.println(stu);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Student类
package com.itheima.io.serializable;
import java.io.Serializable;
/**
对象如果要序列化,必须实现Serializable序列化接口。
*/
public class Student implements Serializable {
// 申明序列化的版本号码
// 序列化的版本号与反序列化的版本号必须一致才不会出错!
private static final long serialVersionUID = 1;
private String name;
private int age;
// transient修饰的成员变量不参与序列化了
private transient String password;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", password='" + password + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Student(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
public Student() {
}
}
属性集properties
package com.itheima.io.property;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/**
目标:Properties的概述和使用(框架底层使用,了解这个技术即可)(保存数据到属性文件)
Properties: 属性集对象。
其实就是一个Map集合。也就是一个键值对集合,但是我们一般不会当集合使用,
因为有HashMap。
Properties核心作用:
Properties代表的是一个属性文件,可以把键值对的数据存入到一个属性文件中去。
属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value。
大家在后期学的很多大型框架技术中,属性文件都是很重要的系统配置文件。
users.properties
admin=123456
dlei=dlei
需求:使用Properties对象生成一个属性文件,里面存入用户名和密码信息。
Properties的方法:
-- public Object setProperty(String key, String value) : 保存一对属性。 (put)
-- public String getProperty(String key) : 使用此属性列表中指定的键搜索属性值 (get)
-- public Set<String> stringPropertyNames() : 所有键的名称的集合 (keySet())
-- public void store(OutputStream out, String comments): 保存数据到属性文件中去
-- public void store(Writer fw, String comments): 保存数据到属性文件中去
小结:
Properties可以保存键值对数据到属性文件
*/
public class PropertiesDemo01 {
public static void main(String[] args) throws IOException {
//创建一个属性集对象
Properties properties = new Properties();
//添加数据
properties.setProperty("admin","123456");
properties.setProperty("shifan","305780");
properties.setProperty("user111","111111");
System.out.println(properties.getProperty("admin"));
System.out.println(properties);
//将数据存储到属性文件中去,属性文件后缀名为.properties
properties.store(new FileWriter("day10-io/src/c.properties"),"userers' information");
}
}
package com.itheima.io.property;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/**
目标:Properties读取属性文件中的键值对信息。(读取)
Properties的方法:
-- public Object setProperty(String key, String value) : 保存一对属性。
-- public String getProperty(String key) :使用此属性列表中指定的键搜索属性值
-- public Set<String> stringPropertyNames() :所有键的名称的集合
-- public void store(OutputStream out, String comments):保存数据到属性文件中去
-- public synchronized void load(InputStream inStream):加载属性文件的数据到属性集对象中去
-- public synchronized void load(Reader fr):加载属性文件的数据到属性集对象中去
小结:
属性集对象可以加载读取属性文件中的数据!!
*/
public class PropertiesDemo02 {
public static void main(String[] args) throws IOException {
//创建一个属性集对象
Properties properties = new Properties();
//读取属性文件恢复到属性集对象中
properties.load(new FileReader("day10-io/src/c.properties"));
System.out.println(properties);
}
}
打印流
package com.itheima.io.printstream;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
目标:学会使用打印流 高效 方便写数据到文件。
PrintWriter和PrintStream在打印功能上是一样的,区别在于PrintStream只能写字节不能写字符
PrintWriter只能写字符不能写字节,write()
*/
public class PrintDemo01 {
public static void main(String[] args) {
try(
//创建一个打印流对象
// PrintStream ps = new PrintStream(new FileOutputStream("day10-io/src/a.txt"));
// PrintStream ps = new PrintStream(new FileOutputStream("day10-io/src/a.txt",true));
PrintStream ps = new PrintStream("day10-io/src/a.txt")
// PrintWriter ps = new PrintWriter("day10-io/src/a.txt")
// PrintStream ps = new PrintStream("day-io/src/a.txt", "GBK");
) {
ps.println(97);
ps.println('a');
ps.println(23.3);
ps.println(true);
ps.println("我是打印流输出的,我是啥就打印啥");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.itheima.io.printstream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
/**
目标:了解改变输出语句的位置到文件
*/
public class PrintDemo02 {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("床前明月光");
System.out.println("疑是地上霜");
//改变输出语句的位置(重定向)
PrintStream ps = new PrintStream("day10-io/src/b.txt");
//将系统的打印流更换成自定义的打印流
System.setOut(ps);
System.out.println("举头望明月");
System.out.println("低头思故乡");
}
}
Commons_io框架
package com.itheima.io.commons_io;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
/**
目标:Commons-io包的使用介绍。
什么是Commons-io包?
commons-io是apache开源基金组织提供的一组有关IO操作的类库,
可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类,
见下表:
| 包 | 功能描述 |
| ----------------------------------- | :------------------------------------------- |
| org.apache.commons.io | 有关Streams、Readers、Writers、Files的工具类 |
| org.apache.commons.io.input | 输入流相关的实现类,包含Reader和InputStream |
| org.apache.commons.io.output | 输出流相关的实现类,包含Writer和OutputStream |
| org.apache.commons.io.serialization | 序列化相关的类
步骤:
1. 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/
2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中
3. 将commons-io-2.6.jar加入到classpath中
小结:
IOUtils和FileUtils可以方便的复制文件和文件夹!!
*/
public class CommonsIODemo {
public static void main(String[] args) throws Exception {
// // 1.完成文件复制!
// IOUtils.copy(new FileInputStream("D:\\resources\\hushui.jpeg"),
// new FileOutputStream("D:\\resources\\hushui2.jpeg"));
// // 2.完成文件复制到某个文件夹下!
// FileUtils.copyFileToDirectory(new File("D:\\resources\\hushui.jpeg"), new File("D:/"));
// 3.完成文件夹复制到某个文件夹下!
// FileUtils.copyDirectoryToDirectory(new File("D:\\resources") , new File("D:\\new"));
// FileUtils.deleteDirectory(new File("D:\\new"));
// JDK1.7 自己也做了一些一行代码完成复制的操作:New IO的技术
// Files.copy(Path.of("D:\\resources\\hushui.jpeg"), Path.of("D:\\resources\\hushui3.jpeg"));
// Files.delete(Path.of("d:/a"));还是无法删除非空文件夹
FileUtils.deleteDirectory(new File("D:\\a"));
}
}