java中的io流

article/2025/9/15 16:17:27

文章目录

      • 1. IO流,什么是IO?
      • 2.IO流的分类?
      • 3.IO流都在java.io.*包下
      • 4.java IO流有四个家族
      • 5.java.io包下需要掌握的流有16个
      • 6.FileInputStream的1个字节读入法
      • 7.FileInputStream的byte[]读入法
      • 8.FileInputStream的其他方法
      • 9.FileOutputStream用法
      • 10.文件复制
      • 11.FileReader用法
      • 12.复制普通文本文件(Reader/Writer)
      • 13.带有缓冲区的字符输入流
      • 14.包装流和节点流(即转换流)
      • 15.带有缓冲区的字符输出流
      • 16.数据流
      • 17.标准输出流
      • 18.File类的理解以及常用方法
      • 19.目录拷贝
      • 20.序列化和反序列化
      • 21.序列化多个对象
      • 22.transient关键字
      • 23.序列化版本号
      • 24.IO和Properties的联合使用

1. IO流,什么是IO?

I : Input
O: Output
通过IO可以完成硬盘文件的读和写。

2.IO流的分类?

有多种分类方式:
1)一种方式是按照流的方向进行分类:
以内存作为参照物,
往内存中去,叫做输入。或者叫做读(Read)。
从内存中出来,叫做输出。或者叫做写(Write)。

2)另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括文本文件、图片、声音文件、视频文件等等…
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读:1个字节,正好读到’a’
第二次读:1个字节,正好读到’中’字符的一半
第三次都:1个字节,正好读到’中’字符的另外一半

有的流是按照字符的方式读取数据,一次读取一个字符,这种流是为了方便读取普通文本文件存在的。这种流不能读取:图片、声音、视频等文件,只能读取纯文本文件,连word文件都无法读取。
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读: 'a’字符('a’字符在windows系统中占用1个字节)
第二次读: '中’字符('中’字符在windows系统中占用2个字节)

综上所述: 流的分类
输入流、输出流(按照流的方向进行分类)
字节流、字符流(按照读取的方式进行分类)

3.IO流都在java.io.*包下

java中的IO流都已经写好了,我们程序员不需要关心,我们最主要还是掌握,在java中已经提供了哪些流,每个流的特点是什么,每个流对象上的常用方法有哪些?
java中所有的流都是在: java.io.*下。

java中主要还是研究:
怎么new流对象。
调用流对象的哪个方法是读,哪个方法是写。

4.java IO流有四个家族

java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流

java.io.Reader 字符输入流
java.io.Writer 字符输出流

注意: 在java中只要"类名"以Stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流。

5.java.io包下需要掌握的流有16个

文件专属:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter

转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter

缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream

数据流专属:
java.io.DateInputStream
java.io.DateOutputStream

标准输出流:
java.io.printWriter
java.io.printStream

对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream

6.FileInputStream的1个字节读入法

