学习笔记(高级篇)【IO流】"/>
JAVA学习笔记(高级篇)【IO流】
JAVA
- File
- File类的创建功能
- File类的删除功能
- File类的判断和获取功能
- 遍历目录
- IO流
- IO流分类
- 字节流
- 字节流写数据
- 字节流写数据三种方式
- 字节流写数据的两个小问题
- 字节流写数据加异常处理
- 字节流读数据
- 字节缓冲流
- 案例:复制视频
- 字符流
- 字符串中的编码解码
- 字符流中的编码解码
- 字符流写数据的五种方式
- 字符流读数据的两种方法
- 案例:复制JAVA文件
- 字符缓冲流
- 字符缓冲流特有功能
- IO流小结
- 集合文件案例
- 集合到文件
- 文件到集合
- 点名器
- 复制单级文件夹
- 特殊操作流
- 标准输入流
- 标准输出流
- 字节打印流
- 字符打印流
- 案例:复制JAVA文件(打印流改进版)
- 对象序列化流
- Properties
File
文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,其封装的并不是一个真正存在的文件, 仅仅是一个路径名而已。 它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的
方法名 | 说明 |
---|---|
File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例 |
File(String parent,String child) | 从父路径名字符串和子路径名字符串创建新的File实例 |
File(File parent,String child) | 从父抽象路径名和子路径名字符串创建新的File实例 |
File f1 = new File("E:\\JavaText\\java.text");System.out.println(f1);File f2 =new File("E:\\JavaText","java.txt" );System.out.println(f2);File f3 = new File("E:\\JavaText");File f4 = new File(f3,"java.txt");System.out.println(f4);
E:\JavaText\java.text
E:\JavaText\java.txt
E:\JavaText\java.txt
File类的创建功能
方法名 | 说明 |
---|---|
public boolean createNewFile() | 当具有该名称的文件不存在时,创建一个由该抽象路径名 命名的新空文件 |
public boolean mkdir() | 创建由此抽象路径名命名的目录 |
public boolean mkdirs() | 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录 |
public static void main(String[] args) throws IOException {//需求1:我要在E:\\itcast目录下创建一个文件java. txtFile f1 = new File("E:\\JavaText\\java.txt");System.out.println(f1.createNewFile());//如果文件不存在,就创建文件,并返回true//如果文件存在,就不创建文件,并返回false//需求2:我要在E:\\itcast目录 下创建- -个目 录JavaSEFile f2 = new File("E:\\JavaText\\JavaSE");System.out.println(f2.mkdir());//需求3:我要在E:\\itcast目录下创建- -个多级目录JavaWEB\ \HTMLFile f3 = new File("E:\\JavaText\\JavaWEB\\HTML");System.out.println(f3.mkdirs());}
File类的删除功能
public boolean delete() | 删除由此抽象路径名表示的文件或目录 |
---|
绝对路径和相对路径的区别
- 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:
E:\itcast\java.txt
- 相对路径:必须使用取自其他路径名的信息进行解释。例如:
myFile\Vjava.txt
注意
如果一个目录中有内容(目录,文件),不能直接删除。应该先删除目录中的内容,最后才能删除目录
File类的判断和获取功能
方法名 | 说明 |
---|---|
public boolean isDirectory() | 测试此抽象路径名表示的File是否为目录 |
public boolean isFile() | 测试此抽象路径名表示的File是否为文件 |
public boolean exists() | 测试此抽象路径名表示的File是否存在 |
public String getAbsolutePath() | 返回此抽象路径名的绝对路径名字符串 |
public String getPath() | 将此抽象路径名转换为路径名字符串 |
public String getName() | 返回由此抽象路径名表示的文件或目录的名称 |
public String[] list() | 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组 |
public File[] listFiles() | 返回此抽象路径名表示的目录中的文件和目录的File对象数组 |
public static void main(String[] args) {//创建一个File类对象File f = new File("java.txt");System.out.println(f.isDirectory());System.out.println(f.isFile());System.out.println(f.exists());System.out.println(f.getAbsoluteFile());System.out.println(f.getPath());System.out.println(f.getName());System.out.println("--------");File f2 = new File("E:\\JavaText");String[] strArray = f2.list();for(String str : strArray){System.out.println(str);}System.out.println("--------");File[] fileArray = f2.listFiles();for(File file : fileArray){
// System.out.println(file);if(file.isFile()){System.out.println(file.getName());}}}
false
true
true
E:\IdeaProjects\text\java.txt
java.txt
java.txt
java.txt
JavaSE
JavaWEB
java.txt
遍历目录
思路:
- 根据给定的路径创建一个File对象
- 定义一个方法,用于获取给定目录下的所有内容,参数为第1步创建的File对象
- 获取给定的File目录下所有的文件或者目录的File数组
- 遍历该File数组,得到每一个File对象
- 判断该File对象是否是目录
- 是:递归调用
- 不是:获取绝对路径输出在控制台
- 调用方法
public static void main(String[] args) {//根据给定的路径创建一 个File对象File srcFile = new File("C:\\Users\\陈柏赫\\Desktop\\前端");//调用方法getAllFilePath(srcFile);}//定义- -个方法,用于获取给定目录下的所有内容,参数为第1步创建的File对象public static void getAllFilePath(File srcFile) {//获取给定的File目录下所有的文件或者目录的File数组File[] fileArray = srcFile.listFiles();//遍历该File数组,得到每一个File对象if (fileArray != null) {for (File file : fileArray) {//判断该File对象是否是目录if (file.isDirectory()) {//是:递归调用getAllFilePath(file);}else {//不是:获取绝对路径输出在控制台System.out.println(file.getAbsolutePath());}}}}
IO流
IO流分类
按照数据的流向
- 输入流:读数据
- 输出流:写数据
按照数据类型
- 字节流:字节输入流;字节输出流
- 字符流:字符输入流;字符输出流
如果数据通过Window自带的记事本软件打开,我们还可以读懂里面的内容,就使用字符流,否则使用字节流。如果你不知道该使用哪种类型的流,就使用字节流。
字节流
字节流写数据
public static void main(String[] args) throws IOException {//创建字节流输出对象FileOutputStream fos = new FileOutputStream("fos.txt");\/*做了三件事:A:调用系统功能创建了文件B:创建了字节输出流对象C:让字节输出流对象指向创建好的文件*/fos.write(97);//最后都要释放资源fos.close();}
字节流写数据三种方式
方法名 | 说明 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流,一次写一个字节数据 |
void write(byte[] b) | 将b.length字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据 |
void write(byte[] b,int off,int len) | 将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流一次写一个字节数组的部分数据 |
public static void main(String[] args) throws IOException {//创建字节流输出对象FileOutputStream fos = new FileOutputStream("fos.txt");//void write(int b)
// fos.write(97);
// fos.write(98);
// fos.write(99);
// fos.write(100);
// fos.write(101);//void write (byte[] b);
// byte[] bys ={97,98,99,100,101};
// fos.write(bys);byte[] bys = "abcde".getBytes();
// fos.write(bys);//void write(byte[] b,int off,int len)fos.write(bys,1,3);}
字节流写数据的两个小问题
字节流写数据如何实现换行
public static void main(String[] args) throws IOException {//创建字节流输出对象FileOutputStream fos = new FileOutputStream("fos.txt");for(int i = 0;i<10;i++){fos.write("hello".getBytes(StandardCharsets.UTF_8));fos.write("\n".getBytes(StandardCharsets.UTF_8));}fos.close();}
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
字节流写数据如何实现追加写入
public static void main(String[] args) throws IOException {//创建字节流输出对象FileOutputStream fos = new FileOutputStream("fos.txt",true);for(int i = 0;i<10;i++){fos.write("hello".getBytes(StandardCharsets.UTF_8));fos.write("\n".getBytes(StandardCharsets.UTF_8));}fos.close();}
public FileOutputStream(String name,boolean append)
- 创建文件输出流以指定的名称写入文件。如果第二个参数为true,则字节将写入文件的末尾而不是开头
字节流写数据加异常处理
finally
:在异常处理时提供finally块来执行所有清除操作。比如说I0流中的释放资源
特点:被finally控制的语句一定会执行,除非JVM退出。
FileOutputStream fos = null;try{fos = new FileOutputStream("fos.txt");fos.write("hello".getBytes(StandardCharsets.UTF_8));}catch(IOException e){e.printStackTrace();}finally {if(fos != null) {try{fos.close();}catch(IOException e){e.printStackTrace();}}}
字节流读数据
一次读一个字节数据
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("fos.txt");int by;while((by=fis.read())!=-1){System.out.print((char)by);}fis.close();}
一次读一个字节数组数据
byte[] bys = new byte[1024];int len;while((len = fis.read(bys))!=-1){System.out.print(new String(bys,0,len));//String方法}
字节缓冲流
BufferedOutputStream
:该类实现缓冲输出流。通过设置这样的输出流, 应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用BufferedInputStream
:创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
构造方法
- 字节缓冲输入流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("fos.txt"));bos.write("kevin\n".getBytes(StandardCharsets.UTF_8));bos.write("james\n".getBytes(StandardCharsets.UTF_8));bos.close();
- 字节缓冲输出流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("fos.txt"));byte[] bys = new byte[1024];int len;while((len=bis.read(bys))!=-1){System.out.println(new String(bys,0,len));}bis.close();
案例:复制视频
//基本字节流一次读写一个字节 共耗时:8244毫秒//基本字节流一次读写一个字节数组 共耗时:10毫秒//字节缓冲流一次读写一个字节 共耗时:44毫秒//字节缓冲流一次读写一个字节数组 共耗时:6毫秒public static void main(String[] args) throws IOException {//记录开始时间long startTime = System.currentTimeMillis();//复制视频method2();//记录结束时间long endTime = System.currentTimeMillis();System.out.println("共耗时:"+(endTime-startTime)+"毫秒");}//基本字节流一次读写一个字节public static void method1 () throws IOException {FileInputStream fis = new FileInputStream("C:\\Users\\陈柏赫\\Desktop\\视频\\李观洋.avi");FileOutputStream fos = new FileOutputStream("扣篮.avi");int by;while((by=fis.read())!=-1){fos.write(by);}fos.close();fis.close();}//基本字节流一次读写一个字节数组public static void method2 () throws IOException {FileInputStream fis = new FileInputStream("C:\\Users\\陈柏赫\\Desktop\\视频\\李观洋.avi");FileOutputStream fos = new FileOutputStream("扣篮.avi");byte[] bys = new byte[2048];int len;while((len=fis.read(bys))!=-1){fos.write(bys,0,len);}fos.close();fis.close();}//字节缓冲流一次读写一个字节public static void method3() throws IOException{BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\陈柏赫\\Desktop\\视频\\李观洋.avi"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("扣篮.avi"));int by;while((by=bis.read())!=-1){bos.write(by);}bos.close();bis.close();}//字节缓冲流一次读写一个字节数组public static void method4() throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\陈柏赫\\Desktop\\视频\\李观洋.avi"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("扣篮.avi"));byte[] bys = new byte[1024];int len;while((len=bis.read(bys))!=-1){bos.write(bys,0,len);}bos.close();bis.close();}
字符流
字节与字符:
- ASCII 码中,一个英文字母(不分大小写)为一个字节,一个中文汉字为两个字节。
- UTF-8 编码中,一个英文字为一个字节,一个中文为三个字节。
- Unicode 编码中,一个英文为一个字节,一个中文为两个字节。
字符流=字节流+编码表
,并且汉字在存储的时候,无论选择哪一种编码存储,第一个字节都是负数。
字符串中的编码解码
//定义一个字符串String s = "中国";//编码byte[] bys = s.getBytes("GBK");System.out.println(Arrays.toString(bys));//解码String ss = new String(bys,"GBK");System.out.println(ss);//[-42, -48, -71, -6]//中国
字符流中的编码解码
字符流抽象基类
Reader
:字符输入流的抽象类Writer
:字符输出流的抽象类
字符流中和编码解码问题相关的两个类
InputStreamReader
:从字节流到字符流的桥梁(InputStreamReader
构造器入参是FileInputStream
的实例对象),它读取字节并使用指定的字符集将其解码为字符。它使用的字符集可以通过名称指定,也可以显式给定,或者可以接受平台的默认字符集。OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt"),"GBK");osw.write("中国");osw.close();InputStreamReader isr = new InputStreamReader(new FileInputStream("fos.txt"),"GBK");int ch;while((ch=isr.read())!=-1){System.out.print((char)ch);}isr.close();
字符流写数据的五种方式
方法名 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(char[] cbuf) | 写入一个字符数组 |
void write(char[] cbuf,int off,int len) | 写入字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str,int off,int len) | 写一个字符串的一部分 |
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt"));osw.write(97);//刷新流osw.flush();osw.write(98);osw.write("\n");//先刷新,再关闭char[] chs = {'a','b','c','d','e'};osw.write(chs);osw.write("\n");osw.write(chs,0,chs.length);osw.write("\n");osw.write(chs,1,3);osw.write("\n");osw.write("jklop");osw.write("\n");osw.write("asdfg",1,3);osw.write("\n");osw.close();
方法名 | 说明 |
---|---|
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭就不能再写数据 |
字符流读数据的两种方法
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
InputStreamReader isr = new InputStreamReader(new FileInputStream("FileOutputStreamDemo.java"));// int ch;
// while((ch=isr.read())!=-1){
// System.out.print((char)ch);
// }char[] chs = new char[1024];int len;while((len=isr.read(chs))!=-1){System.out.println(new String(chs,0,len));}isr.close();/*package IOtext;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;public class FileOutputStreamDemo {public static void main(String[] args){FileOutputStream fos = null;try{fos = new FileOutputStream("fos.txt");fos.write("hello".getBytes(StandardCharsets.UTF_8));}catch(IOException e){e.printStackTrace();}finally {if(fos != null) {try{fos.close();}catch(IOException e){e.printStackTrace();}}}}
}
*/
案例:复制JAVA文件
//根据数据源创建字符输入流对象InputStreamReader isr = new InputStreamReader(new FileInputStream("FileOutputStreamDemo.java"));//根据目的地创建字符输出流对象OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Copy.java"));//一次读写一个字符数据int ch;while((ch=isr.read())!=-1){osw.write(ch);}//一次读写一个字符数组char[] chs = new char[1024];int len;while((len=isr.read(chs))!=-1){osw.write(new String(chs,0,len));}osw.close();isr.close();
改进版
FileReader
:: 用于读取字符文件的便捷类
FileWriter
:用于写入字符文件的便捷类
//根据数据源创建字符输入流对象FileReader fr = new FileReader("FileOutputStreamDemo.java");//根据目的地创建字符输出流对象FileWriter fw = new FileWriter("Copy.java");//一次读写一个字符数据int ch;while((ch=fr.read())!=-1){fw.write(ch);}//一次读写一个字符数组char[] chs = new char[1024];int len;while((len=fr.read(chs))!=-1){fw.write(chs,0,len);}fw.close();fr.close();
字符缓冲流
BufferedWriter
::将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途BufferedReader
:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途
//字符缓冲输出流BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));bw.write("hello");bw.close();//字符缓冲输入流BufferedReader br = new BufferedReader(new FileReader("bw.txt"));int ch;while((ch=br.read())!=-1){System.out.print((char)ch);}char[] chs = new char[1024];int len;while((len=br.read(chs))!=-1){System.out.print(new String(chs,0,len));}br.close();
字符缓冲流特有功能
BufferedWriter
:void newLine()
:写一行行分隔符,行分隔符字符串由系统属性定义
BufferedReader
:public String readLine()
: 读一行文字。结果包含行的内容的字符串,不包括任何行终止字符(如换行符号),如果流的结尾已经到达,则为null。
//字符缓冲输出流BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));for(int i = 0;i<10;i++){bw.write("world");bw.newLine();bw.flush();}bw.close();
//字符缓冲输入流BufferedReader br = new BufferedReader(new FileReader("bw.txt"));String line;while((line=br.readLine())!=null){System.out.println(line);}br.close();
IO流小结
字节流
字符流
集合文件案例
集合到文件
需求:
把ArrayList集合中的字符串数据写入到文本文件。要求:每-个字符串元素作为文件中的- -行数据
//创建ArrayList集合ArrayList<String> array = new ArrayList<String>();//添加集合元素array.add("hello");array.add("world");array.add("java");//创建字符缓冲流输出对象BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt"));//遍历集合,得到每一个元素for(String s:array){bw.write(s);bw.newLine();bw.flush();}bw.close();
改进版(多行数据)
定义学生类
public class Student {private String sid;private String name;private int age;private String address;public Student(){}public Student(String sid,String name,int age,String address){this.sid = sid;this.name = name;this.age = age;this.address = address;}public String getSid(){return sid;}public int getAge() {return age;}public String getAddress() {return address;}public String getName() {return name;}public void setSid(String sid) {this.sid = sid;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setAddress(String address) {this.address = address;}
}
//创建ArrayList集合ArrayList<Student> array = new ArrayList<Student>();//创建学生对象Student s1 = new Student("04202001", "aaa", 15, "西安");Student s2 = new Student("04202002", "bbb", 12, "武汉");Student s3 = new Student("04202003", "ccc", 13, "曹县");//把学生对象添加到集合中array.add(s1);array.add(s2);array.add(s3);//创建字符缓冲输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("students.txt"));//遍历集合for (Student s : array) {//把学生对象拼接成指定格式的字符串StringBuilder sb = new StringBuilder();sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());bw.write(sb.toString());bw.newLine();
// bw.flush();}bw.close();
改进版(数据排序)
定义学生类
public class StudentTest {private String name;private int chinese;private int math;private int english;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getChinese() {return chinese;}public void setChinese(int chinese) {this.chinese = chinese;}public int getMath() {return math;}public void setMath(int math) {this.math = math;}public int getEnglish() {return english;}public void setEnglish(int english) {this.english = english;}public int getSum(){return this.chinese+this.math+this.english;}
}
//创建TreeSet集合,通过比较器进行排序TreeSet<StudentTest> ts = new TreeSet<StudentTest>(new Comparator<StudentTest>() {@Overridepublic int compare(StudentTest s1, StudentTest s2) {// 成绩总分从高到低int num=s2.getSum()-s1.getSum();//分数相同int num2=num==0?s1.getChinese()-s2.getChinese():num;int num3=num2==0?s1.getMath()-s1.getMath():num;int num4=num3==0?s1.getName()pareTo(s2.getName()):num3;return num4;}});//键盘录入学生数据for(int i = 0;i<5;i++){Scanner sc = new Scanner(System.in);System.out.println("请录入第"+(i+1)+"个学生信息:");System.out.println("姓名:");String name = sc.nextLine();System.out.println("语文成绩:");int chinese = sc.nextInt();System.out.println("数学成绩:");int math = sc.nextInt();System.out.println("英语成绩:");int english = sc.nextInt();//创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量StudentTest s = new StudentTest();s.setName(name);s.setChinese(chinese);s.setMath(math);s.setEnglish(english);//把学生对象添加到TreeSet集合ts.add(s);}//创建字符缓冲流输出对象BufferedWriter bw = new BufferedWriter(new FileWriter("ts.txt"));//遍历集合得到学生对象for(StudentTest s :ts){StringBuilder sb = new StringBuilder();sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());bw.write(sb.toString());bw.newLine();bw.flush();}bw.close();
文件到集合
需求:
把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一 个集合元素
//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("array.txt"));//创建ArrayList集合对象ArrayList<String> array = new ArrayList<String>();//调用字符缓冲输入流对象方法读数据String line;while((line=br.readLine())!=null){array.add(line);}br.close();//遍历集合for(String s:array){System.out.println(s);}
改进版
//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("students.txt"));//创建ArrayList集合对象ArrayList<Student> array = new ArrayList<Student>();//调用字符缓冲输入流对象的方法读数据String line;while((line=br.readLine())!=null){//把读取到的数据用split()进行分割String[] strArray = line.split(",");//创建学生对象Student s = new Student();//把字符串数组中的每一个元素取出来,对应的赋值给学生对象的成员变量s.setSid(strArray[0]);s.setName(strArray[1]);s.setAge(Integer.parseInt(strArray[2]));s.setAddress(strArray[3]);//把学生对象添加到集合array.add(s);}br.close();//遍历集合for(Student ss:array){System.out.println(ss.getSid()+","+ss.getName()+","+ss.getAge()+","+ss.getAddress());}
点名器
需求:
我有一个文件里面存储了班级同学的姓名,每一个姓名占一行, 要求通过程序实现随机点名器
//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("names.txt"));//创建ArrayList集合对象ArrayList<String> array = new ArrayList<String>();//调用字符缓冲输入流对象的方法读数据String line;while ((line = br.readLine()) != null) {array.add(line);}br.close();Random r = new Random();int index = r.nextInt(array.size());//把生产的随机数作为索引到ArrayList集合中获取值String name = array.get(index);System.out.println("学生:" + name);
复制单级文件夹
public static void main(String[] args) throws IOException{//根据数据源目录File对象File srcFolder = new File("E:\\JavaText");//获取数据源目录File对象的名称String srcFloderName = srcFolder.getName();//创建目的地目录File对象File destFolder = new File("text",srcFloderName);//判断目的地目录对应的File是否存在,如果不存在,就创建if(!destFolder.exists()){destFolder.mkdir();}//获取数据源目录下所有文件的File数组File[] listFiles = srcFolder.listFiles();//遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件for(File srcFile : listFiles){//获取数据源文件File对象的名称String srcFileName = srcFile.getName();//创建目的地文件File对象File destFile = new File(destFolder,srcFileName);//复制文件copyFile(srcFile,destFile);}}private static void copyFile(File srcFile, File destFile) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));byte[] bys = new byte[1024];int len;while((len=bis.read(bys))!=-1){bos.write(bys,0,len);}bis.close();bos.close();}
特殊操作流
标准输入流
System
类中有两个静态成员变量:
public static final InputStream in
:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
public static final PrintStream out
:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
InputStream is = System.in;
// int by;
// while((by=is.read())!=-1){1
// System.out.print((char)by);
// }
// //如何把字节流转换为字符流?用转换流
// InputStreamReader isr = new InputStreamReader(is);
// //使用字符流实现一次读取一行数据
// //创建字符缓冲输入流对象
// BufferedReader br = new BufferedReader(isr);BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String line = br.readLine();System.out.println(line);
JAVA提供了一个键盘录入类
Scanner sc = new Scanner(System.in);
标准输出流
PrintStream ps = System.out;
ps.print("hello");
ps.print(10);
简便输出
System.out.println();
System.out.print(10);//必须有数据
字节打印流
特点:
只负责输出数据,不负责读取数据
PrintStream ps = new PrintStream("ps.txt");//写数据//字节输出流ps.write(97);//转码//使用特有方法写数据ps.print(97);//输出原样ps.println(98);//释放资源ps.close();
PrintStream(String fileName)
:使用指定的文件名创建新的打印流- 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
字符打印流
构造方法
PrintWriter pw = new PrintWriter("pw.txt");pw.write("hello");pw.write("\n");pw.flush();pw.write("world");pw.write("\n");pw.flush();pw.println("hello");pw.flush();PrintWriter pww =new PrintWriter(new FileWriter("pw.txt"),true);pww.println("hello");pww.println("world");
案例:复制JAVA文件(打印流改进版)
public static void main(String[] args) throws IOException {/*//根据数据源创建字符输入流对象BufferedReader br = new BufferedReader(new FileReader("FileOutputStreamDemo.java"));//根据目的地创建字符输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));//读写数据,复制文件String line;while((line=br.readLine())!=null){bw.write(line);bw.newLine();bw.flush();}//释放资源bw.close();br.close();*///根据数据源创建字符输入流对象BufferedReader br = new BufferedReader(new FileReader("FileOutputStreamDemo.java"));//根据目的地创建字符输出流对象PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"),true);//读写数据,复制文件String line;while((line=br.readLine())!=null);{pw.println(line);}//释放资源pw.close();br.close();}
对象序列化流
对象序列化:就是将对象保存到磁盘中,或者在网络在中传输对象
1.对象序列化流:ObjectOutputStream
将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取 (重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
public static void main(String[] args)throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Oo.txt"));//创建对象Student s = new Student("aaa",15);//将指定对象写入oos.writeObject(s);//释放资源oos.close();}
注意:
- 一个对象要想被序列化,该对象所属的类必须实现
Serializable
接口 Serizable
是一个标记接口,实该接口,不需要重写任何方法
2.对象反序列化流:ObjectInputStream
方法:readObject()
从ObjectInputStream读取一个对象
public static void main(String[] args) throws IOException,ClassNotFoundException{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Oo.txt"));//读取对象Object obj = ois.readObject();//向下转型Student s = (Student)obj;System.out.println(s.getName()+","+s.getAge());ois.close();}
3.serialVersionUID
public static void main(String[] args)throws IOException,ClassNotFoundException{
// write();read();}//反序列化public static void read()throws IOException,ClassNotFoundException{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Oo.txt"));Object obj = ois.readObject();Student s = (Student)obj;System.out.println(s.getName()+","+s.getAge());ois.close();}//序列化public static void write()throws IOException{ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Oo.txt"));Student s = new Student("bbb",13);oos.writeObject(s);oos.close();}
当对象序列化流序列化一个对象后,我们修改对象所属的类文件,读取数据会出现错误。这时我们需要给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42L;
如果一个对象的某个成员的值不想被序列化,则需要添加transient
修饰,该关键字标记的成员变量不参与序列化过程。
Properties
是一个Map体系的集合类,可以保存到流中或从流中加载
public static void main(String[] args) {//创建集合对象Properties prop = new Properties();//存储元素prop.put("1111", "jjj");prop.put("2222", "sss");prop.put("3333", "aaa");//遍历集合Set<Object> keySet = prop.keySet();for (Object key : keySet) {Object value = prop.get(key);System.out.println(key + "," + value);}}
特有方法
方法名 | 说明 |
---|---|
Object setProperty(String key,String value) | 设置集合的键和值,都是String类型,底层调用Hashtable方法put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set<String>stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
public static void main(String[] args) {Properties prop = new Properties();prop.setProperty("1111", "aaa");prop.setProperty("2222", "bbb");prop.setProperty("3333", "ccc");System.out.println(prop.getProperty("1111"));Set<String> names = prop.stringPropertyNames();for (String key : names) {String value = prop.getProperty(key);System.out.println(key + "," + value);}}
Properties和IO流结合的方法
方法名 | 说明 |
---|---|
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out,String comments) | 将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer,String comments) | 将此属性列表(键和元素对)写入此Properties表中,以适合使用load(Reader)方法的格式写入输出字符流 |
public static void main(String[] args) throws IOException{//把集合中数据保存到文件
// myStore();//把文件中数据加载到集合mtLoad();}private static void mtLoad() throws IOException{Properties prop = new Properties();FileReader fr = new FileReader("fw.txt");prop.load(fr);fr.close();System.out.println(prop);}private static void myStore() throws IOException {Properties prop = new Properties();prop.setProperty("111","aaa");prop.setProperty("222","bbb");prop.setProperty("333","ccc");FileWriter fw = new FileWriter("fw.txt");prop.store(fw,null);fw.close();}
更多推荐
JAVA学习笔记(高级篇)【IO流】
发布评论