1. File

1.1 File类概述和构造方法(myFile中的com.itheima_01中的FileDemo01)

File:它是文件和目录路径名的抽象表示

  • 文件和目录是可以通过File封装成对象的
  • 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的
方法名 说明
File(String pathname) 通过将给定的路径名 字符串 转换为抽象路径名 来创建新的File实例
File(String parent, String child) 从父路径名 字符串和子路径名 字符串创建新的File实例
File(File parent, String child) 从父抽象路径名 和子路径名 字符串创建新的File实例
package com.itheima_01;import java.io.File;/*File:文件和目录路径名的抽象表示1:文件和目录是可以通过File封装成对象的2:对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的构造方法:File(String pathname):通过将给定的路径名 字符串转换为抽象路径名 来创建新的File实例。File(String parent, String child):从父路径名 字符串和子路径名 字符串创建新的File实例。File(File parent, String child):从父抽象路径名 和 子路径名 字符串创建新的File实例。*/
public class FileDemo01 {public static void main(String[] args) {//File(String pathname):通过将给定的路径名 字符串转换为抽象路径名 来创建新的File实例。File f1 = new File("D:\\itcast\\java.txt");  //结果说明File类重写了toString()方法System.out.println(f1);//File(String parent, String child):从父路径名 字符串 和子路径名 字符串创建新的File实例File f2 = new File("D:\\itcast", "java.txt");System.out.println(f2);//File(File parent, String child):从父抽象路径名 和 子路径名 字符串创建新的File实例File f3 = new File("D:\\itcast");File f4 = new File(f3, "java.txt");}
}

1.2 File类创建功能(myFile中的com.itheima_01中的FileDemo02)

方法名 说明
public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir() 创建由此抽象路径名命名的目录
public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
package com.itheima_01;import java.io.File;
import java.io.IOException;/*File类创建功能:public boolean createNewFile():当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件如果文件不存在,就创建文件,并返回true如果文件存在,就不创建文件,并返回falsepublic boolean mkdir():创建由此抽象路径名命名的目录如果目录不存在,就创建文件,并返回true如果目录存在,就不创建文件,并返回falsepublic boolean mkdirs():创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录如果目录不存在,就创建文件,并返回true如果目录存在,就不创建文件,并返回false*/
public class FileDemo02 {public static void main(String[] args) throws IOException {//需求1:我要在E:\\itcast目录下创建一个文件java.txtFile f1 = new File("D:\\itcast\\java.txt");System.out.println(f1.createNewFile());System.out.println("--------");//需求2:我要在D:\\itcast目录下创建一个目录JavaSE(可能目录代表文件夹,文件是具体文件)File f2 = new File("D:\\itcast\\JavaSE");System.out.println(f2.mkdir());System.out.println("--------");//需求3:我要在D:\\itcast目录下创建一个多级目录JavaWEB\\HTMLFile f3 = new File("D:\\itcast\\JavaWEB\\HTML");
//        System.out.println(f3.mkdir());System.out.println(f3.mkdirs());System.out.println("--------");//需求4:我要在E:\\itcast目录创建一个文件javaee.txtFile f4 = new File("D:\\itcast\\javaee.txt");
//        System.out.println(f4.mkdir());//不能根据文件名来判断是目录还是文件,要根据所使用的方法System.out.println(f4.createNewFile());//不能有同样的目录名和文件名出现在一块}
}

1.3 File类删除功能(myFile中的com.itheima_01中的FileDemo03)

方法名 说明
public boolean delete() 删除由此抽象路径名表示的文件或目录

绝对路径和相对路径的区别

  • 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\itcast\java.txt
  • 相对路径:必须使用取自其他路径名的信息进行解释。例如:myFile\java.txt

删除目录时的注意事项:

  • 如果一个目录中有内容(目录,文件),不能直接删除。应该先删除目录中的内容,最后才能删除目录
package com.itheima_01;import java.io.File;
import java.io.IOException;/*File类删除功能:public boolean delete():删除由此抽象路径名表示的文件或目录*/
public class FileDemo03 {public static void main(String[] args) throws IOException {//        File f1 = new File("D:\\itcast\\java.txt");//给了这样的路径,我能够直接的知道这个文件所在的目录以及它的盘符信息,绝对路径//需求1:在当前模块目录下创建java.txt文件File f1 = new File("myFile\\java.txt");//给了这样的路径,那我就不太清楚这个文件它具体的在哪个盘下的哪个目录的哪个目录下,那么称为什么呢,称为相对路径
//        System.out.println(f1.createNewFile());//需求2:删除当前模块目录下的java.txt文件System.out.println(f1.delete());System.out.println("--------");//需求3:在当前模块目录下创建itcast目录File f2 = new File("myFile\\itcast");
//        System.out.println(f2.mkdir());//需求4:删除当前模块目录下的itcast目录System.out.println(f2.delete());//需求5:在当前模块下创建一个目录itcast,然后在该目录下创建一个文件java.txtFile f3 = new File("myFile\\itcast");
//        System.out.println(f3.mkdir());File f4 = new File("myFile\\itcast\\java.txt");
//        System.out.println(f4.createNewFile());//我们在创建这个文件的时候,如果说它的上级目录不存在,它就会报一个异常,说系统找不到指定路径,所以说,在创建文件之前,首先应该去创建这个目录//需求6:删除当前模块下的目录itcastSystem.out.println(f4.delete());System.out.println(f3.delete());//如果说你要删除的目录下面有内容,那么该目录是不能直接删的,要先把内容给删掉}
}

1.4 File类型判断和获取功能(myFile中的com.itheima_01中的FileDemo04)

方法 说明
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 对象数组
package com.itheima_01;import java.io.File;
import java.io.IOException;/*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 class FileDemo04 {public static void main(String[] args) throws IOException {//创建一个File对象File f = new File("myFile\\java.txt");System.out.println(f.createNewFile());//public boolean isDirectory():测试此抽象路径名表示的File是否为目录//public boolean isFile():测试此抽象路径名表示的File是否为文件//public boolean exists():测试此抽象路径名表示的File是否存在System.out.println(f.isDirectory());System.out.println(f.isFile());System.out.println(f.exists());//public String getAbsolutePath():返回此抽象路径名的绝对路径名 字符串//public String getPath():将此抽象路径名转换为路径名 字符串//public String getName():返回由此抽象路径名表示的文件或目录的名称System.out.println(f.getAbsolutePath());System.out.println(f.getPath());System.out.println(f.getName());System.out.println("--------");//public String[] list():返回此抽象路径名表示的目录中的文件和目录的  名称  字符串数组//public File[] listFiles():返回此抽象路径名表示的目录中的文件和目录的 File对象  数组File f2 = new File("D:\\itcast");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);//输出结果会 打出它的绝对路径,这是file类重写了toString()方法的结果
//            System.out.println(file.getName());//            if (file.isFile()) {//                System.out.println(file.getName());
//            }//通过上述if的判断,我可以得到所有文件的名称,而目录的名称我是不要的}}
}

1.5 递归(myDiGui中的com.itheima_01中的DiGuiDemo)

老和尚给小和尚讲故事,故事是:从前有座山,山里有个庙,庙里有个老和尚,老和尚给小和尚讲故事,故事是……

递归概述:以编程的角度来看,递归指的是方法定义中调用方法本身的现象

递归解决问题的思路为:

把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算

递归解决问题要找到两个内容:

  • 递归出口:否则会出现内存溢出
  • 递归规则:与原问题相似的规模较小的问题
package com.itheima_01;/*递归概述:以编程的角度来看,递归指的是方法定义中调用方法本身的现象*/
public class DiGuiDemo {public static void main(String[] args) {//回顾不死神兔问题,求第20个月兔子的对数//每个月的兔子对数:1,1,2,3,5,8int[] arr = new int[20];arr[0] = 1;arr[1] = 1;for (int i = 2; i < arr.length; i++) {arr[i]  = arr[i - 1] + arr[i - 2];}System.out.println(arr[19]);System.out.println(f(20));}/*递归解决问题,首先就是要定义一个方法:定义一个方法f(n),表示第n个月的兔子对数那么,第n-1个月的兔子对数该如何表示呢?f(n-1)同理,第n-2个月的兔子对数该如何表示呢?f(n-2)StackOverflowError:当堆栈溢出发生时抛出一个应用程序递归太深。*/public static int f(int n) {if (n == 1 || n == 2) {return 1;} else {return f(n - 1) + f(n - 2);}}}

案例:递归求阶乘(myDiGui中的com.itheima_02中的DiGuiDemo01)(有图示,不懂再回看)

需求:用递归求5的阶乘,并把结果在控制台输出

分析:

1:阶乘:一个正整数的阶乘是所有小于及等于该数的正整数的积,自然数n的阶乘写作n!

5! = 54321

2:递归出口:1!=1

3:递归规则:n! = n*(n-1)!

5! = 5*4!

思路:

1:定义一个方法,用于递归求阶乘,参数为一个int类型的变量

2:在方法内部判断该变量的值是否是1

是:返回1

不是:返回n*(n-1)!

3:调用方法

4:输出结果

package com.itheima_02;/*需求:用递归求5的阶乘,并把结果在控制台输出思路:1:定义一个方法,用于递归求阶乘,参数为一个int类型的变量2:在方法内部判断该变量的值是否是1是,返回1不是,返回n*(n-1)!3:调用方法4:输出结果*/
public class DiGuiDemo01 {public static void main(String[] args) {//调用方法int result = jc(5);//输出结果System.out.println("5的阶乘是:" + result);}//定义一个方法,用于递归求阶乘,参数为一个int类型的变量public static int jc(int n) {//在方法的内部判断该变量是否是1if (n == 1) {//是,返回1return 1;} else {//不是,返回n*(n-1)!return n *jc(n-1);}}}

案例:遍历目录(myDiGui中的com.itheima_02中的DiGuiDemo02)(感觉有点难呀)

需求:给定一个路径(D:\itcast),请通过递归完成遍历该目录下的所有内容,并把所有文件的绝对路径输出在控制台

思路:

1:根据给定的路径创建一个File对象

2:定义一个方法,用于获取给定目录下的所有内容,参数为第1步创建的File对象

3:获取给定的File目录下所有的文件或者目录的File数组

4:遍历该File数组,得到每一个File对象

5:判断该File对象是否是目录

是:递归调用

不是:获取绝对路径输出在控制台

6:调用方法

package com.itheima_02;import java.io.File;/*需求:给定一个路径(D:\\itcastt),请通过递归完成遍历该目录下的所有内容,并把所有文件的绝对路径输出在控制台思路:1:根据给定的路径创建一个File对象2:定义一个方法,用于获取给定目录下的所有内容,参数为第1步创建的File对象3:获取给定的File目录下所有的文件或者目录的File数组4:遍历该File数组,得到每一个File对象5:判断该File对象是否是目录是,递归调用不是,获取绝对路径输出在控制台6:调用方法*/
public class DiGuiDemo02 {public static void main(String[] args) {//根据给定的路径创建一个File对象File srcFile = new File("D:\\itcastt");
//        File srcFile = new File("D:\\IdeaProjects");//调用方法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());}}}}
}

2. 字节流

2.1 IO流概述和分类

IO流概述:

