JAVA I/O框架
1. 什么是流?
链接
动画连接
概念: 内存与存储设备之间传输数据的通道
数据借助流传输
2. 流的分类:
按方向:
输入流:将存储设备的内容读到内存中
输出流:将内存中内容写入到存储设备中
按单位:
字节流:以字节为单位,可以读写所有数据
字符流:以字符为单位,只能读写文本数据
按功能:
节点流:具有实际传输数据的读写功能。
过滤流:在节点流的基础之上增强功能。
3 字节流
3.1 FileInputSteam的使用(文件字节流的使用)
InputStream的子类
FileInputStream:
public int read(byte[]b)
//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
FileOutputStream:
public void write(byte[]b)
//一次写多个字节,将b数组中所有字节,写入输出流。
package javaOfIO;
import java.io.FileInputStream;
/**
* 演示FileInputStream的使用
* 文件字节输入流
*/
public class MyFileInputStream {
public static void main(String[] args) throws Exception{
// 1. 创建FileInputStream, 并指定文件路径
FileInputStream fileInputStream = new FileInputStream("d:\\aaa.txt");
// 2. 读取文件
// 2.1 单个字符读取
// int read = fileInputStream.read();
// int data = 0;
// while((data = fileInputStream.read()) != -1){
// System.out.println((char)data);
// }
// 2.2 一次读取多个字节
// System.out.println("======一次读取多个字节======");
// byte[] buf = new byte[3];
// int count = fileInputStream.read(buf);
// System.out.println(count);
// System.out.println(new String(buf));
//
// int count2 = fileInputStream.read(buf);
// System.out.println(count2);
// System.out.println(new String(buf));
//
// int count3 = fileInputStream.read(buf);
// System.out.println(count3);
// System.out.println(new String(buf,0,count3));
// 使用循环解决
byte[] bytes = new byte[3];
int count = 0;
while((count = fileInputStream.read(bytes)) != -1){
System.out.println(new String(bytes,0,count));
}
// 3. 关闭
fileInputStream.close();
System.out.println("执行完毕!!");
}
}
3.2 FileOutputStream的使用
package javaOfIO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
/**
* 演示文件字节输出流
* FileOutputStream
*/
public class MyFileOutputStream {
public static void main(String[] args) throws Exception {
// 1. 创建文件字节输出流对象
FileOutputStream fileOutputStream = new FileOutputStream("d:\\aaa.txt",true);// append为true表示 追加数据字符,不清空原有字符
// 2. 写入文件
// fileOutputStream.write(97);
// fileOutputStream.write('b');
// fileOutputStream.write('c');
String string = "helloworld\n";
fileOutputStream.write(string.getBytes(StandardCharsets.UTF_8));
// 3. 关闭
fileOutputStream.close();
System.out.println("执行完毕!!");
}
}
3.3 字节流复制文件
package javaOfIO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 使用文件字节流实现文件的复制
*/
public class MyCopyFileWithStream {
public static void main(String[] args) throws Exception{
// 1. 创建流
// 1.1 文件字节输入流
FileInputStream fileInputStream = new FileInputStream("d:\\粉色背景.jpg");
// 1.2 文件字节输出流
FileOutputStream fileOutputStream = new FileOutputStream("d:\\003.jpg");
// 2. 实现复制 一边读,一边写
byte[] buf = new byte[1024];
int count = 0 ; // 保存实际读取的字节个数
while ((count = fileInputStream.read(buf)) != -1 ){
fileOutputStream.write(buf,0,count);
}
// 3. 关比
fileInputStream.close();
fileOutputStream.close();
System.out.println("执行玩匕");
}
}
3.4 字符缓冲流
3.5 BufferedInputStream的使用
·缓冲流:BufferedInputStream/BufferedOutputStream
·提高I0效率,减少访问磁盘的次数;
·数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
package javaOfIO;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
/***
* 使用字节缓冲流读取文件
*
*/
public class Demo04_BufferedInputStream {
public static void main(String[] args) throws Exception{
// 1. 创建BufferedInputStream
FileInputStream fileInputStream = new FileInputStream("d:\\aaa.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
// 2. 读取
// int data = 0 ;
// while ((data = bufferedInputStream.read()) != -1){
// System.out.print((char) data);
// }
// 自己创建缓冲区
byte[] buf = new byte[1024];
int count= 0;
while((count = fileInputStream.read(buf))!= -1 ){
System.out.println(new String(buf,0, count));
}
// 3. 关闭
bufferedInputStream.close();
}
}
3.6 BufferedOutputStream的使用
实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
缓冲区满了就flush
package javaOfIO;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
/**
* 使用字符缓冲流输出文件
* BufferedOutputStream
*/
public class Demo05_BufferedOutputStream {
public static void main(String[] args) throws Exception{
// 1. 创建字节输出缓冲流
FileOutputStream fileOutputStream = new FileOutputStream("d:\\bbb.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
// 2. 写入文件
for (int i = 0; i < 10; i++) {
bufferedOutputStream.write("helloworld\r\n".getBytes(StandardCharsets.UTF_8)); // 先写入8k缓冲区
bufferedOutputStream.flush(); // 刷新到硬盘
}
// 3. 关闭(内部调用Flush方法)
bufferedOutputStream.close();
}
}
4. 对象流
4.1 序列化
java对象转其他对象(比如文件对象),就叫序列化,反过来就是反序列化。
package javaOfIO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
* 使用ObjectOutputStream 实现对象的序列化
* 要求序列化的类 必须要实现implements Serializable 接口
*/
public class Demo06_ObjectOutputStream {
public static void main(String[] args) throws Exception{
// 1. 创建对象
FileOutputStream fileOutputStream = new FileOutputStream("d:\\ccc.bin"); // bin表示二进制文件
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 2. 序列化(写入操作)
Student zhangsan= new Student("张三",20);
objectOutputStream.writeObject(zhangsan);
// 3. 关闭
objectOutputStream.close();
System.out.println("序列化完毕");
}
}
package javaOfIO;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 3836721713802339996L; // 实现可以序列化的接口
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
4.2 反序列化
package javaOfIO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* 使用ObjectOutputStream实现反序列化(读取重构对象)
*/
public class Demo07_ObjectInputStream {
public static void main(String[] args) throws Exception{
// 1. 创建对象流
FileInputStream fileInputStream = new FileInputStream("d:\\ccc.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 2. 读取文件(反序列化)
Object s = (Student)objectInputStream.readObject();
// 3. 关闭
objectInputStream.close();
System.out.println("玩匕");
System.out.println(s.toString());
}
}
4.3 序列化和反序列化注意事项
- 序列化类必须要实现Serializable接口
- 序列化类中对象属性要求实现Serializable接口
- 序列化版本号ID,serialVersionUID,保证序列化的类和反序列化的类是同一个类
- 使用transient(瞬间的)修饰属性,该属性就不能序列化。
- 静态属性不能序列化
- 序列化多个对象,可以借助集合来实现
package javaOfIO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
* 使用ObjectOutputStream 实现对象的序列化
* 要求序列化的类 必须要实现implements Serializable 接口
*/
public class Demo06_ObjectOutputStream {
public static void main(String[] args) throws Exception{
// 1. 创建对象
FileOutputStream fileOutputStream = new FileOutputStream("d:\\ccc.bin"); // bin表示二进制文件
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 2. 序列化(写入操作)
Student zhangsan= new Student("张三",20);
Student lisi= new Student("李四",20);
ArrayList<Student> list = new ArrayList<>();
list.add(zhangsan);
list.add(lisi);
objectOutputStream.writeObject(list);
// 3. 关闭
objectOutputStream.close();
System.out.println("序列化完毕");
}
}
package javaOfIO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
/**
* 使用ObjectOutputStream实现反序列化(读取重构对象)
*/
public class Demo07_ObjectInputStream {
public static void main(String[] args) throws Exception{
// 1. 创建对象流
FileInputStream fileInputStream = new FileInputStream("d:\\ccc.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 2. 读取文件(反序列化)
// Object s = (Student)objectInputStream.readObject();
// Object s2 = (Student)objectInputStream.readObject();
ArrayList<Student> list = (ArrayList<Student>) objectInputStream.readObject();
// 3. 关闭
objectInputStream.close();
System.out.println("玩匕");
// System.out.println(s.toString());
System.out.println(list.toString());
}
}
5 字符流
5.1 常见字符编码
当编码方式和解码方式不一致时,会出现乱码。
5.2 字符流抽象类
5.3 FileReader的使用
· FileReader:
·public int readKchar[]c)
从流中读取多个字符,将读到内容存入
c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。
· FileWriter:
·public void write(String str)
一次写多个字符,将b数组中所有字符,写入输出
流。
package javaOfIO;
import java.io.FileReader;
/**
* 使用FileReader读取文件
*/
public class Demo202_FieReader {
public static void main(String[] args) throws Exception{
// 1. 创建FileReader 文件字符输入流
FileReader fileReader = new FileReader("d:\\hello.txt");
// 2. 读取
// 2.1 单个读取
// int data = 0;
// while ((data = fileReader.read()) != -1){
// System.out.print((char)data);
// }
// 2.2 字符缓冲区
int count = 0;
char[] chars = new char[1024];
while ((count = fileReader.read(chars)) != -1){
System.out.print(new String(chars,0,count));
}
// 3. 关闭
fileReader.close();
}
}
5.4 FileWriter的使用
package javaOfIO;
import java.io.FileWriter;
public class Demo203_FileWriter {
public static void main(String[] args) throws Exception{
// 1. 创建FileWriter对象
FileWriter fileWriter = new FileWriter("d:\\write.txt");
// 2. 写入
for (int i = 0; i < 10; i++) {
fileWriter.write("java是世界上最好的语言!\n");
fileWriter.flush();
}
// 3. 关闭
fileWriter.close();
System.out.println("wanbi ");
}
}
5.5 字符流复制文件
只能复制文本文件,不能复制图片或二进制文件
使用字节流复制任意文件
package javaOfIO;
import java.io.FileReader;
import java.io.FileWriter;
public class Demo204 {
public static void main(String[] args) throws Exception{
// 1. increte
FileReader fileReader = new FileReader("d:\\write.txt");
FileWriter fileWriter = new FileWriter("d:\\write2.txt");
// 2. read and writer
int data = 0;
while ((data = fileReader.read())!=-1){
fileWriter.write(data);
fileWriter.flush();
}
// 3. close
fileReader.close();
fileWriter.close();
}
}
5.6 BufferedReader的使用
·缓冲流:BufferedReader/BufferedWriter
·高效读写
·支持输入换行符。
·可一次写一行、读一行。
package javaOfIO;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* 使用字符缓冲流读取文件
* bufferedReader
*/
public class Demo205_BufferedReader {
public static void main(String[] args) throws Exception{
// 创建缓冲流
FileReader fileReader = new FileReader("d:\\write.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
// reader
//2.1
// char[] chars = new char[1024];
// int count = 0;
// while((count = bufferedReader.read(chars)) != -1){
// System.out.println(new String(chars,0,count));
// }
//2.2 一行一行度
String line = null;
while ((line = bufferedReader.readLine())!=null){
System.out.println(line);
}
// 3. 关闭
bufferedReader.close();
}
}
5.7 BufferedWriter的使用
package javaOfIO;
import java.io.BufferedWriter;
import java.io.FileWriter;
public class Demo205_BufferedWriter {
public static void main(String[] args) throws Exception{
// 1. 创建bufferedWriter对象
FileWriter fileWriter = new FileWriter("D:\\buffer.txt");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 2. 写入
for (int i = 0; i < 10; i++) {
bufferedWriter.write("好好学习,天天向上\n");
bufferedWriter.newLine(); // 换行
bufferedWriter.flush();
}
bufferedWriter.close();
System.out.println("wanbu");
}
}
6. 打印流
6.1 PrintWriter
·PrintWriter:
·封装了print()/println()方法,支持写入后换行。
·支持数据原样打印
package javaOfIO;
import java.io.PrintWriter;
/**
* 演示printwriter的使用
*/
public class Demo206207 {
public static void main(String[] args) throws Exception{
// 1. 创建打印流
PrintWriter printWriter = new PrintWriter("d:\\print.txt");
// 2. print
printWriter.println(97);
printWriter.println(true);
printWriter.println(3.14);
printWriter.println("a");
// 3. close
printWriter.close();
}
}
7. 转换流
·桥转换流:InputStreamReader/OutputStreamWriter
·可将字节流转换为字符流。
·可设置字符的编码方式。
7.1 InputStreamReader的使用
package javaOfIO;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.spec.RSAOtherPrimeInfo;
/**
* Demo301_InputStreamReader 读取文件, 指定使用的编码
*
*/
public class Demo301_InputStreamReader {
public static void main(String[] args) throws Exception{
// 1. 创建 InputStreamReader 对象
FileInputStream fileInputStream = new FileInputStream("d:\\write.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf-8");
// read file
int data = 0;
while((data = inputStreamReader.read()) != -1){
System.out.print((char) data);
}
// 3. 关闭
inputStreamReader.close();
}
}
package javaOfIO;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class Demo302_OutputStreamReader {
public static void main(String[] args) throws Exception{
FileOutputStream fileOutputStream = new FileOutputStream("d:\\info.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "gbk");
// 2
for (int i = 0; i < 10; i++) {
outputStreamWriter.write("我爱北京\t\n");
outputStreamWriter.flush();
}
// 3
outputStreamWriter.close();
System.out.println("good");
}
}
8. file类
8.1 File类文件操作
package javaOfIO;
import java.io.File;
import java.util.Date;
/**
* 1. 分隔符
* 2. 文件操作
* 3. 文件夹操作
*/
public class DomeFile01 {
public static void main(String[] args) throws Exception{
// separator();
fileOpe();
}
// 1. 分隔符
public static void separator(){
System.out.println("路径分隔符:" + File.pathSeparator);
System.out.println("名称分隔符:" + File.separatorChar);
}
// 路径分隔符:;
// 名称分隔符:\
// 2. 文件操作
public static void fileOpe() throws Exception {
// 1. 创建文件
File file = new File("d:\\file.txt");
// File file = new File("file.txt"); // 默认在项目上进行创建
//System.out.println(file.toString());
if(!file.exists()){
boolean newFile = file.createNewFile();// 返回值为bool类型
System.out.println("创建结果:" + newFile);
}
// 2. 删除文件
// 2.1 直接删除
// System.out.println("delete end:"+file.delete());
// 2.2 使用jvm退出时 删除
// file.deleteOnExit();
// Thread.sleep(5000);
// 3. 获取文件信息
System.out.println("获取文件的绝对路径:"+ file.getAbsolutePath());
System.out.println("获取文件的路径:"+ file.getPath());
System.out.println("获取文件的名称:"+ file.getName());
System.out.println("获取文件的父目录:"+ file.getParent());
System.out.println("获取文件的长度:"+ file.length());
System.out.println("获取文件的创建时间:"+ new Date(file.lastModified()).toLocaleString());
// 4 判断
System.out.println("是否可写:" + file.canWrite());
System.out.println("是否是文件:" + file.isFile());
System.out.println("是否隐藏:" + file.isHidden());
}
}
8.2 File类文件夹操作
package javaOfIO;
/**
* 1. 分隔符
* 2. 文件操作
* 3. 文件夹操作
*/
import java.io.File;
import java.util.Date;
public class DomeFile02 {
public static void main(String[] args) throws Exception{
// separator();
directorOpe();
}
// 1. 分隔符
public static void separator(){
System.out.println("路径分隔符:" + File.pathSeparator);
System.out.println("名称分隔符:" + File.separatorChar);
}
// 路径分隔符:;
// 名称分隔符:\
// 2. 文件夹操作
public static void directorOpe() throws Exception {
// 1. 创建文件夹
File dir = new File("d:\\aaa\\bbb\\ccc");
System.out.println(dir.toString());
if(!dir.exists()){
// boolean newdir= dir.mkdir();// 只能创建单级目录
boolean newdir = dir.mkdirs();// 能创建多级目录
System.out.println("创建结果:" + newdir );
}
// 2. 删除文件夹
// 2.1 直接删除(空目录)
// System.out.println("delete end:"+dir.delete()); // 只能删掉单目录,空目录
// 2.2 使用jvm退出时 删除
dir.deleteOnExit();
Thread.sleep(5000);
// 3. 获取文件夹信息
System.out.println("获取文件夹的绝对路径:"+ dir.getAbsolutePath());
System.out.println("获取文件夹的路径:"+ dir.getPath());
System.out.println("获取文件夹的名称:"+ dir.getName());
System.out.println("获取文件夹的父目录:"+ dir.getParent());
System.out.println("获取文件夹的创建时间:"+ new Date(dir.lastModified()).toLocaleString());
// 4 判断
System.out.println("是否是文件Jia:" + dir.isDirectory());
System.out.println("是否隐藏:" + dir.isHidden());
// 5. 遍历文件夹信息
File dir2 = new File("d:\\证件照");
String[] files = dir2.list();
for (String file : files) {
System.out.println(file);
}
}
}
9. 文件过滤器FileFilter接口
public interface FileFilter
boolean accept(File pathname)
·当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。
System.out.println("--------FileFilter接口使用----------");
File[] files2 = dir2.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.getName().endsWith(".jpg")){
return true;
}
return false;
}
});
for (File file : files2) {
System.out.println(file.getName());
}
10.递归遍历和递归删除
package javaOfIO;
import java.io.File;
/**
* 递归遍历文件夹
* 案例2:递归删除文件夹
*/
public class ListDemo {
public static void main(String[] args) {
listDir(new File("d:\\新建文件夹"));
deleteDir(new File("d:\\新建文件夹"));
}
// 案例1:递归遍历文件夹
public static void listDir(File dir){
File[] files = dir.listFiles();
System.out.println(dir.getAbsolutePath());
if(files!=null && files.length>0){
for (File file : files) {
if(file.isDirectory()){
listDir(file); // 递归
}else{
System.out.println(file.getAbsolutePath());
}
}
}
}
// 案例2:递归删除文件夹
public static void deleteDir(File dir){
File[] files = dir.listFiles();
if(files!=null && files.length>0){
for (File file : files) {
if(file.isDirectory()){
deleteDir(file);
}else{
System.out.println(file.getAbsolutePath() + " 删除:" + file.delete());
}
}
}
System.out.println(dir.getAbsolutePath() + " 删除:" + dir.delete());
}
}
11.Properties
·Properties:属性集合,继承hashtable,线程安全的集合
・特点
·1存储属性名和属性值
·2属性名和属性值都是字符串类型
·3没有泛型
·4 和流有关
package javaOfIO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;
/**
* Properties集合使用
*/
public class Demo_Properties {
public static void main(String[] args) throws Exception{
// 1
Properties properties = new Properties();
// 2. add
properties.setProperty("username", "张三");
properties.setProperty("age","20");
// 2. 遍历
// 3.1 keyset
// 3.2 entrySet
// 3.3 StringPropertyNames()
Set<String> strings = properties.stringPropertyNames(); // 获取属性名
for (String string : strings) {
System.out.println(string + ":" + properties.getProperty(string));
}
// 4. 和流有关的方法
// -------------------------list方法-----------------------
// PrintWriter printWriter = new PrintWriter("d:\\print.txt");
// properties.list(printWriter);
// printWriter.close();
// -------------------------stroe方法保存-----------------------
// FileOutputStream fileOutputStream = new FileOutputStream("d:\\store.properties");
// properties.store(fileOutputStream, "注释");
// fileOutputStream.close();
// -------------------------load方法加载-----------------------
Properties properties1 = new Properties();
FileInputStream fileInputStream = new FileInputStream("d:\\store.properties");
properties1.load(fileInputStream);
fileInputStream.close();
System.out.println(properties1.toString());
}
}