框架"/>
Java 入门学习记录之I/O框架
Java 入门学习记录(九)
I/O 框架
什么是流
内存与存储设备之间传输数据的通道
流的分类
按方向 *
输入流:将 **存储设备 **中的内容读入到 内存 中
输出流:将 **内存 **中的内容写入到 存储设备 中
按单位
字节流:以字节为单位,可以读写所有数据
字符流:以字符为单位,只能读写文本数据
按功能
节点流:具有实际传输数据的读写功能
过滤流:在节点流的基础之上增强功能
字节流
字节流的父类(抽象类):
InputStream:字节输入流
-
public int read()
-
public int read(byte[] b)
-
public int read(byte[] b, int off, int len)
OutputStream:字节输出流
-
public void write(int n)
-
public void write(byte[] b)
-
public void write(byte[] b, int off, int len)
文件字节流
FileInputStream
- public int read(byte[] b) // 从流中读取多个字节,将读到内容存入 b 数组,返回实际读到的字节数;如果达到文件的尾部,则返回 -1
import java.io.FileInputStream;
/*** FileInputStream 使用* 文件字节输入流*/
public class Demo {public static void main(String[] args) throws Exception {FileInputStream fileInputStream = new FileInputStream("D:\\hello.txt");// 读取文件// 单字节读取
// int data = 0;
// while ((data = fileInputStream.read()) != -1) {
// System.out.println((char) data);
// }// 一次读取多个字节(3)byte[] bytes= new byte[3];int count ;while ((count = fileInputStream.read(bytes)) != -1) {System.out.println(new String(bytes)); // new String(bytes, 0, count) 转换字符串从bytes的0下标开始count个数System.out.println(count);}fileInputStream.close();System.out.println("Finished!");}
}
FileOutputStream
- public void write(byte[] b) // 一次写多个字节,将 b 数组中所有字节,写入输出流
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;public class Demo1 {public static void main(String[] args) throws Exception{FileOutputStream outputStream = new FileOutputStream("D:\\hello.txt"); // , boolean append 真时为追加文件,默认覆盖outputStream.write(97);outputStream.write('x');String s = "hello world";outputStream.write(s.getBytes(StandardCharsets.UTF_8));outputStream.close();}
}
利用文件字节流复制文件
import java.io.FileInputStream;
import java.io.FileOutputStream;public class Demo2 {public static void main(String[] args) throws Exception{FileInputStream fis = new FileInputStream("D:\\Bird.jpg");FileOutputStream fos = new FileOutputStream("D:\\Bird_Copy.jpg");// 边读边写byte[] bytes = new byte[1024];int count;while ((count = fis.read(bytes)) != -1) {fos.write(bytes, 0, count);}fis.close();fos.close();System.out.println("Finished!");}
}
然后就出现啦
字节缓冲流
BufferedInputStream
-
提高 IO 效率,减少磁盘访问次数
-
数据存储在缓冲区中,flush 是将缓冲区的数据写入文件中,也可以直接 close
import java.io.BufferedInputStream;
import java.io.FileInputStream;public class Demo3 {public static void main(String[] args) throws Exception{FileInputStream fis = new FileInputStream("D:\\hello.txt");BufferedInputStream bis = new BufferedInputStream(fis); // 目的是增强底层流的功能, 先读到缓冲区int data;while ((data = bis.read()) != -1) {System.out.println((char)data);}bis.close(); // 不要忘记关闭哦}
}
BufferedOutputStream
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;class Demo3 {public static void main(String[] args) throws Exception{FileOutputStream fos = new FileOutputStream("D:\\buffer.txt");BufferedOutputStream bos = new BufferedOutputStream(fos); // 目的是增强底层流的功能, 先读到缓冲区for (int i =0; i < 10; i++) {bos.write("hello world".getBytes(StandardCharsets.UTF_8)); // 此时读到了缓冲区,没有在文件中bos.flush(); // 使用 flush 刷新到硬盘}bos.close(); // 不要忘记关闭哦}
}
换行转义字符可以在字符串后面添加
\r\n
对象流
ObjectInputStream/ObiectOutputStream
- 增强了缓冲区功能
- 增强了读写 8 种基本数据类型和字符串功能
- 增强了读写对象的功能
- readObject() // 从流中读取一个对象
- writeObject(Object obj) // 向流中写入一个对象
使用流传输对象的过程称为序列化(写入)和反序列化(读取)
序列化
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;public class Demo4 {public static void main(String[] args) throws Exception{FileOutputStream fis = new FileOutputStream("D:\\helloObject.txt");ObjectOutputStream oos = new ObjectOutputStream(fis);Student s1 = new Student("飞宝", 3);oos.writeObject(s1);oos.close(); // close 中有 flushSystem.out.println("Finished!");}
}
此时会出现异常
此时需要在 Student
类中添加一个标记接口 Serializable
,表示可以被序列化的对象
反序列化
public static void main(String[] args) throws Exception{FileInputStream fis = new FileInputStream("D:\\helloObject.txt");ObjectInputStream ois = new ObjectInputStream(fis);Student s = (Student) ois.readObject();ois.close();System.out.println("Finished!");System.out.println(s);
}
注意事项
序列化类必须实现 Serializable 接口
序列化类中的对象属性要实现 Serializable 接口
实现类中的 序列化版本ID,保证序列化的类和反序列化的类是同一个类
// private static final long serialVersionUID = 4588072408160761752l;
使用 transient (瞬间的) 修饰类属性,则这个属性不可序列化
静态属性不能被序列化
序列化多个对象 批量使用 ArrayList<> 等集合实现
编码方式(常见字符形式)
- ISO-8859-1 收录除 ASCII 外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号
- UTF-8 针对 Unicode 码表的可变长度字符编码
- GB2312 简体中文
- GBK 简体中文、扩充
- BIG5 台湾,繁体中文
字符流
字符流的父类(抽象类):
Reader: 字符输入流
-
public int read()
-
public int read(char[] c)
-
public int read(char[] c, int off, int len)
Writer: 字符输出流
- public void write(int n)
- public void write(String str)
- public void write(char[] c)
文件字符流
FileReader
- public int read(char[] c) // 从流中读取多个字符,将读到的内容存入 c 数组,返回实际读到的字符数;如果达到文件的尾部,则返回 -1
import java.io.FileReader;public class Demo5 {public static void main(String[] args) throws Exception{FileReader fr = new FileReader("D:\\hello.txt");int data;while ((data = fr.read()) != -1) {System.out.print((char) data);}fr.close();
// int count;
// char[] buff = new char[4];
// while ((count = fr.read()) != -1) {
// System.out.println(new String(buff, 0, count));
// }}
}
FileWriter
- public void write(String str) // 一次写多个字符,将所有字符写入输出流
import java.io.FileWriter;public class Demo6 {public static void main(String[] args) throws Exception{FileWriter fw = new FileWriter("D:\\hello.txt");for (int i = 0; i < 10; i++) {fw.write("JavaLearing\r\n");fw.flush();}fw.close();}
}
利用字符流复制文件 (只能复制文本文件,不能复制其他文件!!!)
import java.io.FileReader;
import java.io.FileWriter;public class Demo7 {public static void main(String[] args) throws Exception{FileReader fr = new FileReader("D:\\hello.txt");FileWriter fw = new FileWriter("D:\\hello_Copy.txt");int data;while ((data = fr.read()) != -1) {fw.write(data);fw.flush();}fr.close();fw.close();}
}
字符缓冲流
BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;public class Demo8 {public static void main(String[] args) throws Exception{FileReader fr = new FileReader("D:\\hello.txt");BufferedReader bufferedReader = new BufferedReader(fr);// 自定义 buffer 读取
// char[] chars = new char[1024];
// int count;
// while ((count = bufferedReader.read(chars)) != -1) {
// System.out.println(new String(chars, 0 ,count));
// }// 一行一行的读取String line;while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}bufferedReader.close();}
}
BufferWriter
import java.io.BufferedWriter;
import java.io.FileWriter;public class Demo9 {public static void main(String[] args) throws Exception{FileWriter fw = new FileWriter("D:\\hello.txt");BufferedWriter bw = new BufferedWriter(fw);for (int i = 0; i < 10; i++) {bw.write("hello world!");bw.newLine(); // 相当于插入了 \r\nbw.flush();}bw.close();}
}
打印流
PrintWriter
- 封装了 print() / println()方法,支持写入后换行
- 支持数据原样打印
import java.io.PrintWriter;public class Demo10 {public static void main(String[] args) throws Exception{PrintWriter pw = new PrintWriter("D:\\print.txt");// 原样打印pw.println(97);pw.println(true);pw.println('a');pw.println(3.14);pw.close();}
}
转换流
桥转换流:InputStreamReader / OutputStreamWriter
- 可将字节流转换为字符流
- 可设置字符的编码方式
import java.io.FileInputStream;
import java.io.InputStreamReader;public class Demo10 {public static void main(String[] args) throws Exception{FileInputStream fis = new FileInputStream("D:\\hello.txt");InputStreamReader isr = new InputStreamReader(fis, "utf-8");int data;while ((data = isr.read()) != -1) {System.out.println((char) data);}isr.close();}
}
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;public class Demo10 {public static void main(String[] args) throws Exception{FileOutputStream fos = new FileOutputStream("D:\\hello.txt");OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");for (int i = 0; i < 10; i++) {osw.write("hello Java!\r\n");osw.flush();}osw.close();}
}
File 类
代表物理盘符中的一个文件或者文件夹
- createNewFile() // 创建一个新文件
- mkdir() // 创建一个新目录
- delete() // 删除文件或空目录
- exists() // 判断 File 对象所代表的对象是否存在
- getAbsolutePath() // 获取文件的绝对路径
- getName() // 获取名字
- getParent() // 获取
文件/目录
所在的目录 - isDirectory() // 是否是目录
- isFile() // 是否是文件
- length() // 获取文件的长度
- listFiles() // 列出目录中所有内容
- renameTo() // 将文件重命名为
文件操作
import java.io.File;
import java.util.Date;public class Demo11 {public static void main(String[] args) throws Exception{separator();fileOpen();}// 分割符public static void separator() {System.out.println("路径分隔符" + File.pathSeparator); // ;System.out.println("名称分隔符" + File.separator); // \}// 文件操作public static void fileOpen() throws Exception{// 1.创建文件File file = new File("D:\\file.txt"); // 取消盘符在当前项目目录下创建System.out.println(file);if (! file.exists()) {System.out.println("文件不存在!\r\n创建文件");boolean i = file.createNewFile();System.out.println("创建结果,成功为 true: " + i);}// 2.删除文件// 直接删除
// file.delete(); // boolean
// System.out.println("文件删除");// jvm 退出时删除
// file.deleteOnExit();// 3.获取文件信息System.out.println("获取文件绝对路径 " + file.getAbsolutePath());System.out.println("获取路径 " + file.getPath()); // 与上方的 File 文件实例化路径相同System.out.println("获取名称 " + file.getName());System.out.println("获取上级目录 " + file.getParent());System.out.println("获取文件长度(字节数)" + file.length());System.out.println("获取文件创建时间 " + new Date(file.lastModified()).toLocaleString());// 判断System.out.println("文件是否可写 " + file.canWrite());System.out.println("是否是文件 " + file.isFile());System.out.println("是否隐藏 " + file.isHidden());}
}
文件夹操作
// 文件夹操作public static void directory() {File dir = new File("D:\\aaa\\bbb\\ccc");if (! dir.exists()) {
// dir.mkdir(); // 创建单级目录System.out.println("创建目录结果:"+ dir.mkdirs()); // 多级目录 boolean return}// 2.删除目录
// // 直接删除
// System.out.println("删除结果: " + dir.delete()); // 只能删除最底层的子目录,且目录须为空
// // jvm 删除
// dir.deleteOnExit();// 3.获取目录信息System.out.println("获取文件绝对路径 " + dir.getAbsolutePath());System.out.println("获取路径 " + dir.getPath()); // 与上方的 File 文件实例化路径相同System.out.println("获取名称 " + dir.getName());System.out.println("获取上级目录 " + dir.getParent());System.out.println("获取文件创建时间 " + new Date(dir.lastModified()).toLocaleString());// 4.判断System.out.println("是否是文件 " + dir.isDirectory());System.out.println("是否隐藏 " + dir.isHidden());// 5.遍历文件夹File file = new File("D:\\program files");String[] list = file.list();System.out.println("------遍历文件夹------");for (String s: list) {System.out.println(s);}}
FileFilter接口
public interface FileFilter
- boolean accept(File pathname)
当调用 File 类中的 listFile() 方法时,支持传入 FileFilter 接口实现类,对获取文件进行过滤,只有满足条件的文件才可出现在 listFile() 的返回值中
// FileFilter 接口实现
dir.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {if (dir.getName().endsWith(".jpg")) // 根据文件格式过滤return true;return false;}
});
递归遍历操作文件夹
import java.io.File;/*** 递归遍历文件夹* 递归删除文件夹*/
public class ListDemo {public static void main(String[] args) {listDir(new File("D:\\Data\\LaTeX Data\\Practice\\FinalWorks")); // 随便找个文件夹delList(new File("D:\\New folder"));}public static void listDir(File dir) {File[] files = dir.listFiles();if (files != null && files.length > 0) { // 判断是否存在,或者为空文件夹for (File file : files) {if (file.isDirectory()) {listDir(file); // 递归} else {System.out.println(file.getAbsolutePath());}}}}public static void delList(File dir) {File[] files = dir.listFiles();if (files != null && files.length > 0) { // 判断是否存在,或者为空文件夹for (File file : files) {if (file.isDirectory()) {delList(file); // 递归} else {System.out.println(file.getAbsolutePath());file.delete(); // 文件删除}}}dir.delete(); // 递归目录删除}
}
遍历文件夹
补充集合 Properties
属性集合
- 存储属性名和属性值
- 属性名和属性值都是字符串类型
- 没有泛型
- 和流有关
使用一
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;public class Demo12 {public static void main(String[] args) throws Exception{Properties properties = new Properties();// 添加元素properties.setProperty("username", "张三");properties.setProperty("age", "20");System.out.println(properties);// 遍历// keyset// entryset// stringPropertyNames()Set<String> strings = properties.stringPropertyNames();for (String s: strings) {System.out.println(s + "属性名" + properties.getProperty(s));}// 和流有关的方法PrintWriter pw = new PrintWriter("D:\\hello.txt");properties.list(pw);pw.close();}
}
使用二
// 保存
FileOutputStream fos = new FileOutputStream("D:\\store.properties");
properties.store(fos, "comments");
fos.close();// 加载
Properties properties1 = new Properties();
FileInputStream fis = new FileInputStream("D:\\store.properties");
properties1.load(fis);
fis.close();
System.out.println(properties1);
更多推荐
Java 入门学习记录之I/O框架
发布评论