  • IO:输入/输出(Input/Output)

  • 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输

  • IO流就是用来处理设备间数据传输问题的

    • 常见的应用:文件复制;文件上传;文件下载

硬盘、内存(程序加载到内存里面),把硬盘上的内容给它加载到内存里面,那么这个动作就是一个输入的动作,而输入它对应的是读数据的动作,也就是从硬盘上读数据到内存的动作。把内存上的内容放到硬盘上,做的是一个输出的动作,那么输出对应的是写数据的动作。

IO流分类:

  • 按照数据的流向

    • 输入流:读数据
    • 输出流:写数据
  • 按照数据类型来分

    • 字节流

      • 字节输入流;字节输出流
    • 字符流

      • 字符输入流;字符输出流

一般来说,我们说IO流的分类是按照数据类型来分的

那么这两种流都在什么情况下使用呢?

读得懂的内容我们就用字符流

读不懂内容的这个文件,它就不能使用字符流,只能使用字节流了

  • 如果数据通过Windows自带的记事本软件打开,我们还可以读懂里面的内容,就使用字符流,
  • 否则使用字节流。如果你不知道该使用哪种类型的流,就使用字节流。(因为字节流是万能的流)

2.2 字节流写数据(myByteStream中的com.itheima_01中的FileOutputStreamaDemo01)

字节流抽象基类

  • InputStream:这个抽象类是表示字节输入流的所有类的超类
  • OutputStream:这个抽象类是表示字节输出流的所有类的超类
  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

FileOutputStream:文件输出流用于将数据写入File

  • FileOutputStream(String name):创建文件输出流以指定的名称写入文件

使用字节输出流写数据的步骤:

  • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
  • 调用字节输出流对象的写数据方法
  • 释放资源(关闭此文件输出流并释放与此相关联的任何系统资源)
package com.itheima_01;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;/*FileOutputStream:文件输出用于将数据写入FileFileOutputStream(String name):创建文件输出流以指定的名称写入文件*/
public class FileOutputStreamDemo01 {public static void main(String[] args) throws IOException {//创建字节输出流对象//FileOutputStream(String name):创建文件输出流以指定的名称写入文件FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");/*做了三件事情:A:调用系统功能创建了文件B:创建了字节输出流对象C:让字节输出流对象指向创建好的文件*///void write (int b):将指定的字节写入此文件输出流。fos.write(97);
//        fos.write(57);
//        fos.write(55);//所有和IO操作相关的内容,最后都要释放资源//void close():关闭此文件输出流并释放与此流相关联的任何系统资源。fos.close();}
}

2.3 字节流写数据的3种方式(myByteStream中的com.itheima_01中的FileOutputStreamaDemo02)

方法名 说明
void write(int b) 将指定的字节写入此文件输出流 一次写一个字节数据
void write(byte[] b) 将b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据
void write(byte[] b, int off, int len) 将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据
package com.itheima_01;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;/*构造方法:FileOutputStream(String name):创建文件输出流以指定的名称写入文件FileOutputStream(File file):创建文件输出流以写入由指定的File对象表示的文件写数据的三种方式:void write (int b):将指定的字节写入此文件输出流一次写一个字节数据void write (byte[] b):将b.length字节从指定的字节数组写入此文件输出流一次写一个字节数组数据void write (byte[] b, int off, int len):将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流一次写一个字节数组的部分数据*/
public class FileOutputStreamDemo02 {public static void main(String[] args) throws IOException {//FileOutputStream (String name):创建文件输出流以指定的名称写入文件FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");//这个动作在FileOutputStream类中,底层做的是new File("myByteStream\\fos.txt")这样一个动作,// 把"myByteStream\\fos.txt"字符串路径给封装成了一个File对象//new File(name)
//        FileOutputStream fos = new FileOutputStream(new File("myByteStream\\fos.txt"));//FileOutputStream(File file):创建文件输出流以写入由指定的File对象表示的文件
//        File file = new File("myByteStream\\fos.txt");
//        FileOutputStream fos2 = new FileOutputStream(file);
//        FileOutputStream fos2 = new FileOutputStream(new File("myByteStream\\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):将b.length字节从指定的字节数组写入此文件输出流
//        byte[] bys = {97, 98, 99, 100, 101};//byte[] getBytes():返回字符串对应的数组byte[] bys = "abcde".getBytes();
//        fos.write(bys);//void write (byte[] b, int off, int len):将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流
//        fos.write(bys, 0, bys.length);fos.write(bys, 1, 3);//它是从这个指定的索引开始,写长度为它的数据//释放资源,千万不要忘了!!!fos.close();}
}

2.4 字节流写数据的两个小问题(myByteStream中的com.itheima_01中的FileOutputStreamaDemo03)

字节流写数据如何实现换行呢?

  • 写完数据后,加换行符

    • windows:\r\n
    • linux:\n
    • mac:\r

字节流写数据如何实现追加写入呢?

  • public FileOutputStream(String name, boolean append)
  • 创建文件输出流以指定的名称写入文件。如果第二个参数为true,则字节将写入文件的末尾而不是开头
package com.itheima_01;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;/*字节流写数据的两个小问题:1:字节流写数据如何实现换行呢?用电脑自带记事本打开fos.txt,发现并没有换行,但我的是换行了window:\r\nlinux:\nmac:\r2:字节流写数据如何实追加写入呢?public FileOutputStream(String name, boolean append)创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头。*/
public class FileOutputStreamDemo03 {public static void main(String[] args) throws IOException {//创建字节输出流对象
//        FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt", true);//写数据for (int i = 0; i < 10; i++) {fos.write("hello".getBytes());       //byte[] getBytes():返回字符串对应的数组fos.write("\r\n".getBytes());}//释放资源fos.close();}
}

2.5 字节流写数据加入异常处理(myByteStream中的com.itheima_01中的FileOutputStreamaDemo04)

finally:在异常处理时提供finally块来执行所有清除操作。比如说IO流中的释放资源

特点:被fianlly控制的语句一定会执行,除非JVM退出

try {可能出现异常的代码;
} catch (异常类名 变量名) {异常的处理代码;
} finally {执行所有的清除操作;
}
package com.itheima_01;import java.io.FileOutputStream;
import java.io.IOException;/*字节流写数据加入异常处理*/
public class FileOutputStreamDemo04 {public static void main(String[] args) {//        try {//            FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
//            fos.write("hello".getBytes());
//            fos.close();
//        } catch (IOException e) {//            e.printStackTrace();
//        }//加入finally来实现释放资源FileOutputStream fos = null;try {//            fos = new FileOutputStream("Z:\\myByteStream\\fos.txt");fos = new FileOutputStream("myByteStream\\fos.txt");fos.write("hello".getBytes());} catch (IOException e) {e.printStackTrace();} finally {if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}
}

2.6 字节流读数据(一次读一个字节数据)(myByteStream中的com.itheima_02中的FileInputStreamaDemo01)

需求:把文件fos.txt中的内容读取出来在控制台输出

FileInputStream:从文件系统中的文件获取输入字节

  • FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统的路径名name命名

使用字节输入流读数据的步骤:

1:创建字节输入流对象

2:调用字节输入流对象的读数据方法

3:释放资源

package com.itheima_02;import java.io.FileInputStream;
import java.io.IOException;/*需求:把文件fos.txt中的内容读取出来在控制台输出FileInputStream:从文件系统中的文件获取输入字节FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名使用字节输入流读数据的步骤:1:创建字节输入流对象2:调用字节输入流对象的读数据方法3:释放资源*/
public class FileInputStreamDemo01 {public static void main(String[] args) throws IOException {//创建字节输入流对象FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");//调用字节输入流对象的读数据方法//int read():从该输入流读取一个字节的数据。/*//第1次读取数据int by = fis.read();System.out.println(by);System.out.println((char)by);//第二次读取数据by = fis.read();System.out.println(by);System.out.println((char)by);//再多读取再次by = fis.read();System.out.println((char)by);by = fis.read();System.out.println((char)by);by = fis.read();System.out.println((char)by);by = fis.read();System.out.println((char)by);//如果达到文件的末尾,-1*//*int by = fis.read();while (by != -1) {System.out.print((char)by);by = fis.read();}*///优化上面的程序int by;/*fis.read():读数据by = fis.read():把读取到的数据赋值给byby != -1:判断读取到的数据是否是-1*/while ((by = fis.read()) != -1) {System.out.print((char)by);}//释放资源fis.close();}
}

案例:复制文本文件(myByteStream中的com.itheima_02中的CopyTxtDemo)

需求:把"D:\itcast\窗里窗外.txt"复制到模块目录下的"窗里窗外.txt"

分析:(读进来,写出去)

1:复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)

2:数据源:

D:\itcast\窗里窗外.txt—读数据—InputStream0—FileInputStream by.read();

3:目的地:

myByteStream\窗里窗外.txt—写数据—OutputStream—FileOutputStream fos.write(by);

思路:

1:根据数据源创建字节输入流对象

2:根据目的地创建字节输出流对象

3:读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)

4:释放资源

package com.itheima_02;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*需求:把“D:\\itcastt\\窗里窗外.txt”复制到模块目录下的"窗里窗外.txt"数据源:D:\\itcastt\\窗里窗外.txt---读数据---InputStream---FileInputStream目的地:myByteStream\\窗里窗外.txt---写数据---OutputStream---FileOutputStream思路:1:根据数据源创建字节输入流对象2:根据目的地创建字节输出流对象3:读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)4:释放资源*/
public class CopyTxtDemo {public static void main(String[] args) throws IOException {//根据数据源创建字节输入流对象  FileInputStrem  读数据  by.read();FileInputStream fis = new FileInputStream("D:\\itcastt\\窗里窗外.txt");//根据目的地创建字节输出流对象  FileOutputStream  写数据  fos.write(by);FileOutputStream fos = new FileOutputStream("myByteStream\\窗里窗外.txt");//读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)int by;while ((by = fis.read()) != -1) {fos.write(by);}//释放资源fos.close();fis.close();}
}

2.6 字节流读数据(一次读一个字节数组的部分数据)(myByteStream中的com.itheima_02中的FileInputStreamaDemo02)

需求:把文件fos.txt中的内容出来在控制台输出

使用字节输入流读数据的步骤:

1:创建字节输入流对象

2:调用字节输入流对象的读数据方法

3:释放资源