package com.jmpower.javase.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;/*
java.io.FileInputStream:1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。2.字节的方式,完成输入的操作,完成读的操作。(硬盘-->内存)*/
public class FileInputStreamTest01 {public static void main(String[] args) {FileInputStream fis=null;try {//创建字节输入流对象//文件路径:C:\Users\Jm\Desktop\Java\doSome.txt//文件内容为:abcedf//FileInputStream fis=new FileInputStream("C:\\Users\\Jm\\Desktop\\Java\\doSome.txt");//都采用了: 绝对路径//将"\\"写成"/"也是可以的fis=new FileInputStream("C:/Users/Jm/Desktop/Java/doSome.txt");int readDate=fis.read();//这个方法的返回值是读到字节本身System.out.println(readDate);// 97} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//在finally语句块中确保流一定要关闭if (fis != null) {//关闭流的前提是:流不是空。流是null的时候没必要关闭。try {fis.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

7.FileInputStream的byte[]读入法

package com.jmpower.javase.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;/*
int read(byte[] b)一次最多读取b.length个字节。减少硬盘和内存之间的交互,提高程序的执行效率。往byte[]数组当中读。*/
public class FileInputStreamTest02 {public static void main(String[] args) {FileInputStream fis=null;try {//相对路径的话呢?相对路径一定是从当前所在的位置作为起点开始找!//IDEA默认的当前路径是工程Object的根就是IDEA的默认当前路径。//文件内容:abcdeffis=new FileInputStream("text02.txt");byte[] bytes=new byte[4];//准备一个4个长度的byte数组,一次最多读取4个字节。//这个方法的返回值是,读取到的字节数量。(不是字节本身)//int readCount=fis.read(bytes);//System.out.println(readCount);// 第一次读到4个字节//将字节数组全部转换成字符串//System.out.println(new String(bytes));//不应该全部转换,应该读取了多少个字节,转换多少个。//System.out.println(new String(bytes,0,readCount));// abcd//最终版本,读取文件int readCount=0;while((readCount = fis.read(bytes))!=-1){System.out.print(new String(bytes,0,readCount));}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (fis != null) {try {fis.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

8.FileInputStream的其他方法

1)int available(): 返回流当中剩余的没有读取到的字节的数量

package com.jmpower.javase.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class FileInputStreamTest03 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("test03");System.out.println("总字节数量:"+fis.available());// 41//读一个字节//int readDate=fis.read();//还剩下的可读字节为40//System.out.println("还剩下的可读字节的数量:"+fis.available());// 40//这个方法有什么用?byte[] bytes=new byte[fis.available()];//不需要循环了!//直接读一次就行了。int readCount=fis.read(bytes);// 6System.out.println(new String(bytes)); // abcdef} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (fis != null) {try {fis.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

2)long stip(long n): 跳过几个字节不读

package com.jmpower.javase.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class FileInputStreamTest04 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("text02.txt");//a   b  c  d   e   f//97 98 99 100 101 102System.out.println(fis.read());// 97fis.skip(3);//跳过三个字节System.out.println(fis.read());// 101} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (fis != null) {try {fis.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

9.FileOutputStream用法

package com.jmpower.javase.io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamTest01 {public static void main(String[] args) {FileOutputStream fos=null;try {//file01文件不存在会自动新建!//这种方式慎用,这种方式会先将文件清空,然后重新写入。//fos=new FileOutputStream("file01");//以追加的方式在文件末尾写入。不会清空原文件的内容。fos=new FileOutputStream("text02.txt",true);//开始写byte[] bytes={97,98,99,100};//将byte数组全部写出!fos.write(bytes);// abcd//将bute数组的一部分写出!fos.write(bytes,0,2);// ab//字符串String s="我是中国人!";//将字符串转换成数组byte[] bs=s.getBytes();//写fos.write(bs);//写完之后一定要刷新fos.flush();} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (fos != null) {try {fos.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

10.文件复制

package com.jmpower.javase.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;/*
使用FileInputStream + FileOutputStream完成文件的拷贝。
拷贝的过程一定是一边读,一边写。
使用以上的字节流拷贝文件的时候,文件类型随意,万能的。什么样的文件都可以拷贝。*/
public class Copy01 {public static void main(String[] args) {FileInputStream fis=null;FileOutputStream fos=null;try {//创建一个输入流对象fis=new FileInputStream("C:\\Users\\Jm\\Pictures\\自建\\十三届蓝桥杯省一.jpg");//创建一个输出流对象fos=new FileOutputStream("C:\\Users\\Jm\\Desktop\\Java\\十三届蓝桥杯省一.jpg");//最核心的: 一边读,一边写byte[] bytes=new byte[1024*1024];//1MB(一次最多拷贝1MB)int readCount=0;while((readCount=fis.read(bytes))!=-1){fos.write(bytes,0,readCount);}//刷新,输出流最后要刷新fos.flush();} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//分开try,不要一起try//一起try的时候,其中一个出现异常,可能会影响到另一个流的关闭if (fis != null) {try {fis.close();} catch (IOException e) {throw new RuntimeException(e);}}if (fos != null) {try {fos.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

11.FileReader用法

package com.jmpower.javase.io;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
FileReader:读取文本内容时,比较方便,快捷。一次读取一个字符。*/
public class FileReaderTest {public static void main(String[] args) {FileReader reader=null;try {//创建文件字符输入流reader=new FileReader("text02.txt");//开始读char[] chars=new char[4];//一次读取4个字符(1个字符2个字节)int readCount=0;while((readCount=reader.read(chars))!=-1){System.out.print(new String(chars,0,readCount));}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (reader != null) {try {reader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

12.复制普通文本文件(Reader/Writer)

package com.jmpower.javase.io;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class Copy02 {public static void main(String[] args) {FileReader in=null;FileWriter out=null;try {//读in=new FileReader("src/com/jmpower/javase/io/FileInputStreamTest02.java");//写out=new FileWriter("reader");//一边读一边写char[] chars=new char[1024*512];//1MBint readCount=0;while((readCount=in.read(chars))!=-1){out.write(new String(chars,0,readCount));}//刷新out.flush();} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//关闭流if (in != null) {try {in.close();} catch (IOException e) {throw new RuntimeException(e);}}if (out != null) {try {out.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

13.带有缓冲区的字符输入流

package com.jmpower.javase.io;import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;/*
BufferedReader:带有缓冲区的字符输入流。使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲。*/
public class BufferedReaderTest01 {public static void main(String[] args) {FileReader reader=null;BufferedReader br=null;try {reader=new FileReader("src/com/jmpower/javase/io/Copy02.java");//当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做: 节点流。//外部负责包装的这个流,叫做: 包装流,还有一个名字叫做: 处理流。//像当前这个程序来说: FileReader叫做一个节点流。BufferedReader就是包装流/处理流。br=new BufferedReader(reader);/*//第一行String firstLine=br.readLine();System.out.println(firstLine);//第二行String secondLine=br.readLine();System.out.println(secondLine);*///br.readLine()方法读取一个文本行,但不带换行符。String line=null;while((line=br.readLine())!=null){System.out.println(line);}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//关闭流//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭。(可以看源代码)if (br != null) {try {br.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

14.包装流和节点流(即转换流)

package com.jmpower.javase.io;import java.io.*;public class BufferedReaderTest02 {public static void main(String[] args) {BufferedReader br=null;try {//字节流FileInputStream in=new FileInputStream("src/com/jmpower/javase/io/Copy02.java");//通过转换流转换(InputStreamReader将字节流转换成字符流)//in是节点流。reader是包装流。InputStreamReader reader=new InputStreamReader(in);//这个构造方法只能传一个字符流。不能传字节流。//reader是节点流。br是包装流。br=new BufferedReader(reader);String line=null;while((line=br.readLine())!=null){System.out.println(line);}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//关闭最外层try {br.close();} catch (IOException e) {throw new RuntimeException(e);}}}
}

15.带有缓冲区的字符输出流

package com.jmpower.javase.io;import java.io.*;
/*
BufferedWriter: 带有缓冲的字符输出流
OutputStreamWriter: 转换流*/
public class BufferedWriterTest01 {public static void main(String[] args) {BufferedWriter out=null;try {//带有缓冲的字符输出流//out=new BufferedWriter(new FileWriter("bo"));out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("doSome"/*,true*/)));//开始写out.write("123");out.write("\n");out.write("456");//刷新(输出流记得刷新)out.flush();} catch (IOException e) {throw new RuntimeException(e);} finally {if (out != null) {try {out.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

16.数据流

1)写

package com.jmpower.javase.io;import java.io.*;/*
java.io.DataOutputStream:数据专属的流
这个流可以将数据连通数据的类型一并写入文件。
注意: 这个文件不是普通文本文档。(这个文件使用记事本打不开)*/
public class DataOutputStreamTest01 {public static void main(String[] args) {DataOutputStream dos=null;try {//创建数据专属的字节输出流dos=new DataOutputStream(new FileOutputStream("data"));//写数据byte b=100;short s=400;int i=200;long l=300;float f=3.0f;double d=3.14;boolean sex=false;char c='0';//写dos.writeByte(b);dos.writeShort(s);dos.writeInt(i);dos.writeLong(l);dos.writeFloat(f);dos.writeDouble(d);dos.writeBoolean(sex);dos.writeChar(c);//刷新dos.flush();} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (dos != null) {try {dos.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

2)读

package com.jmpower.javase.io;import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;/*
java.io.DataInputStream: 数据字节输入流
DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。
读的顺序需要和谐的顺序一致。才可以正常读出数据。*/
public class DataInputStreamTest01 {public static void main(String[] args) {DataInputStream dis=null;try {dis=new DataInputStream(new FileInputStream("data"));//开始读byte b=dis.readByte();short s=dis.readShort();int i=dis.readInt();long l=dis.readLong();float f= dis.readFloat();double d= dis.readDouble();boolean sex= dis.readBoolean();char c= dis.readChar();System.out.println(b);System.out.println(s);System.out.println(i);System.out.println(l);System.out.println(f);System.out.println(d);System.out.println(sex);System.out.println(c);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (dis != null) {try {dis.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

17.标准输出流

package com.jmpower.javase.io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;/*
java.io.PrintStream: 标准的字节输出流。默认输出到控制台。*/
public class PrintStreamTest {public static void main(String[] args) {//联合起来写System.out.println("hello world!");//分开写java.io.PrintStream ps=System.out;ps.println("hello zhangsan");ps.println("hello lisi");ps.println("hello wangwu");//标准输出流不需要手动colse()关闭。//可以改变标准输出流的输出方向吗?可以try {//标准输出流不再指向控制台,指向“log”文件PrintStream printStream=new PrintStream(new FileOutputStream("log"));//修改输出方向,将输出方向修改到"log"文件System.setOut(printStream);//再输出,输入到了"log"文件中System.out.println("hello lisi");System.out.println("hello zhangsan");System.out.println("hello wangwu");} catch (FileNotFoundException e) {throw new RuntimeException(e);}}
}

18.File类的理解以及常用方法

1)
boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
boolean createNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。
boolean mkdir() 创建由此抽象路径名命名的目录。
boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
String getParent() 返回此抽象路径名的父 null的路径名字符串,如果此路径名未命名为父目录,则返回null。
File getParentFile() 返回此抽象路径名的父,或抽象路径名 null如果此路径名没有指定父目录。
String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。

package com.jmpower.javase.io;import java.io.File;
import java.io.IOException;/*
File1.File类和四大家族没有关系,所以File类不能完成文件的读和写2.File对象代表什么?文件和目录路径名的抽象表示方式。C:\Users\Jm\Desktop\Java 这是一个File对象C:\Users\Jm\Desktop\Java\学习笔记(Java) 这也是一个File对象一个File对象有可能对应的目录,也可能是文件File只是一个路径名的抽象表达形式3.需要掌握File类中常用的方法boolean exists() 测试此抽象路径名表示的文件或目录是否存在。boolean createNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。boolean mkdir() 创建由此抽象路径名命名的目录。boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。String getParent() 返回此抽象路径名的父 null的路径名字符串,如果此路径名未命名为父目录,则返回null。File getParentFile() 返回此抽象路径名的父,或抽象路径名 null如果此路径名没有指定父目录。String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。  */
public class FileTest01 {public static void main(String[] args) {//创建一个File对象File f1=new File("D:\\file");//判断是否存在System.out.println(f1.exists()); // false//如果D:\file不存在,则以文件的形式创建出来/*if(!f1.exists()){try {//以文件的形式创建出来f1.createNewFile();} catch (IOException e) {throw new RuntimeException(e);}}*///如果D:\\file不存在,则以目录的形式创建出来/*if(!f1.exists()){//以目录的形式创建出来f1.mkdir();}*///可以创建多重目录吗?/*File f2=new File("D:\\a\\b\\c\\d");if(!f2.exists()){f2.mkdirs();}*/File f3=new File("C:\\Users\\Jm\\Desktop\\Java\\学习笔记(Java)");//获取文件的父路径String fatherPath=f3.getParent();System.out.println(fatherPath);// C:\Users\Jm\Desktop\JavaFile parentFile=f3.getParentFile();System.out.println("获得绝对路径: "+parentFile.getAbsolutePath());File f4=new File("doSome");System.out.println("绝对路径: "+f4.getAbsolutePath());}
}

2)
String getName() 返回由此抽象路径名表示的文件或目录的名称。
boolean isDirectory() 测试此抽象路径名表示的文件是否为目录。
boolean isFile() 测试此抽象路径名表示的文件是否为普通文件。
long lastModified() 返回此抽象路径名表示的文件上次修改的时间。
long length() 返回由此抽象路径名表示的文件的长度。

package com.jmpower.javase.io;import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;/*
File常用方法:String getName() 返回由此抽象路径名表示的文件或目录的名称。boolean isDirectory() 测试此抽象路径名表示的文件是否为目录。boolean isFile() 测试此抽象路径名表示的文件是否为普通文件。long lastModified() 返回此抽象路径名表示的文件上次修改的时间。long length() 返回由此抽象路径名表示的文件的长度。  */
public class FileTest02 {public static void main(String[] args) {File f1=new File("C:\\Users\\Jm\\Desktop\\Java\\学习笔记(Java)\\day01.txt");//获取文件名System.out.println("文件名: "+f1.getName());//判断是否是一个目录System.out.println(f1.isDirectory());// false//判断是否是一个文件System.out.println(f1.isFile());// true//判断文件最后一次修改时时间long haoMiao=f1.lastModified();Date time=new Date(haoMiao);SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");String strTime=sdf.format(time);System.out.println(strTime);//获取文件的大小System.out.println(f1.length());// 2155字节}
}

3)
File[] listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。

package com.jmpower.javase.io;import java.io.File;/*
File中的lastFiles方法。File[] listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。  */
public class FileTest03 {public static void main(String[] args) {File f1=new File("C:\\Users\\Jm\\Desktop\\Java\\学习笔记(Java)");File[] files=f1.listFiles();//foreachfor(File file:files){//获取绝对路径//System.out.println(file.getAbsolutePath());//获取名字System.out.println(file.getName());}}
}

19.目录拷贝

package com.jmpower.javase.io;import java.io.*;
//程序BUG:拷贝源目录下的第一个文件无法拷贝
public class CopyAll {public static void main(String[] args) {//拷贝源File srcFile=new File("D:\\666\\c语言");//拷贝目标File destFile=new File("C:\\Users\\Jm\\Desktop\\Java");//调用方法拷贝copyDir(srcFile,destFile);}/*** 拷贝目录* @param srcFile   拷贝源* @param destFile  拷贝目标*/private static void copyDir(File srcFile,File destFile){if(srcFile.isFile()){//srcFile如果是一个文件的话,递归结束//是文件需要拷贝//....一边读一边写FileInputStream in=null;FileOutputStream out=null;try {//读这个文件//D:\666\c语言\算法模板\map函数.txtin=new FileInputStream(srcFile);//写到这个文件中//C:\Users\Jm\Desktop\Java\666\c语言\算法模板\map函数.txtString path=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcFile.getAbsolutePath().substring(3);out=new FileOutputStream(path);//一边读一边写byte[] bytes=new byte[1024*1024];//1MBint readCount=0;while((readCount=in.read(bytes))!=-1){out.write(bytes,0,readCount);}//刷新out.flush();} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (out != null) {try {out.close();} catch (IOException e) {throw new RuntimeException(e);}}if (in != null) {try {in.close();} catch (IOException e) {throw new RuntimeException(e);}}}return ;}//获取源下面的子目录File[] files=srcFile.listFiles();for(File file:files){if(file.isDirectory()){//新建对应目录//System.out.println(file.getAbsolutePath());//D:\666\c语言\算法模板                           源目录//C:\Users\Jm\Desktop\Java\666\c语言\算法模板     目标目录String srcDir=file.getAbsolutePath();String destDir=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcDir.substring(3);File newFile=new File(destDir);if(!newFile.exists()){newFile.mkdirs();}}else {//保证拷贝目录下第一个是文件时,不会出现FileNotFound的异常File newFile=new File((destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcFile.getAbsolutePath().substring(3));if(!newFile.exists()){newFile.mkdirs();}}//递归调用copyDir(file,destFile);}}
}

20.序列化和反序列化

序列化: Serialize java对象存储到文件中。将java对象的状态保存下来的过程。
反序列化:DeSerialize 将硬盘上的数据重新恢复到内存当中,恢复成java对象。
在这里插入图片描述

1)序列化的实现:

package com.jmpower.javase.io;import com.jmpower.javase.bean.Student;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/*
1.参与序列化和反序列化的对象,必须实现Serializable接口。2.注意: 通过源码发现,Serializable接只是一个标志接口:public interface Serializable{}这个接口当中什么代码都没有。他只是起到一个标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。3.序列化版本号有什么用呢?java.io.InvalidClassException:com.jmpower.javase.bean.Student;local class incompatible:stream classdesc serialVersionUID = -6680413217747085692, (10年前)local class serialVersionUID = -1967551671371379446(10年后)java语言是采用什么机制来区分类的?第一,首先通过类名进行比对,如果类名不一样,肯定不是同一个类。第二,如果类名一样,再根据序列化版本号进行区分。自动生成序列化版本号的好处:java虚拟机会自动区分不同人相同的实现了Serializable接口的类,都有默认的序列化版本号,他们的序列化版本号不一样。所以区分开了。自动生成序列化版本号的坏处:这种自动生成的序列化版本号,一旦代码确定之后,不能进行后续的修改,因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类。(不利于以后的修改)*/
public class ObjectOutputStreamTest01 {public static void main(String[] args) {//创建java对象Student s=new Student(1111,"zhansan");ObjectOutputStream oos=null;try {//序列化oos=new ObjectOutputStream(new FileOutputStream("students"));//序列化对象oos.writeObject(s);//刷新oos.flush();} catch (IOException e) {throw new RuntimeException(e);} finally {if (oos != null) {try {oos.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

2)反序列化的实现

package com.jmpower.javase.io;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;/*
反序列化*/
public class ObjectInputStreamTest01 {public static void main(String[] args) {ObjectInputStream ois=null;try {ois=new ObjectInputStream(new FileInputStream("students"));//开始反序列化,读Object obj=ois.readObject();//反序列化回来是一个学生对象,所以会调用学生对象的toString方法。System.out.println(obj);ois.close();} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} finally {if (ois != null) {try {ois.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

3)Student类

package com.jmpower.javase.bean;import java.io.Serializable;public class Student implements Serializable {private int age;private int no;private String name;public Student(){}public Student(int no, String name) {this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"no=" + no +", name='" + name + '\'' +'}';}
}

21.序列化多个对象

1)序列化

package com.jmpower.javase.io;import com.jmpower.javase.bean.User;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
/*
一次序列化多个对象呢?可以,可以将对象放到集合当中,序列化对象。
提示:参与序列化的ArrayList集合以及集合中的元素User都需要实现java.io.Serializable接口。*/
public class ObjectOutputStreamTest02 {public static void main(String[] args) {List<User> list=new ArrayList<>();list.add(new User(1111,"zhangsan"));list.add(new User(2222,"lisi"));list.add(new User(3333,"wangwu"));list.add(new User(4444,"zhaoliu"));ObjectOutputStream oos=null;try {oos=new ObjectOutputStream(new FileOutputStream("users"));//序列化一个集合,这个集合对象中放了很多其他对象。oos.writeObject(list);//刷新oos.flush();} catch (IOException e) {throw new RuntimeException(e);} finally {if (oos != null) {try {oos.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

2)反序列化

package com.jmpower.javase.io;import com.jmpower.javase.bean.User;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;public class ObjectInputStreamTest02 {public static void main(String[] args) throws FileNotFoundException {ObjectInputStream ois=null;try {//反序列化ois=new ObjectInputStream(new FileInputStream("users"));List<User> list= (List<User>) ois.readObject();for(User user:list){System.out.println(user);}} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} finally {if (ois != null) {try {ois.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

22.transient关键字

变量被transient关键词修饰,不会参与序列化。

package com.jmpower.javase.bean;import java.io.Serializable;public class User implements Serializable {//java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号//这里没有手动写出来,java虚拟机会默认提供这个序列化版本号。//建议将序列化版本号手动的写出来。不建议自动生成。private static final long serialVersionUID=1L;//java虚拟机识别一个类的时候,先看类名,类名一样再看序列化版本号。private int age;//若不手动写序列化版本号,过了很久,Student这个类源代码改动了。//源代码改动之后,需要重新编译,编译之后生成了全新的字节码文件。//并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变。private int no;//transient关键字表示游离的,不参与序列化。private transient String name;//name不参与序列化操作!
}

23.序列化版本号

序列化版本号有什么用呢?
java.io.InvalidClassException:
com.jmpower.javase.bean.Student;
local class incompatible:
stream classdesc serialVersionUID = -6680413217747085692,
(10年前)
local class serialVersionUID = -1967551671371379446
(10年后)

java语言是采用什么机制来区分类的?
第一,首先通过类名进行比对,如果类名不一样,肯定不是同一个类。
第二,如果类名一样,再根据序列化版本号进行区分。

自动生成序列化版本号处:
java虚拟机会自动区分不同人相同的实现了Serializable接口的类,都有默认的序列化版本号,
他们的序列化版本号不一样。所以区分开了。

自动生成序列化版本号处:
这种自动生成的序列化版本号,一旦代码确定之后,不能进行后续的修改,
因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候
java虚拟机会认为这是一个全新的类。(不利于以后的修改)

所以我们应该手动生成序列化版本号,以后修改源代码的时候,可以不用重新编译,直接运行,不会使得java虚拟机产生新的类,便于程序的修改。

package com.jmpower.javase.bean;import java.io.Serializable;public class User implements Serializable {//java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号//这里没有手动写出来,java虚拟机会默认提供这个序列化版本号。//建议将序列化版本号手动的写出来。不建议自动生成。private static final long serialVersionUID=1L;//java虚拟机识别一个类的时候,先看类名,类名一样再看序列化版本号。private int age;//若不手动写序列化版本号,过了很久,Student这个类源代码改动了。//源代码改动之后,需要重新编译,编译之后生成了全新的字节码文件。//并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变。private int no;//transient关键字表示游离的,不参与序列化。private transient String name;//name不参与序列化操作!
}

24.IO和Properties的联合使用

package com.jmpower.javase.io;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;/*
IO+Properties的联合应用:
非常好的一个设计理念:以后经常改变的数据,可以单独写到一个文件中,使用程序动态读取。将来只需要修改这个文件的内容,java代码不需要改动,不需要重新编译,服务器也不需要重启。就可以拿到动态的信息。类似于以上机制的这种文件被称为配置文件。并且当配置文件中的内容格式是:key1=valuekey2=value的时候,我们把这种配置文件叫做属性配置文件。java规范中要求: 属性配置文件建议以.properties结尾,但这不是必须的。这种以.properties结尾的文件在java中称为: 属性配属文件。其中Properties是专门存放属性配置文件内容的一个类。*/
public class IopropertiesTest01 {public static void main(String[] args) {/*Properties是一个Map集合,key和value都是String类型。想将doSome文件中的数据加载得到Properties的对象当中。*/FileReader reader=null;try {//创建输入流对象reader=new FileReader("doSome1.properties");//创建一个Map集合Properties pro=new Properties();//调用Properties对象的load方法将文件中的数据加载到Map集合中。pro.load(reader);//文件中的数据顺着管道加载到Map集合中,其中=左边做key,右边做value//通过key来的调用valueSystem.out.println(pro.getProperty("age"));//遍历Set<Map.Entry<Object, Object>> s=pro.entrySet();for(Map.Entry<Object,Object> o:s){System.out.println(o.getKey()+"="+o.getValue());}} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {if (reader != null) {try {reader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}

属性配置文件的使用:

#在属性配置文件中井号是注释
#建议key和value之间使用=的方式,不建议使用 age:40
#=左边是key,=右边是value
#最好不要有空格
username=zhangsan
age=40

http://chatgpt.dhexx.cn/article/TlVlr0bu.shtml

相关文章

Java读写IO流详解

一、IO流要明确的几点 &#xff08;1&#xff09;明确要操作的数据是数据源还是数据目的&#xff08;是读还是写&#xff09; 源/读 InputStream Reader 目的/写 OutputStream Writer &#xff08;2&#xff09;明确操作设备上的数据是字节还是文本 源/读 字节&…

python IO流

python io流 总的来说就说计算机输入和输出的操作&#xff0c;一般来说是内存与磁盘之间的输入输出 一种虚拟世界的物质。 IO流操作是一种持久化操作&#xff0c;是将数据持久化在磁盘上。 这里用了open函数 函数的第一个引号内放的是运行的python文件目录下的一个名为1.txt的…

IO流的概念

IO流的概念 IO就是Input和Output的简写&#xff0c;也就是输入和输出的含义 IO流就是读写数据时像流水一样从一端流到另外一端&#xff0c;因此得名为"流" 基本分类 按照读写数据的基本单位不同&#xff0c;分为字节流和字符流 其中字节流主要指以字节为单位进行…

什么是IO流?

大家好,我是IT修真院北京分院第27期的JAVA学员,一枚正直纯洁善良的java程序员。 今天给大家分享一下,修真院官网Java任务10,深度思考中的知识点———什么是IO流? 1.背景介绍 什么是流 流就是一系列的数据 当不同的介质之间有数据交互的时候,JAVA就使用流来实现。 数…

JavaIO流详解

转载&#xff1a;https://www.cnblogs.com/LittleHann/p/3678685.html Java输入、输入、IO流 类层次关系梳理 本文主要关注在Java编程中涉及到的IO相关的类库、方法。以及对各个层次(抽线、接口继承)的流之间的关系进行梳理 相关学习资料 http://baike.baidu.com/view/100795…

IO流的介绍

一&#xff1a;IO流的介绍 1.IO流属于一种Java技术&#xff0c;主要用于处理数据传输。通过IO与外界进行数据交互&#xff0c;通信等。 2.IO流适用于文件&#xff0c;图片&#xff0c;音乐&#xff0c;视频等等的传输任务。 3.通信的目标也存在多种。例如&…

最全最详细的IO流教程

前言 io流用到的地方很多&#xff0c;就比如上传下载&#xff0c;传输&#xff0c;设计模式等…基础打扎实了&#xff0c;才能玩更高端的。 在博主认为真正懂IO流的优秀程序员每次在使用IO流之前都会明确分析如下四点&#xff1a; &#xff08;1&#xff09;明确要操作的数据…

IO流详解.

目录&#xff1a; 一、IO流概述 二、FileInputStream初步 三、FileOutStream的使用 四、文件复制 五、FileReader的使用 六、FileWriter的使用 七、复制普通文本文件 八、带有缓冲区的字符流 九、标准输出流&#xff08;掌握&#xff09; / 写日志 十、File类 一、IO流概述…

IO流 (字节流、字符流)

目录 一、IO流概述 1.1 IO流概述 1.2 FileInputStream读取一个字节 1.3 FileInputStream读取多个字节 1.4 FileInputStream读取全部字节 1.5 FileOutputStream写字节 1.6 字节流复制文件 二、IO流资源释放 2.1 JDK7以前的资源释放 2.2 JDK7以后的资源释放 三、字符流…

面试官:请讲一讲IO流核心模块与基本原理是什么?

前言 一、IO流与系统 IO技术在JDK中算是极其复杂的模块&#xff0c;其复杂的一个关键原因就是IO操作和系统内核的关联性&#xff0c;另外网络编程&#xff0c;文件管理都依赖IO技术&#xff0c;而且都是编程的难点&#xff0c;想要整体理解IO流&#xff0c;先从Linux操作系统…

java IO流

目录 序 一、IO流开篇 1、概念 2、流的分类 3、IO流的作用 4、IO流的使用场景 二、字节流 1、字节流抽象基类 2、字节流写数据 &#xff08;1&#xff09;基本步骤 &#xff08;2&#xff09;三种方式 &#xff08;3&#xff09;两个问题 &#xff08;4&#xff0…

【Java基础-3】吃透Java IO:字节流、字符流、缓冲流

Java IO流 前言1 初识Java IO1.1 IO流分类1.2 案例实操 2 IO流对象2.1 File类2.2 字节流2.3 字符流2.4 序列化 3 IO流方法3.1 字节流方法3.2 字符流方法 4 附加内容4.1 位、字节、字符4.2 IO流效率对比4.3 NIO 前言 有人曾问fastjson的作者&#xff08;阿里技术专家高铁&#x…

2.2.5 操作系统之调度算法(时间片轮转调度算法、优先级调度算法、多级反馈队列调度算法)

文章目录 0.思维导图1.时间片轮转---RR2.优先级调度算法3.多级反馈队列调度算法4.三种算法的对比总结 0.思维导图 1.时间片轮转—RR Round-Robin 时间片为2举例 以时间片为5举例 可能出现的问题&#xff0c;比如与FCFS对比 2.优先级调度算法 非抢占式例子 - 抢占式例子 补充…

进程调度算法详解

进程调度算法 &#x1f3de;️1. 调度指标&#x1f301;2. 先进先出&#xff08;FIFO&#xff09;&#x1f320;3. 最短作业优先&#xff08;SJF&#xff09;&#x1f30c;4. 最短剩余时间优先&#xff08;STCF&#xff09;&#x1f33f;5. 新度量指标&#xff1a;响应时间&…

《操作系统》-调度算法

调度算法 在了解调度算法之前我们先了解一下调度算法的评价指标从这几个方面入手&#xff1a;CPU利用率、系统吞吐量、周转时间、等待时间、响应时间 CPU利用率&#xff1a;指CPU“忙碌”的时间占总时间的比例 由于早期的CPU造价极其昂贵&#xff0c;因此人们会希望让CPU尽可…

【操作系统】-- 时间片轮转调度算法、优先级调度算法、多级反馈队列调度算法

一、时间片轮转调度算法 1、算法思想 公平地、轮流地为各个进程服务&#xff0c;让每个进程在一定时间间隔内都可以得到响应。 2、算法规则 按照各进程到达就绪队列的顺序&#xff0c;轮流让各个进程执行一个时间片&#xff0c;若进程未在一个时间片内执行完&#xff0c;则…

调度算法解析

一、常见的批处理作业调度算法 1.先来先服务调度算法&#xff08;FCFS&#xff09;:就是按照各个作业进入系统的自然次序来调度作业。这种调度算法的优点是实现简单&#xff0c;公平。其缺点是没有考虑到系统中各种资源的综合使用情况&#xff0c;往往使短作业的用户不满意&…

进程和线程调度算法

调度算法是指&#xff1a;根据系统的资源分配策略所规定的资源分配算法&#xff0c;如任务A在执行完后&#xff0c;选择哪个任务来执行&#xff0c;使得某个因素&#xff08;如进程总执行时间&#xff0c;或者磁盘寻道时间等&#xff09;最小。对于不同的系统目标&#xff0c;通…

进程的调度算法

什么时候调度进程 在进程的生命周期中&#xff0c;当进程从一个运行状态到另外一状态变化的时候&#xff0c;其实会触发一次调度。 比如&#xff0c;以下状态的变化都会触发操作系统的调度&#xff1a; 从就绪态->运行态&#xff1a;当进程被创建时&#xff0c;会进入到就…

调度算法的介绍及优缺点

调度算法是根据系统的资源分配策略所规定的资源分配算法。有的调度算法适用于作业调度&#xff0c;有的适用于进程调度&#xff0c;有的两者都适用。先了解几个术语 到达时间、服务时间、开始时间 完成时间、等待时间 周转时间&#xff1a;完成时间-到达时间 带权周转时间&…