IO流
1 IO流概述
IO流:传输数据的一套机制。
输入和输出的参考系是程序中的内存
I: input 输入流
O: output 输出流
Java中的流分为两种:字节流、字符流
字符流只能处理和字符相关的文件
字节流可以处理所有的文件
分为字符输入流 字符输出流 字节输入流 字节输出流
字符流 | 字节流 | |
---|---|---|
输入流 | Reader | InputStream |
输出流 | Writer | OutputStream |
2 File类
用于操作文件和文件夹(目录)的。
public static void main(String[] args) throws IOException {
// 创建文件对象
// 表示创建了一个指向D盘下的a.txt的file对象
// file对象在创建的时候不会去检查文件或者文件夹是否真实存在
// 仅仅是将当前的路径标记为一个file对象
File file = new File("D:\\62q\\第一阶段\\0625映射\\笔记");
// 当且仅当这个文件不存在的时候,创建该文件
// 要求存放文件的目录必须真实存在
// 只能创建文件不能创建目录
// 返回true说明创建成功
// boolean newFile = file.createNewFile();
// System.out.println(newFile);
// 当且仅当目录不存在时,会创建目录
// 创建目录 这个只能创建单级的目录
// boolean mkdir = file.mkdir();
// System.out.println(mkdir);
// 创建目录 创建多级目录
// boolean mkdirs = file.mkdirs();
// System.out.println(mkdirs);
// 判断目录或者文件是否存在
// boolean exists = file.exists();
// System.out.println(exists);
// 删除文件或者目录 永久删除 回收站中没有
// 当删除目录时,这个目录不是空,则删除失败
// boolean delete = file.delete();
// System.out.println(delete);
// 获取指定目录下的所有的的子目录和子文件
File[] files = file.listFiles();
for (File file1 : files) {
System.out.println(file1);
if (file1.isDirectory()){
File[] files1 = file1.listFiles();
for (File file2 : files1) {
System.out.println(file2);
}
}
}
// 判断file是否是一个文件
System.out.println(file.isFile());
// 判断file是否是一个目录
System.out.println(file.isDirectory());
// 获取文件名
System.out.println(file.getName());
}
课堂练习:删除某一个目录中的所有的文件和所有的目录
private static void deleteDir(File file) {
// 删除某一个目录中的所有的文件和所有的目录
// 判断file对象是文件还是目录
if (file.isDirectory()){
// 如果是目录,获取目录中的子目录和子文件
File[] files = file.listFiles();
// 遍历数组
for (File file1 : files) {
deleteDir(file1);
}
}
// 如果是文件
file.delete();
}
课堂练习:统计工作空间中java文件和class文件的个数
static int javaCount = 0;
static int classCount = 0;
private static void count(File file){
// 统计工作空间中java文件和class文件的个数
if (file.isDirectory()){
// 获取子目录或子文件
File[] files = file.listFiles();
for (File file1 : files) {
count(file1);
}
}else if (file.getName().endsWith(".java")){
javaCount++;
}else if (file.getName().endsWith(".class")){
classCount++;
}
}
public static void main(String[] args) {
File file = new File("D:\\b\\b.txt");
// 判断文件能否被执行 windows中都返回true 在windows中认为只要是能打开的文件就是可执行文件
// System.out.println(file.canExecute());
// // 判断文件是否可写
// System.out.println(file.canWrite());
//
// // 获取绝对路径
// // 绝对路径就是从盘符开始的路径
// System.out.println(file.getAbsolutePath());
// 获取剩余空间 单位 字节
System.out.println(file.getFreeSpace());
// 获取可用空间
System.out.println(file.getUsableSpace());
// 获取总大小
System.out.println(file.getTotalSpace());
// 获取文件名
// separatorChar: 目录分隔符 unix / windows \\
// pathSeparatorChar: 路径分隔符 unx : windows ;
System.out.println(file.getName());
// 获取父路径
System.out.println(file.getParent());
// 获取路径
System.out.println(file.getPath());
// can 能不能
// is 是不是
// has 有没有
// get 获取
// set 设置
// 是否是绝对路径
System.out.println(file.isAbsolute());
// 是否是隐藏文件
System.out.println(file.isHidden());
// 获取最后的修改时间到计算机元年的毫秒值
System.out.println(file.lastModified());
// File[] files = file.listFiles(new FileFilter() {
// // 如果满足条件,就会留下
// // 如果不满足条件,会被过滤掉
// @Override
// public boolean accept(File file1) {
// return file1.getName().matches(".*\\d.*");
// }
// });
// File[] files = file.listFiles(f -> f.getName().matches(".*\\d.*"));
// for (File file1 : files) {
// System.out.println(file1);
// }
// File[] files = file.listFiles(new FilenameFilter() {
// // dir 是文件所在的父目录
// // name 文件名
// @Override
// public boolean accept(File dir, String name) {
// return name.matches(".*\\d.*");
// }
// });
// File[] files = file.listFiles((d, n) -> n.matches(".*\\d.*"));
// for (File file1 : files) {
// System.out.println(file1);
// }
// 移动文件并重命名
file.renameTo(new File("D:\\b\\b.txt"));
// 设置最后的修改时间
// file.setLastModified(1000L);
file.setReadOnly();
// 设置是否可写
file.setWritable(true);
}
3 字符流
3.1 FileWriter
FileWriter是一个字符输出流
public static void main(String[] args) throws IOException {
// 创建字符输出流
// 创建一个流对象指向D盘下的shangma.txt
// 如果原文件不存在,则使用创建的文件
// 如果原文件存在,创建新的覆盖原来的文件
// append: 追加写入
FileWriter fileWriter = new FileWriter("D:\\shangma.txt",true);
// 在内存中写字符串
String str = "我爱java";
// 把内存的数据保存到硬盘中
fileWriter.write(str);
// 立即把缓冲区的数据保存在文件中
// 冲刷缓冲区
// fileWriter.flush();
// 当IO流不使用时,记得关闭流
// 当关闭资源之前,会自动冲刷一次缓冲区
fileWriter.close();
fileWriter = null;
// Stream closed 当IO流被关闭后不能再使用
// fileWriter.write("nba");
}
3.2 FileReader
private static void demo2() throws IOException {
// 创建字符输入流
FileReader fileReader = new FileReader("D:\\shangma.txt");
// 一次读取一个字符 读取完毕返回 -1
// int read = fileReader.read();
// System.out.println((char)read);
// int c;
// while ((c = fileReader.read()) != - 1){
// System.out.print((char)c);
// }
// 给读取添加缓冲区
char[] chs = new char[5];
// 读取不到返回-1
// 返回的是读取到的实际个数
// int read = fileReader.read(chs);
// System.out.println(read);
// System.out.println(chs);
int len;
while ((len = fileReader.read(chs)) != -1){
System.out.print(new String(chs,0,len));
}
// 关闭资源
fileReader.close();
}
作业: 拷贝一本书
public static void main(String[] args) throws IOException {
// 创建字符输入流和字符输出流
FileReader fileReader = new FileReader("D:\\聊斋志异.txt");
FileWriter fileWriter = new FileWriter("D:\\a\\聊斋.txt");
// 使用字符输入流读取内容
// 定义字符数组作为缓冲区
char[] chs = new char[1024];
// 实际读取到的个数
int len;
while ((len = fileReader.read(chs)) != -1){
// 读取到了内容
// 写入到硬盘中
fileWriter.write(chs,0,len);
// 冲刷缓冲区
fileWriter.flush();
}
// 关流 从里向外关 先创建的流最后关
fileWriter.close();
fileReader.close();
}
3.3 高效字符流
自带缓冲区,非常高效
3.3.1 BufferedReader
3.3.2 BufferedWriter
public static void main(String[] args) throws IOException {
// 装饰设计模式
// 创建高效字符输入流
FileReader fileReader = new FileReader("D:\\聊斋志异.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc.txt"));
// 一次读取一行 不会读取换行符
// 读取到最后返回null
// String s = bufferedReader.readLine();
// System.out.println(s);
String str = null;
while ((str = bufferedReader.readLine()) != null){
bufferedWriter.write(str);
// 换行
bufferedWriter.newLine();
}
// 关流
bufferedWriter.close();
bufferedReader.close();
}
模式:针对某一类问题的统一处理方案
设计模式:在软件开发中针对遇到的问题所提供的统一的解决方案
装饰设计模式:利用同类对象来构建本类对象,然后对所构建的对象进行功能的改善或者增强
public static void main(String[] args) throws IOException {
// 装饰设计模式
// 创建高效字符输入流
FileReader fileReader = new FileReader("D:\\聊斋志异.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc.txt"));
// 一次读取一行 不会读取换行符
// 读取到最后返回null
// String s = bufferedReader.readLine();
// System.out.println(s);
String str = null;
while ((str = bufferedReader.readLine()) != null){
bufferedWriter.write(str);
// 换行
bufferedWriter.newLine();
}
// 关流
bufferedWriter.close();
bufferedReader.close();
}
课堂练习:统计工作空间中java代码的行数
public class Practice01 {
public static void main(String[] args) throws IOException {
// 统计工作空间中java代码的行数
File file = new File("D:\\develop\\workspace");
count(file);
System.out.println("共编写了" + count + "行代码");
}
static int count = 0;
public static void count(File file) throws IOException {
// 判断是否是目录
if (file.isDirectory()){
// 获取子目录和子文件
File[] files = file.listFiles();
for (File f : files) {
count(f);
}
}else if (file.getName().endsWith(".java")){
// java文件
// 读取文件中的行数
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
while (bufferedReader.readLine() != null){
count++;
}
// 关闭资源
bufferedReader.close();
}
}
}
4 字节流
字符流只能操作纯文本文件(.txt .java),字节流可以操作任意的文件
4.1 FileInputStream
private static void demo2() throws IOException {
// 创建字节输入流
FileInputStream fileInputStream = new FileInputStream("D:\\aaa.txt");
// 读取字节 一次读一个字节
// int read = fileInputStream.read();
// System.out.println(read);
// 创建字节数组作为缓冲区
// fileInputStream.available() 返回字节输入流内容的个数
byte[] bys = new byte[fileInputStream.available()];
// 把内容读取到字节数组中
// int len = fileInputStream.read(bys);
// System.out.println(len);
// System.out.println(new String(bys,0,len));
// int len;
// while ((len = fileInputStream.read(bys)) != -1){
// System.out.print(new String(bys,0,len,"utf-8"));
// }
// 读取所有内容到字节数组中 当内容比较多的时候,不要使用这个方法
// byte[] bytes = fileInputStream.readAllBytes();
// System.out.println(new String(bytes));
fileInputStream.read(bys);
System.out.println(new String(bys));
// 关流
fileInputStream.close();
}
4.2 FileOutputStream
private static void demo1() throws IOException {
// 创建字节输出流 字节流没有缓冲区
// 会在路径中创建一个新的文件
FileOutputStream fileOutputStream = new FileOutputStream("D:\\aaa.txt");
// 写出内容
fileOutputStream.write("尚马教育".getBytes("utf-8"));
// 关流
fileOutputStream.close();
}
使用字节流拷贝文件
private static void demo3() throws IOException {
// 创建字节输入流和字节输出流
FileInputStream fileInputStream = new FileInputStream("D:\\帅哥.gif");
FileOutputStream fileOutputStream = new FileOutputStream("D:\\a\\shuaiguo.gif");
// 创建字节数组作为缓冲区
byte[] bys = new byte[1024];
// 读取到的实际字节个数
int len;
while ((len = fileInputStream.read(bys)) != - 1){
// 写出到新文件中
fileOutputStream.write(bys,0,len);
}
// 关流
fileOutputStream.close();
fileInputStream.close();
}
5 读取内存中的流
private static void demo2() throws IOException {
// ByteArrayOutputStream
// ByteArrayInputStream
// CharArrayWriter
// CharArrayReader
StringWriter stringWriter = new StringWriter();
// 向内存中写入字符串
stringWriter.write("abc");
stringWriter.close();
}
private static void demo1() throws IOException {
String str = "abdefdc";
// 读取字符串
StringReader stringReader = new StringReader(str);
// 定义字符数组作为缓冲区
char[] cs = new char[3];
int len = -1;
while ((len = stringReader.read(cs)) != -1){
System.out.print(new String(cs,0,len));
}
// 关流
stringReader.close();
}
6 转换流
将字节流转换成字符流
FileReader和FileWriter是它们的子类
private static void demo3() throws IOException {
// 转换流 将字节流转换成字符流 可以指定编码格式
// OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\abc.txt"),"utf-8");
// // 写出数据
// outputStreamWriter.write("ufo");
//
// // 关流
// outputStreamWriter.close();
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\abc.txt"));
char[] cs = new char[3];
int len = inputStreamReader.read(cs);
System.out.println(cs);
// 关流
inputStreamReader.close();
}
7 系统流
系统流也称之为标准流
Systen.out 标准输出流
System.in 标准输入流
System.err 标准错误流
private static void demo4() throws IOException {
// 系统输出流 --> 属于字节输出流
System.out.println("HelloWorld");
// 系统错误流 --> 属于字节输出流
System.err.println("警告!");
// 系统输入流 --> 属于字节输入流
// 读取控制台的一个字节
// int i = System.in.read();
// System.out.println((char)i);
for (int j = 0; j < 100; j++) {
System.out.println('a');
System.err.println('a');
}
}
课堂练习:用已知的流从控制台获取一行数据
private static void demo5() throws IOException {
// 用已知的流从控制台获取一行数据
// 获取一行数据 BufferedReader
// 从控制台获取 System.in
// 把字节流转换成字符流 使用转换流 InputStreamReader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String readLine = bufferedReader.readLine();
System.out.println(readLine);
// 关流
// 只需要关闭最外层流,自动关闭里层的流
bufferedReader.close();
}
8 打印流
打印流只有输出流,没有输入流
PrintWriter 字符流
PrintStream 字节流
System.out 和System.err 就是PrintStream类型
private static void demo6() throws IOException {
// 打印流
// 只有输出流,没有输入流
// PrintWriter printWriter = new PrintWriter("a.txt");
// printWriter.write("abc");
// // 打印并换行
// printWriter.println("helloworld");
// printWriter.close();
PrintStream printStream = new PrintStream("b.txt");
printStream.write("abc".getBytes());
printStream.print("lll");
printStream.close();
}
9 随机获取流
随机获取流RandomAccessFile是一个双向流,可以读也可以写
操作模式分为:
- R 读
- RW 读写
- RWS 读写并写入到硬盘
- RWD 读写并写入到硬盘,同步保存
private static void demo7() throws IOException {
// 底层把操作的文件看作一个大型的字节数组,索引从0开始
// 随机获取流 789defg
RandomAccessFile randomAccessFile = new RandomAccessFile("D:\\test.txt","rw");
// 向文件中写入内容
randomAccessFile.write("789".getBytes());
// 读取文件中的内容
System.out.println((char)randomAccessFile.read());
// 将索引设置为0
randomAccessFile.seek(0);
System.out.println((char)randomAccessFile.read());
// 设置索引的位置
randomAccessFile.skipBytes(5);
System.out.println((char)randomAccessFile.read());
// 关流
randomAccessFile.close();
}
10 序列化和反序列化流
序列化: 将对象以及其中的信息转换成字节进行完整保存
反序列化:将存储的字节数组取出来还原对应的对象
static修饰的变量称之为静态变量,是属于类的,不属于对象。所以序列化没有意义,不能被序列化。
transient修饰的变量强制性不能序列化。
serialVersionUID:版本号 。每一个类在实现Serializable接口之后,这个类中就会自动产生一个版本号。如果这个版本号没有手动指定,那么java在编译的时候会根据当前类中的属性和方法自动计算,也就意味着当类中的属性或者方法产生变动的时候,版本号就会自动重新计算。序列化的时候会随着对象一起序列化出去,当对象反序列化的时候,会拿着原来的版本号和当前类中的版本号进行比较,如果版本号一致,序列化成功。如果版本号不一致,序列化失败,抛出异常.
如果手动指定版本号,就使用程序员设定的版本号。
Person类
package cn.javasm.demo;
import java.io.Serializable;
/***
* @className: Person
* @author: gfs
* @description:
* @date: 2024/6/27 16:04
* @version: 0.1
* @since :jdk11
*/
public class Person implements Serializable {
// 手动指定版本号
private static final long serialVersionUID = 785443255L;
private String name;
private String address;
static String kongfu;
transient int age;
private String gender;
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
- 序列化方法
private static void demo8() throws IOException {
// 序列化 把对象完整保存起来
Person person = new Person();
person.setName("周杰伦");
person.setAddress("台湾人");
System.out.println(person);
// 创建序列化流对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("person.data"));
// NotSerializableException 不能序列化异常
// 需要被序列化的类,必须实现Serializable接口
// Serializable接口是标记接口,不需要实现方法
objectOutputStream.writeObject(person);
// 关闭流
objectOutputStream.close();
}
- 反序列化方法
private static void demo9() throws IOException, ClassNotFoundException {
// 反序列化 把信息读取成对象
// 创建反序列化流对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("person.data"));
Person person = (Person) objectInputStream.readObject();
System.out.println(person);
// 关流
objectInputStream.close();
}
11 Properties
private static void demo9() throws IOException, ClassNotFoundException {
// 反序列化 把信息读取成对象
// 创建反序列化流对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("person.data"));
Person person = (Person) objectInputStream.readObject();
System.out.println(person);
// 关流
objectInputStream.close();
}
private static void demo8() throws IOException {
// 序列化 把对象完整保存起来
Person person = new Person();
person.setName("周杰伦");
person.setAddress("台湾人");
System.out.println(person);
// 创建序列化流对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("person.data"));
// NotSerializableException 不能序列化异常
// 需要被序列化的类,必须实现Serializable接口
// Serializable接口是标记接口,不需要实现方法
objectOutputStream.writeObject(person);
// 关闭流
objectOutputStream.close();
}
12 合并流
public class TestDemo {
public static void main(String[] args) throws IOException {
// 创建字节流
FileInputStream fis1 = new FileInputStream("D:\\a.txt");
FileInputStream fis2 = new FileInputStream("D:\\b.txt");
FileInputStream fis3 = new FileInputStream("D:\\c.txt");
// 创建向量
Vector<FileInputStream> vector = new Vector<>();
vector.add(fis1);
vector.add(fis2);
vector.add(fis3);
// 创建合并流
SequenceInputStream sequenceInputStream = new SequenceInputStream(vector.elements());
// 使用合并流读取内容,然后写出到新的文件中
// 创建输出流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\d.txt");
// 创建字节个数
int len;
// 创建缓冲数组
byte[] bs = new byte[20];
while ((len = sequenceInputStream.read(bs)) != -1){
fileOutputStream.write(bs,0,len);
}
// 关流
fileOutputStream.close();
sequenceInputStream.close();
}
}
标签:IO,System,String,file,println,new,out
From: https://www.cnblogs.com/460759461-zeze/p/18287666