    int read(byte[] b):该输入流读取最多b.length个字节的数据到一个字节数组。String(byte[] bytes)String(byte[] bytes, int offset, int length)
package com.itheima_02;import java.io.FileInputStream;
import java.io.IOException;/*需求:把文件fos.txt中的内容读取出来在控制台输出使用字节输入流读数据的步骤:1:创建字节输入流对象2:调用字节输入流对象的读数据方法3:释放资源*/
public class FileInputStreamDemo02 {public static void main(String[] args) throws IOException {//创建字节输入流对象FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");//调用字节输入流对象的读数据方法//int read(byte[] b):该输入流读取最多b.length个字节的数据到一个字节数组。/*byte[] bys = new byte[5]; // 这里相当于建立一个字节数组空间//第一次读取数据int len = fis.read(bys);    // 得到字节数组空间长度   System.out.println(len);    // 5//String(byte[] bytes)
//        System.out.println(new String(bys));  // helloSystem.out.println(new String(bys, 0, len));    // hello//第二次读取数据len = fis.read(bys);System.out.println(len);
//        System.out.println(new String(bys));System.out.println(new String(bys, 0, len));//第三次读取数据len = fis.read(bys);System.out.println(len);//String(byte[] bytes, int offset, int length)System.out.println(new String(bys, 0, len));//再多读取再次len = fis.read(bys);System.out.println(len);len = fis.read(bys);System.out.println(len);*//*hello\r\nworld\r\n第一次:hell0第二次:\r\nwor第三次:ld\r\nr*///我觉得是建立一个字节数组空间,然后用fis对象的read()方法,把东西读入到这个空间,//然后把东西长度赋给len,这就是东西的长度,只要这不是-1就可以继续读,然后输出在控制台上byte[] bys = new byte[1024];  //1024及其整数倍int len;while ((len = fis.read(bys)) != -1) {System.out.print(new String(bys, 0, len));}//释放资源fis.close();}
}

案例:复制图片(myByteStream中的com.itheima_02中的CopyJpgDemo)

需求:把"D:\itcastt\mn.jpg"复制到模块目录下的"mn.jpg"

思路:

1:根据数据源创建字节输入流对象

2:根据目的地创建字节输出流对象

3:读写数据,复制图片(一次读取一个字节数组,一定写入一个字节数组

4:释放资源

package com.itheima_02;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*需求:把"D:\\itcastt\\mn.jpg"复制到模块目录下的mn.jpg思路:1:根据数据源创建字节输入流对象2:根据目的地创建字节输出流对象3:读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)4:释放资源*/
public class CopyJpgDemo {public static void main(String[] args) throws IOException {//根据数据源创建字节输入流对象FileInputStream fis = new FileInputStream("D:\\itcastt\\mn.jpg");//根据目的地创建字节输出流对象FileOutputStream fos = new FileOutputStream("myByteStream\\mn.jpg");//读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)byte[] bys = new byte[1024];int len;while ((len = fis.read(bys)) != -1) {fos.write(bys, 0, len);}//释放资源fos.close();fis.close();}
}

2.7 字节缓冲流(myByteStream中的com.itheima_03中的BufferedStreamDemo)

字节缓冲流:

  • BufferedOutputStream:该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
  • BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节

构造方法:

  • 字节缓冲输出流:BufferedOutputStream(OutputStream out)
  • 字节缓冲输入流:BufferedInputStream(InputStream in)

为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?

  • 字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
package com.itheima_03;import java.io.*;/*字节缓冲流:BufferedOutputStreamBufferedInputStream构造方法:字节缓冲输出流:BufferedOutputStream (OutputStream out)字节缓冲输入流:BufferedInputStream (InputStream in)*/
public class BufferedStreamDemo {public static void main(String[] args) throws IOException {//字节缓冲输出流:BufferedOutputStream (OutputStream out)
//        FileOutputStream fos = new FileOutputStream("myByteStream\\bos.txt");
//        BufferedOutputStream bos = new BufferedOutputStream(fos);/*BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\bos.txt"));//写数据bos.write("hello\r\n".getBytes());bos.write("world\r\n".getBytes());//释放资源bos.close();*///字节缓冲输入流:BufferedInputStream(InputStream in)
//        FileInputStream fis = new FileInputStream("myByteStream\\bis.txt");
//        BufferedInputStream bis = new BufferedInputStream(fis);BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\\bos.txt"));//一次读取一个字节数据
//        int by;
//        while ((by = bis.read()) != -1) {//            System.out.print((char)by);
//        }//一次读取一个字节数组数据byte[] bys = new byte[1024];int len;while ((len = bis.read()) != -1) {System.out.print(new String(bys, 0, len));  //不知道为啥这里乱码 这里不用换行 可能编码、解码不同?应该都是默认的字符集}//释放资源bis.close();}
}

案例:复制视频(myByteStream中的com.itheima_03中的CopyAbiDemo)

需求:把"E:\itcastt\字节流复制图片.avi"复制到模块目录下的"字节流复制图片"

思路:

1:根据数据源创建字节输入流对象

2:根据目的地创建字节输出流对象

3:读写数据,复制视频

4:释放资源

package com.itheima_03;import java.io.*;/*需求:把E:\\itcastt\\字节流复制图片.avi复制到模块目录下的 字节流复制图片.avi思路:1:根据数据源创建字节输入流对象2:根据目的地创建字节输出流对象3:读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)4:释放资源四种方式实现复制视频,并记录每种方式复制视频的时间1:基本字节流一次读写一个字节             共耗时:90376毫秒2:基本字节流一次读写一个字节数组          共耗时:171毫秒3:字节缓冲流一次读写一个字节             共耗时:803毫秒4:字节缓冲流一次读写一个字节数组          共耗时:219毫秒*/
public class CopyAviDemo {public static void main(String[] args) throws IOException {//记录开始时间long startTime = System.currentTimeMillis();//复制视频
//        method1();
//        method2();
//        method3();method4();//记录结束时间long endTime = System.currentTimeMillis();System.out.println("共耗时:" + (endTime - startTime) + "毫秒");}//基本字节流一次读写一个字节
//    public static void method1() throws IOException {//        //D:\\itcastt\\字节流复制图片.avi
//        //模块目录下的 字节流复制图片.avi
//        FileInputStream fis = new FileInputStream("D:\\itcastt\\字节流复制图片.avi");
//        FileOutputStream fos = new FileOutputStream("myByteStream\\字节流复制图片.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("D:\\itcastt\\字节流复制图片.avi");
//        FileOutputStream fos = new FileOutputStream("myByteStream\\字节流复制图片.avi");
//
//        byte[] bys = new byte[1024];
//        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("D:\\itcastt\\字节流复制图片.avi"));
//        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\字节流复制图片.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("D:\\itcastt\\字节流复制图片.avi"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\字节流复制图片.avi"));byte[] bys = new byte[1024];int len;while ((len = bis.read(bys)) != -1) {bos.write(bys, 0, len);}bis.close();bos.close();}}

3. 字符流(myCharStream中的com.itheima_01中的FileInputStreamDemo)

package com.itheima_01;import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;/*需求:字节流读文本文件数据一个汉字存储:如果是GBK编码,占用2个字节如果是UTF-8编码,占用3个字符*/
public class FileInputStreamDemo {public static void main(String[] args) throws IOException {//        FileInputStream fis = new FileInputStream("myCharStream\\a.txt");
//
//        int by;
//        while ((by = fis.read()) != -1) {//            System.out.print((char)by);
//        }
//
//        fis.close();//        String s = "abc";  //[97, 98, 99]String s = "中国";  //[-28, -72, -83, -27, -101, -67]
//        byte[] bys = s.getBytes();
//        byte[] bys = s.getBytes("UTF-8");  //[-28, -72, -83, -27, -101, -67]byte[] bys = s.getBytes("GBK");System.out.println(Arrays.toString(bys));    // [-42, -48, -71, -6]}
}

3.1 为什么会出现字符流

由于字节流操作中文不是特别的方便,所以Java就提供字符

  • 字符流 = 字节流 + 编码表

用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文呢?

  • 汉字在存储的时候,无论选择哪种编码存储,每一个字节都是负数

3.2 编码表

基础知识:

  • 计算机中储存的信息都是用二进制数来表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果
  • 按照某种规则,将字符存储到计算机,称为编码。反之,将存储在计算机中的二进制按照某种规则解析显示出来,称为解码

​ 这里强调一下:按照A编码存储,必须按照A编码解析,这样才能显示正确的文本符号。否则就会导致乱码现象

字符编码:就是一套自然语言的字符与二进制之间的对应规则(A,65)

字符集:

  • 是一个系统支持的所有字符的合集,包括各国家文字、标点符号、图形符号、数字等
  • 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。

常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等

ASCII字符集:

  • ASCII(American Standard Code for Information Interchange,美国信息交换标准代码):是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西方符号)

  • 基本的ASCII字符集,使用7位表示一个字符,共128个字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等

GBXXX字符集:

  • GB2312:简体中文码表。一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名等都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的“全角”字符,而原来在127号以下的那些就叫“半角”字符了

  • GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等

  • GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的汉字,同时支持繁体汉字以及日韩汉字等

Unicode字符集:

  • 为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16、UTF32。最为常用的UTF-8编码

  • UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一到四个字节为每个字符编码

编码规则:

128个US-ASCII字符,只需一个字节编码

拉丁文等字符,需要二个字节编码

大部分常用字(含中文),使用三个字节编码

其他极少使用的Unicode辅助字符,使用四字节编码

小结:采用何种规则编码,就要采用对应规则解码,否则就会出现乱码

3.3 字符串中的编码解码问题(myCharStream中的com.itheima_01中的StringDemo)

编码: 这里我们采用的是IDEA平台来编写代码的

  • byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到的字节数组中
  • byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

解码: 这里我们采用的是IDEA平台来编写代码的

