关于CodeJava的学习笔记——9
一、IO流
1、定义
I=Input=输入 O=Output=输出
流 : 数据从源点传输到汇点的"管道"而已
2、流的分类
按照方向分: 输入流 输出流 *:参照物=当前Java程序为参照物
按照单位分: 字节流 字符流
按照功能分: 节点流 过滤流(包装流 处理流)
3、各种流
(1)基础IO流
InputStream 所有字节输入流统一的父类 抽象类
int read()
int read(byte[] data)
int read(byte[] data,int offset,int length)
OutputStream 所有字节输出流统一的父类 抽象类
write(int data)
write(byte[] data)
write(byte[] data,int offset,int length)
(2)File
FileInputStream 输入流 字节流 节点流
可以自动创建新的文件。如果指向的文件不存在
FileOutputStream 输出流 字节流 节点流(但是只能连接文件 不能连接目录)
会直接替换掉这个文件,然后往文件内部转数据
import java.io.*;
//JDK7.0 出现的 TWR => Try-With-Resources
public class TestFileCopyWithTWR{
public static void main(String[] args){
try(FileInputStream fis = new FileInputStream("1.mp3");
FileOutputStream fos = new FileOutputStream("3.mp3")){
byte[] data = new byte[5<<20];//5m
int len;
while((len = fis.read(data))!=-1){
fos.write(data,0,len);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
(3)Buffered
BufferedInputStream 输入流 字节流 过滤流
BufferedOutputStream 输出流 字节流 过滤流
作为过滤流的它们 是给原本的流添加缓冲空间
从而提高每次读写的吞吐量 进而提高效率
默认8192 也就是8k 可以传参指定大小
import java.io.*;
public class TestBufferedStream{
public static void main(String[] args)throws Exception{
FileInputStream fis = new FileInputStream("1.mp3");//针头
BufferedInputStream bis = new BufferedInputStream(fis,5<<20);//针管(针头)
FileOutputStream fos = new FileOutputStream("3.mp3");//针头
BufferedOutputStream bos = new BufferedOutputStream(fos,5<<20);//针管(针头)
int data;
while((data = bis.read())!=-1){
bos.write(data);
}
bos.flush();
//bos.close();
bis.close();
}
}
(4)Data
DataInputStream 输入流 字节流 过滤流
DataOutputStream 输出流 字节流 过滤流
为了给原本的流,添加读写基本数据类型的功能
*: DataInputStream 提供的核心方法 readXxxx() 有返回值
*: DataOutputStream 提供的核心方法 writeXxxx() 要参数
import java.io.*;
public class HelloWorld{
public static void main(String[] args)throws Exception{
int time = 1;
File dataFile = new File("cs.data");
if(dataFile.exists()){
DataInputStream dis = new DataInputStream(new FileInputStream(dataFile));
time = dis.readInt();
dis.close();
}
System.out.println("HelloWorld : "+time);
time++;
//存档的逻辑
DataOutputStream dos = new DataOutputStream(new FileOutputStream(dataFile));
dos.writeInt(time);
dos.close();
}
}
(5)Object
ObjectInputStream 输入流 字节流 过滤流
ObjectOutputStream 输出流 字节流 过滤流
*: 想要持久化 首先需要序列化
想要被保存到磁盘当中的对象它的类必须实现序列化接口
implements Serializable
如果这个类型当中有其它引用类型的属性
就连属性的类型也必须要实现序列化接口
如果某些属性无关紧要 不需要参与持久化存储
则可以使用transient修饰
transient => 不参与持久化的
import java.io.*;
public class TestObjectStreamMax{
public static void main(String[] args)throws Exception{
/*
Teacher tea = new Teacher("JayZhou",37);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("电冰箱.data"));
oos.writeObject(tea);
oos.close();
*/
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("电冰箱.data"));
Teacher tea = (Teacher)ois.readObject();
ois.close();
System.out.println(tea.name + " : " + tea.age + " : " +tea.pc);
}
}
class Computer{
String logo;
public Computer(String logo){
this.logo = logo;
}
}
class Teacher implements Serializable{//标识接口
String name;
int age;
//transient => 短暂的 转瞬即逝的 => 不参与持久化的
transient Computer pc;
public Teacher(String name,int age){
this.name = name;
this.age = age;
pc = new Computer("Lenovo");
}
}
4、small big one
import java.io.*;
import java.util.*;
/*
请用程序找出c盘下的所有.jpg图片 (包含子目录中的哦)
然后用刚学的内容 将每张图片都复制到d:\foto目录当中
*: d盘下的foto目录可能尚不存在 得用程序建
*: c盘下的不同的子目录当中 可能会有重名的文件
目标目录当中的文件 请以序列编号命名
00001.jpg
00002.jpg
00003.jpg
*/
public class SmallOne{
static int id; // 用于生成文件名的序列号
static List<File> list = new ArrayList<>(); // 存储找到的.jpg文件列表
public static void main(String[] args){
search(new File("c:\\")); // 从C盘根目录开始搜索
sortList(); // 对找到的文件按最后修改时间排序
createTarget(); // 创建目标目录
for(File src : list){ // 遍历所有找到的文件
File tar = nextFile(); // 获取下一个目标文件名
copy(src,tar); // 复制文件
}
}
// 复制文件的方法
public static void copy(File src,File tar){
try(FileInputStream fis = new FileInputStream(src); // 输入流读取源文件
FileOutputStream fos = new FileOutputStream(tar)){ // 输出流写入目标文件
byte[] data = new byte[16384]; // 缓冲区大小为16KB
int len;
while((len = fis.read(data))!=-1){ // 循环读取数据
fos.write(data,0,len); // 写入数据到目标文件
}
}catch(Exception e){
e.printStackTrace(); // 捕获并打印异常信息
}
}
// 生成下一个目标文件名的方法
public static File nextFile(){
StringBuffer buff = new StringBuffer(String.valueOf(++id)); // 序列号自增并转换为字符串
while(buff.length() < 5){ // 确保文件名长度为5位,不足则补零
buff.insert(0,"0");
}
buff.append(".jpg"); // 添加文件扩展名
File x = new File("d:\\foto",buff.toString()); // 创建目标文件对象
return x; // 返回目标文件对象
}
// 创建目标目录的方法
public static void createTarget(){
File dir = new File("d:\\foto"); // 目标目录路径
dir.mkdirs(); // 创建目录及其父目录(如果不存在)
}
// 对找到的文件列表进行排序的方法
public static void sortList(){
list.sort((a,b) -> Long.compare(a.lastModified(),b.lastModified())); // 按最后修改时间升序排序
}
// 递归搜索指定目录下的所有.jpg文件的方法
public static void search(File tar){
File[] ds = tar.listFiles((x) -> x.isDirectory()); // 获取当前目录下的所有子目录
File[] js = tar.listFiles((x) -> x.isFile() && x.getName().toLowerCase().endsWith(".jpg")); // 获取当前目录下的所有.jpg文件
if(ds == null) return; // 如果当前目录没有子目录,直接返回
for(File d : ds){ // 递归搜索每个子目录
search(d);
}
Collections.addAll(list,js); // 将找到的.jpg文件添加到列表中
}
}