  • String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
  • String(byte[] bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
package com.itheima_01;import java.io.UnsupportedEncodingException;
import java.util.Arrays;/*编码:byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中解码:String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的StringString(byte[] bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的String*/
public class StringDemo {public static void main(String[] args) throws UnsupportedEncodingException {//定义一个字符串String s = "中国";//byte[] getBytes():使用平台默认的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
//        byte[] bys = s.getBytes();  //[-28, -72, -83, -27, -101, -67]//byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
//        byte[] bys = s.getBytes("UTF-8");  //[-28, -72, -83, -27, -101, -67]byte[] bys = s.getBytes("GBK");  //[-42, -48, -71, -6]System.out.println(Arrays.toString(bys));//String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
//        String ss = new String(bys);//String(byte[] bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
//        String ss = new String(bys, "UTF-8");String ss = new String(bys, "GBK");  //涓浗,因为编码的时候使用的是UTF-8,解码也得需要UTF-8来解码(这里是GBK解码的)System.out.println(ss);}
}

3.4 字符流中的编码解码问题(myCharStream中的com.itheima_02中的ConversionStreamDemo)

字符流抽象基类

  • Reader:字符输入流的抽象类
  • Writer:字符输出流的抽象类

字符流中和编码解码问题相关的两个类:

  • InputStreamReader (字符输入流)
  • OutputStreamWriter (字符输出流)

输出 写 一个空的
输入 读 一个有内容的

package com.itheima_02;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;/*InputStreamReader:是从字节流转到字符流的桥梁它读取字节,并使用指定的编码解码为字符它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集OutputStreamWriter:是从字符流到字节流的桥梁是从字符流到字节流的桥梁,使用指定的编码将写入的字符 编码为字节它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集*/
public class ConversionStreamDemo {public static void main(String[] args) throws IOException {//字符流输出流
//        OutputStreamWriter(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。
//        OutputStreamWriter(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。//        FileOutputStream fos = new FileOutputStream("myCharStream\\osw.txt");
//        OutputStreamWriter osw = new OutputStreamWriter(fos);  //创建字符输出流对象//        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));  //这里采用的是默认字符编码来做的//        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"), "UTF-8");//这里采用的是UTF-8字符编码来做的OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"), "GBK");//这里采用的是GBK字符编码来做的osw.write("中国");osw.close();//字符流输入流
//        InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。
//        InputStreamReader(InputStream in, String charsetName) 创建一个使用命名字符集的InputStreamReader。//        InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"));//这里采用的是默认字符编码来做的InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"), "GBK");//这里指定我们的GBK//一次读取一个字符数据(还有一次读取一个字符数组的方式)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.print(new String(chs, 0, len));   // 这里没有ln,new String 解码}isr.close();}
}

3.5 字符流写数据的5种方式(myCharStream中的com.itheima_02中的OutputStreamWriterDemo)

方法名 说明
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) 写一个字符串的一部分
方法名 说明
flush() 刷新流,还可以继续写数据
close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
package com.itheima_02;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;/*构造方法:OutputStreamWriter (OutputStream out):创建一个使用默认字符编码的OutputStreamWriter写数据的5种方式: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):写一个字符串的一部分*/
public class OutputStreamWriterDemo {public static void main(String[] args) throws IOException {//创建字符输出流对象//OutputStreamWriter (OutputStream out):创建一个使用默认字符编码的OutputStreamWriterOutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw1.txt"));//写数据//void write (int c):写一个字符
//        osw.write(97);
//        //从文件里面没有数据,因为这个地方采用的是字符流写数据,而字符流写数据并不能直接写到这个文件里面来,因为它最终要通过这个字节流去写的,
//        //所以它现在还在缓冲区里面呢。我们怎么让这个数据进到这个文件里面来呢?在这个字符输出流里面有一个方法叫flush(),刷新流
//
//        //void flush() 刷新流。
//        osw.flush();
//
//        osw.write(98);
//        osw.flush();
//
//        osw.write(99);//void write (char[] cbuf):写入一个字符数组char[] chs = {'a', 'b', 'c', 'd', 'e'};
//        osw.write(chs);//void write (char[] cbuf, int off, int len):写入字符数组的一部分
//        osw.write(chs, 0, chs.length);
//        osw.write(chs, 1, 3);     // bcd//void write (String str):写一个字符串
//        osw.write("abcdef");//void write (String str, int off, int len):写一个字符串的一部分
//        osw.write("abcdefg", 0, "abcdefg".length());osw.write("abcdefg", 1, 3);     // bcd//释放资源osw.close();
//        osw.write(100);  //当我们释放资源的close()方法一旦调用,就不能再往里面写数据了//它和flush()方法的区别在于,flush()方法仅仅刷新我们留的缓冲,刷新完之后还可以继续写数据,// 而我们的close()方法,它是先刷新缓冲,然后再去释放资源,释放完资源之后我们是不能再继续写数据的}
}

3.6 字符流读数据的2种方式(myCharStream中的com.itheima_02中的InputStreamReaderDemo)

方法名 说明
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据

一次读一个字符数组数据最后输出有点难度

package com.itheima_02;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*构造方法:InputStreamReader (InputStream in):创建一个使用默认字符集的InputStreamReader读数据的2种方式:int read ():一次读一个字符数据int read (char[] cbuf):一次读一个字符数组*/
public class InputStreamReaderDemo {public static void main(String[] args) throws IOException {//InputStreamReader (InputStream in):创建一个使用默认字符集的InputStreamReader
//        InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw2.txt"));InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\ConversionStreamDemo.java"));//int read ():一次读一个字符数据
//        int ch;
//        while ((ch = isr.read()) != -1) {//            System.out.print((char)ch);
//        }//int read (char[] cbuf):一次读一个字符数组char[] chs = new char[1024];int len;while ((len = isr.read(chs)) != -1) {System.out.print(new String(chs, 0, len));}//释放资源isr.close();}
}

案例:复制Java文件(myCharStream中的com.itheima_03中的CopyJavaDemo01)

需求:把模块目录下的“ConversionStreamDemo.java”复制到模块目录下的“Copy.java”

思路:

1:根据数据源创建字符输入流对象

2:根据目的地创建字符输出流对象

3:读写数据,复制文件

4:释放资源

package com.itheima_03;import java.io.*;/*需求:把模块目录下的ConversionStreamDemo.java复制到模块目录下的Copy.java思路:1:根据数据源创建字符输入流对象2:根据目的地创建字符输出流对象3:读写数据,复制文件4:释放资源*/
public class CopyJavaDemo01 {public static void main(String[] args) throws IOException {//根据数据源创建字符输入流对象InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\ConversionStreamDemo.java"));//根据目的地创建字符输出流对象OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\copy.java"));//读写数据,复制文件//一次读写一个字符数据
//        int ch;
//        while ((ch = isr.read()) != -1) {//            osw.write((char)ch);  // 这里前面有个(char)ch
//        }//一次读写一个字符数组数据char[] chs = new char[1024];int len;while ((len = isr.read(chs)) != -1) {osw.write(chs, 0, len);}//释放资源osw.close();isr.close();}
}

案例:复制Java文件(改进版)(myCharStream中的com.itheima_03中的CopyJavaDemo02)

需求:把模块目录下的“ConversionStreamDemo.java”复制到模块目录下的“Copy.java”

分析:

1:转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类

2:FileReader:用于读取字符文件的便捷类

FileReader(String fileName)

3:FileWriter:用于写入字符文件的便捷类

FileWriter(String fileName)

4:数据源和目的地分析

数据源:myCharStream\ConversionStreamDemo.java—读数据—Reader—InputStreamReader—FileReader

目的地:myCharStream\Copy.java—写数据—Writer—OutputStreamWriter—FileWriter

思路:

1:根据数据源创建字符输入流对象

2:根据目的地创建字符输出流对象

3:读写数据,复制文件

4:释放资源

package com.itheima_03;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;/*需求:把模块目录下的ConversionStreamDemo.java复制到模块目录下的copy02.java数据源和目的地分析数据源:myCharStream\\ConversionStreamDemo.java---读数据---Reader---InputStreamReader---FileReader目的地:myCharStream\\Copy.java---写数据---Writer---OutputStreamWriter---FileWriter思路:1:根据数据源创建字符输入流对象2:根据目的地创建字符输出流对象3:读写数据,复制文件4:释放资源*/
public class CopyJavaDemo02 {public static void main(String[] args) throws IOException {//根据数据源创建字符输入流对象FileReader fr = new FileReader("myCharStream\\ConversionStreamDemo.java");//根据目的地创建字符输出流对象FileWriter fw = new FileWriter("myCharStream\\copy02");//读写数据,复制文件//一次读写一个字符数据
//        int ch;
//        while ((ch = fr.read()) != -1) {//            fw.write((char)ch);
//        }//一次读写一个字符数组数据char[] chs = new char[1024];int len;while ((len = fr.read(chs)) != -1) {fw.write(chs, 0, len);}//释放资源fw.close();fr.close();}
}

3.7 字符缓冲流(myCharStream中的com.itheima_04中的BufferedStreamDemo01)

字符缓冲流:

  • BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
  • BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途

构造方法:

  • BufferedWriter(Writer out)
  • BufferedReader(Reader in)

System.out.print(new String(chs, 0, len));

package com.itheima_04;import java.io.*;
import java.lang.reflect.Array;/*字符缓冲流:BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途构造方法:BufferedWriter(Writer out)BufferedReader(Reader in)*/
public class BufferedStreamDemo01 {public static void main(String[] args) throws IOException {//BufferedWriter(Writer out)
//        FileWriter fw = new FileWriter("myCharStream\\bw.txt");
//        BufferedWriter bw = new BufferedWriter(fw);//        BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
//
//        bw.write("hello\r\n");
//        bw.write("world\r\n");
//        bw.write("java\r\n");
//
//        bw.close();//BufferedReader(Reader in)BufferedReader br = new BufferedReader(new FileReader("myCharStream\\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();}
}

案例:复制Java文件(字符缓冲流改进版)(myCharStream中的com.itheima_04中的CopyJavaDemo01)

需求:把模块目录下的“ConversionStreamDemo.java”复制到模块目录下的“Copy.java”

思路:

1:根据数据源创建字符缓冲输入流对象

2:根据目的地创建字符缓冲输出流对象

3:读写数据,复制文件

4:释放资源

package com.itheima_04;import java.io.*;/*需求:把模块目录下的ConversionStreamDemo.java复制到模块目录下的Copy01.java思路:1:根据数据源创建字符缓冲输入流对象2:根据目的地创建字符缓冲输出流对象3:读写数据,复制文件4:释放资源*/
public class CopyJavaDemo01 {public static void main(String[] args) throws IOException {//根据数据源创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("myCharStream\\ConversionStreamDemo.java"));//根据目的地创建字符缓冲输出流BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy01.java"));//读写数据,复制文件//一次读写一个字符数据
//        int ch;
//        while ((ch = br.read()) != -1) {//            bw.write(ch);
//        }//一次读写一个字符数组数据char[] chs = new char[1024];int len;while ((len = br.read(chs)) != -1) {bw.write(chs, 0, len);}//释放资源bw.close();br.close();}
}

3.8 字符缓冲流特有功能

BufferedWriter:

  • void newLine():写一行(个)
  • 行分隔符 ,行分隔符字符串由系统属性定义

BufferedReader:

  • public String readLine():读一行文字。结果包含行的内容的字符串,不包括任何行终止字符(不包括换行符号的),如果流的结尾已经到达,则为null

案例:复制Java文件(字符缓冲流特有功能改进版)(myCharStream中的com.itheima_04中的CopyJavaDemo02)

需求:把模块目录下的“ConversionStreamDemo.java”复制到模块目录下的“Copy02.java”

思路:

1:根据数据源创建字符缓冲输入流对象

2:根据目的地创建字符缓冲输出流对象

3:读写数据,复制文件

使用字符缓冲流特有功能实现

4:释放资源

package com.itheima_04;import java.io.*;/*需求:把模块目录下的ConversionsStreamDemo.java复制到模块目录下的Copy02.java思路:1:根据数据源创建字符缓冲输入流对象2:根据目的地创建字符缓冲输出流对象3:读写数据,复制文件使用字符缓冲流特有功能实现4:释放资源*/
public class CopyJavaDemo02 {public static void main(String[] args) throws IOException {//根据数据源创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("myCharStream\\ConversionStreamDemo.java"));//根据目的地创建字符缓冲输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy02.java"));//读写数据,复制文件//使用字符缓冲流特有功能实现String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine();bw.flush();}//释放资源br.close();bw.close();}
}

3.9 IO流小结(有总结图示)

小结:字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能


小结:字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能

案例:集合到文件(myCharStream中的com.itheima_05中的ArrayListToTxtDemo)

思路:

1:创建ArrayList集合

2:往集合中存储字符串元素

3:创建字符缓冲输出流对象

4:遍历集合,得到每一个字符串数据

5:调用字符缓冲输出流对象的方法写数据

6:释放资源

package com.itheima_05;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;/*需求:把ArrayList集合中的字符串数据写入到文本文件。要求:每一个字符串元素作为文件中的一行数据思路:1:创建ArrayList集合2:往集合中存储字符串元素3:创建字符缓冲输出流对象4:遍历集合,得到每一个字符串数据5:调用字符缓冲输出流对象的方法写数据6:释放资源*/
public class ArrayListToTxtDemo {public static void main(String[] args) throws IOException {//创建ArrayList集合ArrayList<String> array = new ArrayList<String>();//往集合中存储字符串元素array.add("hello");array.add("world");array.add("java");//创建字符缓冲输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\array.txt"));//遍历集合,得到每一个字符串数据for (String s : array) {//调用字符缓冲输出流对象的方法写数据bw.write(s);bw.newLine();bw.flush();}//释放资源bw.close();}
}

案例:文件到集合(myCharStream中的com.itheima_05中的TxtToArrayListDemo)

需求:把文本文件中的数据读取到集合中,并遍历集合。要求:文件中的每一行数据是一个集合元素

思路:

1:创建字符缓冲输入流对象

2:创建ArrayList集合对象

3:调用字符缓冲输入流对象的方法读数据

4:把读取到的字符串数据存储到集合中

5:释放资源

6:遍历集合

package com.itheima_05;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;/*需求:把文本文件中的数据读取到集合中,并遍历集合。要求:文件中的每一行数据是一个集合元素思路:1:创建字符缓冲输入流对象2:创建ArrayList集合对象3:调用字符缓冲输入流对象的方法读数据4:把读取到的字符串数据存储到集合中5:释放资源6:遍历集合*/
public class TxtToArrayListDemo {public static void main(String[] args) throws IOException {//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("myCharStream\\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);}}
}

案例:点名器(myCharStream中的com.itheima_05中的CallNameDemo)(想当于文件到集合)

需求:我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随机点名器

思路:

1:创建字符缓冲输入流对象

2:创建ArrayList集合对象

3:调用字符缓冲输入流对象的方法读数据

4:把读取到的字符串数据存储到集合中

5:释放资源

6:使用Random产生一个随机数,随机数的范围在:[0, 集合的长度)

7:把第6步产生的随机数作为索引到ArrayList集合中获取值

8:把第7步得到的数据输出在控制台

package com.itheima_05;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;/*需求:我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随机点名器思路:1:创建字符缓冲输入流对象2:创建ArrayList集合对象3:调用字符缓冲输入流对象的方法读数据4:把读取到的字符串存储到集合中5:释放资源6:使用Random产生一个随机数,随机数的范围在:[0, 集合的长度)7:把第6步产生的随机数作为索引到ArrayList集合中获取值8:把第7步得到的数据输出在控制台*/
public class CallNameDemo {public static void main(String[] args) throws IOException {//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("myCharStream\\name.txt"));//创建ArrayList集合对象ArrayList<String> array = new ArrayList<String>();//调用字符缓冲输入流对象的方法读数据String line;while ((line = br.readLine()) != null) {//把读取到的字符串存储到集合中array.add(line);}//释放资源br.close();//使用Random产生一个随机数,随机数的范围在:[0, 集合的长度)Random r = new Random();int index = r.nextInt(array.size());//把第6步产生的随机数作为索引到ArrayList集合中获取值String name = array.get(index);//把第7步得到的数据输出在控制台System.out.println("幸运者是:" + name);}
}

案例:集合到文件(改进版)(myCharStream中的com.itheima_06中的ArrayListToFileDemo、Student)

需求:把ArrayList集合中的学生数据写入到文本文件。要求:每一个学生对象的数据作为文件中的一行数据

格式:学号,姓名,居住地

举例:itheima001,林青霞,30,西安

思路:

1:定义学生类

2:创建ArrayList集合

3:创建学生对象

4:把学生对象添加到集合中

5:创建字符缓冲输出流对象

6:遍历集合,得到每一个学生对象

7:把学生对象的数据拼接成指定格式的字符串

8:调用字符缓冲输出流对象的方法写数据

9:释放资源

package com.itheima_06;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 void setSid(String sid) {this.sid = sid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}
package com.itheima_06;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;/*需求:把ArrayList集合中学生数据写入到文本文件。要求:每一个学生对象的数据作为文件中的每一行数据格式:学号,姓名,年龄,居住地举例:itheima001,林青霞,30,西安思路:1:定义学生类2:创建Arraylist集合3:创建学生对象4:把学生对象添加到集合5:创建字符缓冲输出流对象6:遍历集合7:把学生对象的数据拼接成指定格式的字符串8:调用字符缓冲输出流对象的方法写数据9:释放资源*/
public class ArrayListToFileDemo {public static void main(String[] args) throws IOException {//创建ArrayList集合ArrayList<Student> array = new ArrayList<Student>();//创建学生对象Student s1 = new Student("itheima001", "林青霞", 30, "西安");Student s2 = new Student("itheima002", "张曼玉", 35, "武汉");Student s3 = new Student("itheima003", "王祖贤", 33, "郑州");//把学生对象添加到集合array.add(s1);array.add(s2);array.add(s3);//创建字符缓冲输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\student.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();}
}

案例:文件到集合(改进版)(myCharStream中的com.itheima_06中的FileToArrrayListDemo)

需求:把文本文件的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个学生对象的成员变量值

举例:itheima001,林青霞,30,西安

思路:

1:定义学生类

2:创建字符缓冲输入流

3:创建ArrayList集合对象

4:调用字符缓冲输入流对象的方法读数据

5:把读取到的字符串数据用split()进行分割,得到一个字符串数组

6:创建学生对象

7:把字符串数组中的每一个元素取出来对应的赋值给学生对象的成员变量值

8:把学生对象添加到集合

9:释放资源

10:遍历集合

package com.itheima_06;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 void setSid(String sid) {this.sid = sid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}
package com.itheima_06;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;/*需求:把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个学生对象的成员变量值举例:itheima001,林青霞,30,西安思路:1:定义学生类2:创建字符缓冲输入流对象3:创建ArrayList集合对象4:调用字符缓冲输入流对象的方法读数据5:把读取到的字符串数据用split()进行分割,得到每一个字符串数组6:创建学生对象7:把字符串数组中的每一个元素取出来对应的赋值给学生对象的成员变量值8:把学生对象添加到集合9:释放资源10:遍历集合*/
public class FileToArrayListDemo {public static void main(String[] args) throws IOException {//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("myCharStream\\student.txt"));//创建ArrayList集合对象ArrayList<Student> array = new ArrayList<Student>();//调用字符缓冲输入流对象的方法读数据String line;while ((line = br.readLine()) != null) {//把读取到的字符串数据用split()进行分割,得到一个字符串数组String[] strArray = line.split(",");//创建学生对象Student s = new Student();//把字符串数组中的每一个元素取出来对应的赋值给学生对象的的成员变量值//itheima001,林青霞,30,西安s.setSid(strArray[0]);s.setName(strArray[1]);s.setAge(Integer.parseInt(strArray[2]));         //靠,这里之前报送是因为Student类中set方法里面没有传参数s.setAddress(strArray[3]);//把学生对象添加到集合array.add(s);}//释放资源br.close();      //之前把下面这现场放在while循环里面了,难道提示s已经被定义了,下面可以定义s一样的//遍历集合for (Student s : array) {System.out.println(s.getSid() + "," + s.getName() + "," + s.getAge() + "," + s.getAddress());//student文本文件中的逗号只是用来分割成集合字符串,所以这里需要重新加逗号进行分割}}
}

案例:集合到文件(数据排序改进版)(myCharStream中的com.itheima_07中的Student、TreeSetToFileDemo)

需求:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)。要求按照成绩总分从高到低写入文本文件

格式:姓名,语文成绩,数学成绩,英语成绩

举例:林青霞,98,99,100

思路:

1: 定义学生类

2:创建TreeSet集合,通过比较器排序进行排序

3:键盘录入学生数据

4:创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量

5:把学生对象添加到TreeSet集合

6:创建字符缓冲输出流对象

7:遍历集合,得到每一个学生对象

8:把学生对象的数据拼接成指定格式的字符串

9:调用字符缓冲输出流对象的方法写数据

10:释放资源

package com.itheima_07;/*学生类*/
public class Student {//姓名private String name;//语文成绩private int chinese;//数学成绩private int math;//英语成绩private int english;public Student() {}public Student(String name, int chinese, int math, int english) {super();this.name = name;this.chinese = chinese;this.math = math;this.english = 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;}
}
package com.itheima_07;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;/*需求:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)。要求按照成绩总分从高到低写入文本文件格式:姓名,语文成绩,数学成绩,英语成绩举例:林青霞,98,99,100思路:1:定义学生类2:创建TreeSet集合,通过比较器排序进行排序3:键盘录入学生数据4:创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量5:把学生对象添加到TreeSet集合6:创建字符缓冲输出流对象7:遍历集合,得到每一个学生对象8:把学生对象的数据拼接成指定格式的字符串9:调用字符缓冲输出流对象的方法写数据10:释放资源*/
public class TreeSetToFileDemo {public static void main(String[] args) throws IOException {//创建TreeSet集合,通过比较器排序进行排序TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {//成绩总分从高到低int num = s2.getSum() - s1.getSum();//次要条件int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;int num4 = num3 == 0 ? s1.getName().compareTo(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();//创建学生对象,把键盘录入的数据对应给学生对象的成员变量Student s = new Student();s.setName(name);s.setChinese(chinese);s.setMath(math);s.setEnglish(english);//把学生对象添加到TreeSet集合ts.add(s);}//创建字符缓冲输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\ts.txt"));//遍历集合,得到每一个学生对象for (Student 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();}
}

案例:复制单级文件夹(myCharStream中的com.itheima_08中的CopyFolderDemo)

需求:把“D:\itcasttt”这个文件夹复制到模块目录下

思路:

1:创建数据源目录File对象,路径是D:\itcasttt

2:获取数据源目录File对象的名称(itcasttt)

3:创建目的地目录File对象,路径名是模块名+itcasttt组成(myCharStream\itcasttt)

4:判断目的地目录对应的File是否存在,如果不存在,就创建

5:获取数据源目录下所有的文件的File数组

6:遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件

数据源文件:D:\itcasttt\mn.jpg

7:获取数据源文件File对象的名称(mn.jpg)

8:创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharStream\itcasttt\mn.jpg)

9:复制文件

由于文件不仅仅是文本文件,还有图片,视频等文件,所以采用字节流复制文件

package com.itheima_08;import java.io.*;/*需求:把D:\\itcasttt这个文件夹复制到模块目录下思路:1:创建数据源目录File对象,路径是D:\\itcasttt2:获取数据源目录File对象的名称(itcast)3:创建目的地目录File对象,路径名是模块名+itcasttt组成(myCharStream\\itcasttt)4:判断目的地目录对应的File是否存在,如果不存在,就创建5:获取数据源目录下所有文件的File对象6:遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件数据源文件:D:\\itcasttt\\mn.jpg7:获取数据源文件File对象的名称(mn.jpg)8:创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharmStream\\itcastt\\mn.jpg)9:复制文件由于文件不仅仅是文本文件,还有图片,视频等文件,所以采用字节流复制文件*/
public class CopyFolderDemo {public static void main(String[] args) throws IOException {//创建数据源目录File对象,路径是D:\\itcastttFile srcFolder = new File("D:\\itcasttt");//获取数据源目录File对象的名称(itcasttt)String srcFolderName = srcFolder.getName();//创建目的地目录File对象,路径名是模块名+itcasttt组成(myCharStream\\itcasttt)File destFolder = new File("myCharStream", srcFolderName);//判断目的地目录对应的File是否存在,如果不存在,就创建if (!destFolder.exists()) {destFolder.mkdir();}//获取数据源目录下的所有文件的File对象File[] listFiles = srcFolder.listFiles();//遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件for (File srcFile : listFiles) {//数据源文件:D:\\itcasttt\\mn.jpg//获取数据源文件File对象的名称(mn.jpg)String srcFileName = srcFile.getName();//创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharStream\\itcasttt\\mn.jpg)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);}bos.close();bis.close();}}

案例:复制多级文件(myCharStream中的com.itheima_08中的CopyFoldersDemo)(自己可能写不出来,看讲解才能写出来)

需求:把“D:\itcastt”复制到C盘目录下

思路:

1:创建数据源File对象,路径是D:\itcastt

2:创建目的地File对象,路径是C:\

3:写方法实现文件夹的复制,参数为数据源File对象和目的地File对象

4:判断数据源是否是目录

是:

A:在目的地下创建和数据源File名称一样的目录

B:获取数据源File下所有文件或者目录的File数组

C:遍历该File数组,得到每一个File对象

D:把该File作为数据源File对象,递归调用复制文件夹的方法

不是:

说明是文件,直接复制,用字节流

package com.itheima_08;import java.io.*;/*需求:把“D:\\itcastt”复制到C盘目录下思路:1:创建数据源File对象,路径是D:\\itcastt2:创建目的地File对象,路径是C:\\3:写方法实现文件夹的复制,参数为数据源File对象和目的地File对象4:判断数据源File是否是目录是:A:在目的地下创建和数据源File名称一样的目录B:获取数据源File下所有文件或者目录的File数组C:遍历该File数组,得到每一个File对象D:把该File作为数据源File对象,递归调用复制文件夹的方法不是:说明是文件,直接复制,用字节流*/
public class CopyFoldersDemo {public static void main(String[] args) throws IOException {//创建数据源File对象,路径是D:\\itcasttFile srcFile = new File("D:\\itcastt");//创建目的地File对象,路径是C:\\File destFile = new File("C:\\");//写方法实现文件夹的复制,参数为数换源File对象和目的地File对象copyFolder(srcFile, destFile);}//复制文件夹的private static void copyFolder(File srcFile, File destFile) throws IOException {//判断数据源File是否是目录if (srcFile.isDirectory()) {//在目的地下创建和数据源File名称一样的目录String srcFileName = srcFile.getName();File newFolder = new File(destFile, srcFileName);  //C:\\itcasttif (!newFolder.exists()) {newFolder.mkdir();}//获取数据源File下所有文件或者目录的File数组File[] fileArray = srcFile.listFiles();//遍历该File数组,得到每一个File对象for (File file : fileArray) {  //这里file可能是文件,也可能是文件夹//把该File作为数据源File对象,递归调用复制文件夹的方法copyFolder(file, newFolder);}} else {//不是:说明是文件,直接复制,用字节流File newFile = new File(destFile, srcFile.getName());copyFile(srcFile, newFile);}}//字节缓冲流复制文件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);}bos.close();bis.close();}
}

3.10 复制文件的异常处理(myCharStream中的com.itheima_09中的CopyFileDemo)

直接抛出处理

try…catch…finally的做法:

 try {可能出现异常的代码;
} catch (异常类名 变量名) {异常的处理代码;
} finally {执行所有清除操作;
}

JDK7改进方案:

try(定义流对象) {可能出现异常的代码;
} catch (异常类名 变量名) {异常的处理代码;
}自动释放资源

JDK9改进方案:

定义输入流对象;
定义输出流对象;
try (输入流对象; 输出流对象) {可能出现异常的代码;
} catch (异常类名 变量名) {异常的处理代码;
}自动释放资源
package com.itheima_09;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;/*复制文件加入异常处理*/
public class CopyFileDemo {public static void main(String[] args) {}//JDK9的改进方案private static void method4() throws IOException {FileReader fr = new FileReader("fr.txt");FileWriter fw = new FileWriter("fw.txt");try (fr ; fw) {char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}} catch (IOException e) {e.printStackTrace();}}//JDK7的改进方案private static void method3() {try (FileReader fr = new FileReader("fr.txt");FileWriter fw = new FileWriter("fw.txt");) {char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}} catch (IOException e) {e.printStackTrace();}}//try...catch...finallyprivate static void method2() {FileReader fr = null;FileWriter fw = null;try {fr = new FileReader("fr.txt");fw = new FileWriter("fw.txt");char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}} catch (IOException e) {e.printStackTrace();} finally {if (fw != null) {try {fw.close();} catch (IOException e) {e.printStackTrace();}}if (fr != null) {try {fr.close();} catch (IOException e) {e.printStackTrace();}}}}//抛出处理private static void method1() throws IOException {FileReader fr = new FileReader("fr.txt");FileWriter fw = new FileWriter("fw.txt");char[] chs = new char[1024];int len;while ((len = fr.read()) != -1) {fw.write(chs, 0, len);}fw.close();fr.close();}
}

4. 特殊操作流

4.1 标准输入输出流

System类中有两个静态的成员变量:

  • public static final InputStream in标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
  • public static final PrintStream out标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标

4.1.1 标准输入流(myOtherStream中的com.itheima_01中的SystemInDemo)

自己实现键盘录入数据:

  • BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

写起来太麻烦,Java就提供了一个类实现键盘录入

  • Scanner sc = new Scanner(System.in);
package com.itheima_01;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;/*public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源*/
public class SystemInDemo {public static void main(String[] args) throws IOException {//public static final InputStream in:标准输入流
//        InputStream is = System.in;  // 这里是把System类中的成员变量in,赋值给is?//字节流读数据,一个字节一个字节读的,输入一个“中”,UTF-8规则,有三个字节输出
//        int by;
//        while ((by = is.read()) != -1) {//            System.out.print((char)by);
//        }//如何把字节流转换为字符流?用转换流
//        InputStreamReader isr = new InputStreamReader(is);
//        //使用字符流能不能够实现一次读取一行数据呢?可以
//        //但是,一次读取一行数据的方法是字符缓冲输入流的特有方法
//        BufferedReader br = new BufferedReader(isr);BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 标准输入流转为字符输入流转为字符缓冲输入流,再使用特有方法System.out.println("请输入一个字符串:");String line = br.readLine();System.out.println("你输入的字符串是:" + line);System.out.println("请输入一个整数:");int i = Integer.parseInt(br.readLine());System.out.println("你输入的整数是:" + i);//自己实现键盘录入数据太麻烦了,所以就提供了一个类供我们使用Scanner sc = new Scanner(System.in);}
}

4.1.2 标准输出流(myOtherStream中的com.itheima_01中的SystemOutDemo)

输出语句的本质:是一个标准的输出流

  • PrintStream ps = System.out;
  • PrintStream类有的方法,System.out都可以使用
package com.itheima_01;import java.io.PrintStream;/*public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标*/
public class SystemOutDemo {public static void main(String[] args) {//public static final PrintStream out:标准输出流PrintStream ps = System.out; // 这里是把System类中的成员变量out,赋值给ps?创建对象?//能够方便地打印各种数据值
//        ps.print("hello");
//        ps.print(100);//        ps.println("hello");
//        ps.println(100);//System.out的本质是一个字节输出流(PrintStream ps = System.out)System.out.println("hello");System.out.println(100);System.out.println();
//        System.out.print();  //如果PrintStream类中没有的方法,System.out是不能使用的,所以print()方法要有参数}
}

4.2 打印流

打印流分类:

  • 字节打印流:PrintStream
  • 字符打印流:PrintWriter

打印流的特点:

  • 只负责输出数据,不负责读取数据
  • 有自己的特有方法

4.2.1 字节打印流(myOtherStream中的com.itheima_02中的PrintStreamDemo)

  • PrintSteam(String fileName):使用指定的文件名创建新的打印流(构造方法)
  • 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
package com.itheima_02;import java.io.IOException;
import java.io.PrintStream;/*打印流的特点:只负责输出数据,不负责读取数据有自己的特有方法字节打印流PrintStream (String fileName):使用指定的文件名创建新的打印流*/
public class PrintStreamDemo {public static void main(String[] args) throws IOException {//printStream (String fileName):使用指定的文件名创建新的打印流PrintStream ps = new PrintStream("myOtherStream\\ps.txt");//写数据//字节输出流有的方法
//        ps.write(97);  //这里输出的是a//使用特有方法来写数据
//        ps.print(97);  //这里输出的就是97。使用特有的方法去写数据的时候,不会做这个转码操作的
//        ps.println();
//        ps.print(98);ps.println(97);ps.println(98);//释放资源ps.close();}
}

4.2.2 字符打印流(myOtherStream中的com.itheima_02中的PrintWriterDemo)

字符打印流PrintWriter的构造方法:

方法名 说明
PrintWriter(String fileName) 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新
PrintWriter(Writer out, boolean autoFlush) 创建一个新的PrintWriter out:字符输出流 autoFlush:一个布尔值,如果为真,则println,printf,或format方法将刷新输出缓冲区
package com.itheima_02;import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;/*字符打印流的构造方法:PrintWriter (String fileName):使用指定的文件名创建一个新的printWriter,而不需要自动执行行刷新PrintWriter (Writer out, boolean autoFlush):创建一个新的PrintWriterout:字符输出流autoFlush:一个布尔值,如果为真,则println,printf,或format方法将刷新输出缓冲区*/
public class PrintWriterDemo {public static void main(String[] args) throws IOException {//PrintWriter (String fileName):使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新
//        PrintWriter pw = new PrintWriter("myOtherStream\\pw.txt");//        pw.write("hello");
//        pw.write("\r\n");
//        pw.flush();   需要手动行刷新
//
//        pw.write("world");
//        pw.write("\r\n");
//        pw.flush();//        pw.println("hello");
//        /*
//            pw.write("hello");
//            pw.write("\r\n");
//         */
//        pw.flush();
//
//        pw.println("world");
//        pw.flush();//PrintWriter (Writer out, boolean autoFlush):创建一个新的PrintWriterPrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"), true);
//        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"), false);pw.println("hello");/*pw.write("hello");pw.write("\r\n");pw.flush();*/pw.println("world");pw.close();}
}

案例:复制Java文件(打印流改进版)(myOtherStream中的com.itheima_02中的CopyJavaDemo)

需求:把模块目录下的PrintStreamDemo.java复制到模块目录下的Copy.java

思路:

1:根据数据源创建字符输入流对象

2:根据目的地创建字符输出流对象

3:读写数据,复制文件

4:释放资源

package com.itheima_02;import java.io.*;/*需求:把模块目录下的PrintStreamDemo.java复制到模块目录下的Copy.java思路:1:根据数据源创建字符输入流对象2:根据目的地创建字符输出流对象3:读写数据,复制文件4:释放资源*/
public class CopyJavaDemo {public static void main(String[] args) throws IOException {/*//字符缓冲输入流//根据数据源创建字符输入流对象BufferedReader br = new BufferedReader(new FileReader("myOtherStream\\PrintStreamDemo.java"));//根据目的地创建字符输出流对象BufferedWriter bw = new BufferedWriter(new FileWriter("myOtherStream\\Copy.java"));//读写数据String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine();bw.flush();}//释放资源bw.close();bw.close();*///使用字符打印流改进//根据数据源创建字符输入流对象BufferedReader br = new BufferedReader(new FileReader("myOtherStream\\PrintStreamDemo.java"));//根据目的地创建字符输出流对象PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\Copy.java"), true);//读写数据,复制文件String line;while ((line = br.readLine()) != null) {pw.println(line);}//释放资源pw.close();br.close();}
}

4.3 对象序列化流

对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象

这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息

字节序列写到文件之后,相当于文件中持久保存了一个对象的信息

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:

  • 对象序列化流:ObjectOutputStream
  • 对象反序列化流:ObjectInputStream

4.3.1 对象序列化流(myOtherStream中的com.itheima_03中的ObjectOutputStreamDemo)

对象序列化流:ObjectOutputStream

  • 将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。

如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象

构造方法:

  • ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法:

  • void writeObject(Object obj):将指定的对象写入ObjectOutputStream

注意:

  • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable接口
  • Serializable是一个标记接口,实现该接口,不需要重写任何方法
package com.itheima_03;import java.io.Serializable;public class Student implements Serializable {private static final long serialVersionUID = 42L;private String name;
//    private int age;private transient int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}//    @Override
//    public String toString() {//        return "Student{" +
//                "name='" + name + '\'' +
//                ", age=" + age +
//                '}';
//    }
}
package com.itheima_03;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;/*对象序列化流:构造方法:ObjectOutputStream (OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream序列化对象的方法:void writeObject (Object obj):将指定的对象写入ObjectOutputStreamNotSerializableException:抛出一个实例需要一个Serializable接口。 序列化运行时或实例的类可能会抛出此异常类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。只是一个标识,不需要重写这个接口里面的方法,只要明白这是对象序列化或者对象反序列的标识就可以了*/
public class ObjectOutputStreamDemo {public static void main(String[] args) throws IOException {//ObjectOutputStream (OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStreamObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));//创建对象Student s = new Student("林青霞", 30);//void writeObject (Object obj):将指定的对象写入ObjectOutputStreamoos.writeObject(s);//释放资源oos.close();}
}

4.3.2 对象反序列化流(myOtherStream中的com.itheima_03中的ObjectInputStreamDemo)

对象反序列化流:ObjectInputStream

  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象

构造方法:

  • ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法:

  • Object readObject():从ObjectInputStream读取一个对象
package com.itheima_03;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;/*构造方法:ObjectInputStream (InputStream in):创建从指定的InputStream读取的ObjectInputStream反序列化对象的方法:Object readObject ():从ObjectInputStream读取一个对象*/
public class ObjectInputStreamDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {//ObjectInputStream (InputStream in):创建从指定的InputStream读取的ObjectInputStreamObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));//Object readObject ():从ObjectInputStream读取一个对象Object obj = ois.readObject();Student s = (Student) obj;System.out.println(s.getName() + "," + s.getAge());ois.close();}
}

4.3.3 对象序列化流中的三个问题(myOtherStream中的com.itheima_03中的ObjectStreamDemo)

用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

  • 会出问题,抛出InvalidClassException异常

如果出问题了,如何解决呢?

  • 给对象所属的类加一个serialVersionUID

private static final long serialVersionUID = 42L;

如果一个对象中的某个成员变量的值还想序列化,又该如何实现呢?

  • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
package com.itheima_03;import java.io.Serializable;public class Student implements Serializable {private static final long serialVersionUID = 42L;private String name;
//    private int age;private transient int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}//    @Override
//    public String toString() {//        return "Student{" +
//                "name='" + name + '\'' +
//                ", age=" + age +
//                '}';
//    }
}
package com.itheima_03;import java.io.*;/*用对象序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?java.io.InvalidClassException:当序列化运行时检测到类中的以下问题之一时抛出。类的串行版本与从流中读取的类描述符的类型不匹配该类包含未知的数据类型该类没有可访问的无参数构造函数com.itheima_03.Student; local class incompatible:stream classdesc serialVersionUID = -3743788623620386195,local class serialVersionUID = -247282590948908173如果出问题了,如何解决呢?给这个所属的类加一个值:private static final long serialVersionUID = 42L大概意思就是:在学生类中先添加这个值,然后写出去到文件,然后从文件读进来,这样类的值是这个,因为刚刚写出去文件也是这个值,所以现在再去改变学生类中的东西,也只可以直接再从这个文件读进来如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?不想被序列化就是不想输出到文件,也就是说文件里只有名字private transient int age;  用transient关键字修饰,就不会参与对象序列化了。在这里age默认值是0,所以输出为0*/
public class ObjectStreamDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {//        write();read();}//反序列化private static void read() throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));Object obj = ois.readObject();Student s = (Student) obj;System.out.println(s.getName() + "," + s.getAge());ois.close();}//序列化private static void write() throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));Student s = new Student ("林青霞", 30);oos.writeObject(s);oos.close();}
}

4.4 Properties

Properties概述:

  • 是一个Map体系的集合类
  • Properties可以保存到流中或从流中加载

练习:Properties作为Map集合的使用(myOtherStream中的com.itheima_04中的PropertiesDemo01

package com.itheima_04;import java.util.Properties;
import java.util.Set;/*Properties作为Map集合的使用*/
public class PropertiesDemo01 {public static void main(String[] args) {//创建集合对象
//        Properties<String, String> prop = new Properties<String, String>();
//        错误,在这里是不能写这个泛型的,因为这个类不是一个泛型类。因为没有指定泛型,所以默认为Object类型的,
//        所以在下面键的集合是Object类型的,每个键是Object类型,每个值是Object类型Properties prop = new Properties();//存储元素prop.put("itheima001", "林青霞");prop.put("itheima002", "张曼玉");prop.put("itheima003", "王祖贤");//遍历集合Set<Object> keySet = prop.keySet();for (Object key : keySet) {Object value = prop.get(key);System.out.println(key + "," + value);}}
}

4.4.1 Properties作为集合的特有方法:(myOtherStream中的com.itheima_04中的PropertiesDemo02)

方法名 说明
Object setProperty(String key, String value) 设置集合的键和值,都是String类型,底层调用Hashtable方法put
String getProperty(String key) 使用此属性列表中指定的键搜索属性
Set< String> stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
package com.itheima_04;import java.util.Properties;
import java.util.Set;/*Properties作为集合的特有方法:Object setProperty(String key, String value):设置集合的键和值,都是String类型,底层调用Hashtable方法putString getProperty(String key):使用此属性列表中指定的键搜索属性Set<String> stringPropertyName():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串*/
public class PropertiesDemo02 {public static void main(String[] args) {//创建集合对象Properties prop = new Properties();//Object setProperty(String key, String value):设置集合的键和值,都是String类型,底层调用Hashtable方法putprop.setProperty("itheima001", "林青霞");/*Object setProperty(String key, String value) {return put(key, value);}Object put(Object key, Object value) {return map.put(key, value);}*/prop.setProperty("itheima002", "张曼玉");prop.setProperty("itheima003", "王祖贤");//String getProperty(String key):使用此属性列表中指定的键搜索属性
//        System.out.println(prop.getProperty("itheima001"));
//        System.out.println(prop.getProperty("itheima0011"));//        System.out.println(prop);//Set<String> stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串Set<String> names = prop.stringPropertyNames();for (String key : names) {//            System.out.println(key);String value = prop.getProperty(key);System.out.println(key + "," + value);}}
}

4.4.2 Properties和IO流结合的方法:(myOtherStream中的com.itheima_04中的PropertiesDemo03)

方法名 说明
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)方法的格式写入输出字符流
package com.itheima_04;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;/*Properties和IO流结合的方法void load(Reader reader):从输入字符流读取属性列表(键和元素对)void store(Writer writer, String comments):将此属性列表(键和元素对)写入此Properties表中,以适合使用load(Reader)方法的格式写入输出字符流*/
public class PropertiesDemo03 {public static void main(String[] args) throws IOException {//把集合中的数据保存到文件
//        myStore();//把文件中的数据加载到集合myLoad();}private static void myLoad() throws IOException{Properties prop = new Properties();//void load(Reader reader):FileReader fr = new FileReader("myOtherStream\\fw.txt");prop.load(fr);fr.close();System.out.println(prop);}private static void myStore() throws IOException {Properties prop = new Properties();prop.setProperty("itheima001", "林青霞");prop.setProperty("itheima002", "张曼玉");prop.setProperty("itheima003", "王祖贤");//void store(Writer writer, String comments):FileWriter fw = new FileWriter("myOtherStream\\fw.txt");prop.store(fw, "null");fw.close();}
}

案例:游戏次数(myOtherStream中的com.itheima_04中的PropertiesTest、GuessNumber、game.txt)

需求:请写程序实现猜数字小游戏,只能试玩3次,如果还想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)

思路:

1:写一个游戏类,里面有一个猜数字的小游戏

2:写一个测试类,测试类中有main()方法,main()方法中按照下面步骤完成:

A:从文件中读取数据到Properties集合,用load()方法实现

文件已经存在:game.txt

里面有一个数据值:count = 0

B:通过Properties集合获取到玩游戏的次数

C:判断次数是否到3次了

如果到了,给出提示:游戏试玩已结束,想玩请充值(www.itcast.cn)

如果不到3次:

玩游戏

次数+1,重新写回文件,用Properties()方法实现

package com.itheima_04;import java.util.Random;
import java.util.Scanner;/*猜数字小游戏*/
public class GuessNumber {private  GuessNumber() {}public static void start() {//要完成猜数字的游戏,产生需要有一个要猜的数字,使用随机数生成该数字,范围1到100Random r = new Random();int number = r.nextInt(100) + 1;while (true) {//使用程序实现猜数字,每次均要输入猜测的数字值,需要使用键盘录入实现Scanner sc = new Scanner(System.in);System.out.println("请输入你要猜的数字");int guessNumber = sc.nextInt();//比较输入的数字和系统产生的数据,需要使用分支语句。这里使用if...else...if...格式,根据不同情况进行猜测结果显示if (guessNumber > number) {System.out.println("你猜的数字" + guessNumber + "大了");} else if (guessNumber < number) {System.out.println("你猜的数字" + guessNumber + "小了");} else {System.out.println("恭喜你猜中了");break;}}}
}
package com.itheima_04;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;/*需求:请写程序实现猜数字小游戏只能试玩3次,如果还想玩,提示:游戏试玩结束,想玩请充值(www.itcast.cn)思路:1:写一个游戏类,里面有一个猜数字的小游戏、2:写一个测试类,测试类中有main()方法,main()方法中按照下面步骤完成A:从文件中读取数据到Properties集合,用load()方法实现文件已经存在:game.txt里面有一个数据值:count=0B:通过Properties集合获取到玩游戏的次数C:判断次数是否到3次了如果到了,给出提示:游戏试玩结束,想玩请充值(www.itcast.cn)如果不到3次:玩游戏次数+1,重新写回文件,用Properties的store()方法实现*/
public class PropertiesTest {public static void main(String[] args) throws IOException {//从文件中读取数据到Properties集合,用load()方法实现Properties prop = new Properties();FileReader fr = new FileReader("myOtherStream\\game.txt");prop.load(fr);fr.close();//通过Properties集合获取到玩游戏的次数String count = prop.getProperty("count");int number = Integer.parseInt(count);//判断次数是否到3次了if (number >= 3) {//如果到了,给出提示:游戏试玩已结束,想玩请充值(www.itcast.cn)System.out.println("游戏试玩已结束,想玩请充值(www.itcast.cn)");} else {//玩游戏GuessNumber.start();//次数+1,重新写回文件,用Properties的store()方法实现number++;prop.setProperty("count", String.valueOf(number));FileWriter fw = new FileWriter("myOtherStream\\game.txt");prop.store(fw, null);fw.close();}}
}

Java基础学习(二十七)之IO流相关推荐

  1. Java基础学习总结(13)——流IO

    2019独角兽企业重金招聘Python工程师标准>>> 一.JAVA流式输入/输出原理 流是用来读写数据的,java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象 ...

  2. Java基础:File类与IO流

    1. File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 1.2 构造方法 public File(String path ...

  3. 第一阶段>>>Java基础进阶 OOP/Reflect/注解/IO流/API核心

    目录 >>>java基础01-结构以及类型 >>>java基础02-初识数组 >>>java基础03-面向对象OOP >>>ja ...

  4. JAVA基础-08.File类与IO流-21.【缓冲流、转换流、序列化流、打印流】

    01_缓冲流的原理 02_转换流的原理 03_序列化和反序列化的概述 04_序列号冲突异常的原理和解决方案 day10[缓冲流.转换流.序列化流] 主要内容 缓冲流 转换流 序列化流 打印流 教学目标 ...

  5. Java基础学习 -- I/O系统、流

    Java类库里有四个表示流的抽象父类:InputStream.OutputStream.Reader.Writer. 其中 InputStream 和 OutputStream 是对字节进行操作的输入 ...

  6. Java基础(十五)IO流---字符流(Reader、Writer)、字节流(InputStream、OutputStream)

    IO流(应用广泛) 1.概念与三要素 本质是一套用于数据传输的机制 分类: 根据传输的方向(参照物–内存) 输入流:往内存传输数据 输出流:从内存往外传输数据 根据数据传输方式: 字符流:底层以字符形 ...

  7. 一个编程小白的Java SE学习日志 X—— 输入输出(IO)流【极客BOY-米奇】

    文章目录 前言(转载请说明作者!)4.30~5.7编写 File类 File类的构造方法 File类常用方法 File类的一些常用方法实例 IO流 IO流的分类 按数据流的方向分类 按是否直接操作源或 ...

  8. Java基础(二十七)Java IO(4)字符流(Character Stream)

    字符流用于处理字符数据的读取和写入,它以字符为单位. 一.Reader类与Writer类 1.Reader类是所有字符输入流的父类,它定义了操作字符输入流的各种方法. 2.Writer类是所有字符输出 ...

  9. Java基础学习(二十一)之接口

    1. 接口 1.1 接口概述 五孔插线面板,不同品牌都能使用,因为它们遵循同样的规范来生产的.所以说接口其实就是一种公共的规范,只要符合规范,大家都可以使用. 笔记本,USB口,鼠标,键盘,U盘 接口 ...

最新文章

  1. 3.初识Verilog HDL
  2. 2016年计算机视觉和图像处理相关的国际会议一览表
  3. GitHub如何下载单个文件夹
  4. win10家庭版安装docker(DockerToolbox)及问题解决
  5. plesk 打不开php,Laravel在Plesk背后,遇到PHP版本困难
  6. *【CodeForces - 791B】Bear and Friendship Condition (图论,判断完全图,dfs乱搞或带权并查集)
  7. 如何使用域组策略(AD GPO)分发软件安装以及卸载[1.31.2013更新]
  8. conformal mapping的理解
  9. 使用CSS按比例调整图像大小? [重复]
  10. vue day8 table page
  11. L1-052 2018我们要赢 (5 分)—团体程序设计天梯赛
  12. 济南遥墙机场停5天怎么收费,济南遥墙国际机场停车场收费标准
  13. 堡垒之夜显示连接不上服务器,堡垒之夜匹配提示未能连接到服务器 | 手游网游页游攻略大全...
  14. 五个了解自己天赋优势的分析工具(二)盖洛普优势测评
  15. Apostrophe not preceded by \
  16. 矩阵分析与应用(二)——矩阵微分
  17. Jenkins Windons下安装ChangeLog插件获取Git更新日志
  18. 基本数据结构--字典和常用内置序列函数
  19. .NET5.0 初始
  20. 营销策略策划的方法汇总(上)

热门文章

  1. 电商平台开发你需要注意下面的几点!
  2. 国家知识产权局宣告易百珑自发电专利权有效
  3. 【从零开始学习YOLOv3】3.YOLOv3的数据组织和处理
  4. linux执行startx进入桌面黑屏,linux下误操作startx命令后,在登录界面进不去解决办法...
  5. 0x7fffffff是多少(也就是INT_MAX,首位是 0,其余都是1,f代表1111)
  6. 2020华为春招面试:一面二面三面(一下午4h左右完成)已挂
  7. glove.840B.300d、glove.42B.300d、glove.6B网盘下载
  8. 记笔记-文件记笔记方法
  9. 吸粉神器——维盟智慧wifi,微信粉丝生产基地!
  10. 开发板的lcd 显示