文件类以及IO输入输出
文件类以及IO输入输出
我们在java使用中必不可少与文件交互,由此IO流显得格外重要
绝对路径和相对路径
绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件
相对路径:必须使用取自其他路径名的信息进行解释
File类
File:它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,封装的并不是真正的文件,仅仅是一个路径名而已,它可以是存在的,可以是不存在的
File类构造方法
方法如下:
方法名 | 说明 |
---|---|
File(String pathname) | 通过将给定的路径字符串转换为抽象路径名来创建新的File实例 |
File(String parent,String child) | 从父路径名字符串和子路径名字符串创建新的File实例 |
File(File parent,String child) | 从父抽象路径名和子路径名字符串创建新的File实例 |
下面给出代码实例:
import java.io.File;
public class Demo1 {
public static void main(String[] args) {
//下方示例存在D:\Test,但不存在D:\Test\java.txt;
//但仍旧可以执行,因为File采用的是抽象路径,不需要文件地址存在
//第一种构造:直接写入地址
File f1 = new File("D:\\Test\\java.txt");
System.out.println(f1);
//第二种构造,分开写父类和子类地址
File f2 = new File("D:\\Test","java.txt");
System.out.println(f2);
//第三种构造,分开写父类和子类地址,但父类是File类型,子类是String类型
File f3 = new File("D:\\Test");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
}
}
File类创建功能
方法如下:
方法名 | 说明 |
---|---|
public boolean createNewFile() | 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件 |
public boolean mkdir() | 创建由此抽象路径名命名的目录 |
public boolean mkdirs() | 创建由此抽象路径名命名的目录,包括任何必须但不存在的目录 |
下面给出示例代码:
import java.io.File;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) throws IOException {
//f1:创建文件createNewFile()需要抛出异常
File f1 = new File("D:\\Test\\java.txt");
System.out.println(f1.createNewFile());
//f2:创建目录mkdir()创建单层目录
File f2 = new File("D:\\Test\\javaSE");
System.out.println(f2.mkdir());
//f3:创建目录mkdirs()创建多层目录(注意这里使用mkdir()会报错,因为没有上一级目录,所以无法在上一级创建下一级)
File f3 = new File("D:\\Test\\javaWEB\\HTML");
System.out.println(f3.mkdirs());
//以上输出,如果创建成功为true;但若已有该文件或创造失败输出false
}
}
注意:window同一页面下不允许出现目录或文件名字一样的情况
File类删除功能
方法如下:
方法名 | 说明 |
---|---|
public boolean delete() | 删除由此抽象路径名表示的文件和目录 |
下面给出代码示例:
import java.io.File;
import java.io.IOException;
public class Demo3 {
public static void main(String[] args) throws IOException {
//在当前目录下创建文件java
File f1 = new File("java.txt");
f1.createNewFile();
//删除文件java
f1.delete();
//在当前目录下创建目录javaSE
File f2 = new File("javaSE");
f2.mkdir();
//删除目录javaSE
f2.delete();
//创建目录javaWEB以及内部文件HTML.txt
File f3 = new File("javaWEB");
f3.mkdir();
File f4 = new File("javaWEB\\HTML.txt");
f4.createNewFile();
//删除目录javaWEB,注意删除目录前必须删除目录内所有元素
f4.delete();
f3.delete();
}
}
注意:需要目录内容全部删除完毕,才可以删除该目录
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对象数组 |
下面给出示例代码:
import java.io.File;
import java.io.IOException;
public class Demo4 {
public static void main(String[] args) throws IOException {
//首先创建一个文件来实施下面的判断:
File f1 = new File("IO流\\Demo1\\java.text");
//定义之前定义的Test目录实施下面的判断
File f2 = new File("D:\\Test");
//判断1:是否为目录
System.out.println(f1.isDirectory());
//判断2:是否为文件
System.out.println(f1.isFile());
//判断3:是否存在
System.out.println(f1.exists());
//获取1:返回绝对路径
System.out.println(f1.getAbsolutePath());
//获取2:返回路径名称
System.out.println(f1.getPath());
//获取3:返回文件或目录名
System.out.println(f1.getName());
//获取4:获取当前目录下所有文件和目录名称
String[] strArrary = f2.list();
for(String s : strArrary){
System.out.println(s);
}
//获取5:获取当前目录下所有文件和目录File对象数组
File[] files = f2.listFiles();
for(File file : files){
System.out.println(file);
}
//获取5提升:获得当前目录下所有文件对象
for(File file : files){
if(file.isFile()){
System.out.println(file);
}
}
}
}
案例:遍历目录
需求:给定一个路径,请通过递归完成遍历该目录下所有内容,并把文件的绝对路径输出在控制台
import java.io.File;
public class Demo5 {
public static void main(String[] args) {
//定义之前定义的Test目录
File f = new File("D:\\Test");
//调用方法:
getAllFile(f);
}
//定义方法使得不断遍历
public static void getAllFile(File f){
//提取出来各文件和目录
File[] files = f.listFiles();
//非空情况下运行
if(files != null){
for(File file : files){
//如果是文件就输出;如果是目录就继续遍历
if(file.isFile()){
System.out.println(file);
}else {
getAllFile(file);
}
}
}
}
}
IO流
IO流概述:
- IO:输入/输出(Input/Output)
- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
- IO流是用来处理设备间数据传输问题的
IO流分类
- 按数据的流向:
输入流:读数据
输出流:写数据
- 按数据类型来分类:
字节流
字符流
一般按照数据类型来分类:
当数据通过Windows的记事本打开,可以读懂即为字节流,读不懂为字符流(可以默认使用字符流)
字节流分界线
下面介绍均为字节流
基类介绍
字节流抽象基类:
- InputStream:这个抽象类是表示字节输入流的所有类的超类
- OutputStream:这个抽象类是表示字节输出流的所有类的超类
- 子类名特点:子类都是以其父类名作为子类名结尾
字节流写数据
FileOutputStream:文件输出流用于将数据写入File
FileOutputStream(String name):创建文件输出流以指定的名称写入文件
/*
* 上面语句做了三件事:
* 1.调用系统功能创建了文件
* 2.创建了字节输出流对象
* 3.让字节输出流对象指向创好的文件
*/
下面给出代码示例:
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
//创建字符输出流对象(注意抛出异常)
FileOutputStream fos =new FileOutputStream("Demo2\\fos.txt");
//字符写入:(写入的是ASCII代码转化前的数字)
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开始写入(一次写入一个字节数组数据) |
下面给出示例代码:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class Demo2 {
public static void main(String[] args) throws IOException {
//构造方法1:
FileOutputStream fos1 = new FileOutputStream("Demo2\\fos1.txt");
//构造方法2:
File f = new File("Demo2\\fos2.txt");
FileOutputStream fos2 = new FileOutputStream(f);
//字符流输入:
fos1.write(97);
//Byte[]流输入;(可以写String类型采用格式转换)
byte[] bytes = {97,98,99,100,101};
fos1.write(bytes);
fos1.write("Hello".getBytes(StandardCharsets.UTF_8));
//Byte[]流部分输入:
fos1.write(bytes,1,3);
}
}
字节流两个小问题
1.字节流写完数据如何换行?
- 写完数据后,加换行符
windows:\r\n
linux:\n
mac:\r
2.字节流写数据如何实现追加写入?
- public FileOutputStream(String name,boolean append)
- 创建文件输出流以指定的名称写入文件,如果第二个参数为true,则字节将写入文件的末尾而不是开头
下面给出示例代码:
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class Demo3 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("Demo2\\fos3.txt");
//实现换行需要在输入结束后打印换行符:
fos.write("Hello".getBytes(StandardCharsets.UTF_8));
fos.write("\r\n".getBytes(StandardCharsets.UTF_8));
fos.write("Hello".getBytes(StandardCharsets.UTF_8));
//如果要实施追加操作,需要在定义对象时设置为可追加模式:
FileOutputStream foss = new FileOutputStream("Demo2\\fos3.txt",true);
}
}
字节流写数据加异常处理
finally:在异常处理时提供finally模块来执行所有清除操作(close())
特点:被finally控制的语句一定会执行,除非JVM退出
//基本格式
try{
可能出现异常的代码;
} catch(异常类型 变量名){
异常的处理代码;
} finally{
执行所有清楚操作;
}
下面给出示例代码:
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4 {
public static void main(String[] args) {
//我们下面将采用try()来处理异常
//因为fos在下面各个部分都使用,需要在外面定义fos且赋值null
FileOutputStream fos = null;
//第一层try,处理write
try {
fos = new FileOutputStream("Demo2\\fos.txt");
fos.write(97);
} catch (IOException e){
//出现异常打印异常
e.printStackTrace();
} finally {
//最后记得close(),但close也有异常,所以出现第二层try(注意要在fos存在的情况下close())
if(fos != null){
try {
fos.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
}
字节流读数据
FileInputStream:从文件系统中的文件获取输入字节
FileInputStream:通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
下面给出代码示例:
import java.io.FileInputStream;
import java.io.IOException;
public class Demo5 {
public static void main(String[] args) throws IOException {
//输入流对象
FileInputStream fis = new FileInputStream("Demo2\\fos.txt");
//一次读取一个字节(读取第一个字节)
int i = fis.read();
System.out.println(i);
System.out.println((char)i);
//一次读取一个字节(读取第二个字节)
i = fis.read();
System.out.println(i);
System.out.println((char)i);
//一次读取一个字节(读取第三个字节)
//注意:当文件没有内容时,反馈-1
i = fis.read();
System.out.println(i);
System.out.println((char)i);
//输入流对象
FileInputStream fiss = new FileInputStream("Demo2\\fos.txt");
//所以我们可以根据没有内容反馈-1的特性来输出:
while ((i = fiss.read()) != -1){
System.out.print((char)i);
}
}
}
案例:复制文本文件
需求:把fos1的内容复制到fos中
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo6 {
public static void main(String[] args) throws IOException {
//把fos1内容移到fos中
//创建输入流对象
FileInputStream fis = new FileInputStream("Demo2\\fos1");
//闯进输出流对象
FileOutputStream fos = new FileOutputStream("Demo2\\fos");
//逐渐循环
int i ;
while ((i = fis.read()) != -1){
fos.write(i);
}
//释放资源
fis.close();
fos.close();
}
}
字节流读数据
需求:把文件fos.txt的内容读取出来在控制台输出
import java.io.FileInputStream;
import java.io.IOException;
public class Demo7 {
public static void main(String[] args) throws IOException {
//创造对象
FileInputStream fis = new FileInputStream("Demo2\\fos.txt");
//首先创造一个byte[],大小固定为1024或1024整数倍
byte[] bytes = new byte[1024];
//创造len来指定fis内容大小
int len;
//当内容不为null,输出内容
while ((len = fis.read(bytes)) != -1){
//注意只输出fos有的部分,采用String方法
System.out.println(new String(bytes,0,len));
}
}
}
案例:复制图片
需求:把图片1复制到图片2
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo8 {
public static void main(String[] args) throws IOException {
//创造输入流对象
FileInputStream fis = new FileInputStream("D:\\test\\mn.jpg");
//创造输出流对象
FileOutputStream fos = new FileOutputStream("Demo2\\mmn.jpg");
//逐一赋值
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read()) != -1 ){
fos.write(bytes,0,len);
}
//close处理
fis.close();
fos.close();
}
}
字节缓冲流
字节缓冲流提供空间来存储写入读取的字节,使IO操作不再频繁
下面给出两种字节缓冲流的概念:
- BufferOutputSteam:该类实现缓冲输出流;通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入到的每个字节导致底层的调用
- BufferInputSteam:该类将创建一个内部缓冲区数组;当从流种读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次多个字节
下面给出构造方法:
- 字节缓冲输出流:BufferOutputSteam(OutputSteam out)
- 字节缓冲输入流:BufferInputSteam(InputSteam in)
为什么构造方法需要的是字节流,而不是具体的文件或路径呢?
//因为字节缓冲流仅仅提供缓冲区,真正的读写仍旧由基本的字节流对象控制操作
下面给出示例代码:
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Demo1 {
public static void main(String[] args) throws IOException {
//先创建输出流对象
FileOutputStream fos = new FileOutputStream("Demo3\\fos.txt");
//创建缓冲流
BufferedOutputStream bos = new BufferedOutputStream(fos);
//上面两步可以合成一步:BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Demo3\\fos.txt"));
//缓冲流可以使用输出流的方法(缓冲流只负责缓存,其他方法仍旧使用输出流对象的方法)
bos.write(97);
bos.write("Hello\t\n".getBytes(StandardCharsets.UTF_8));
//清空
bos.close();
//创造输入流对象
FileInputStream fis = new FileInputStream("Demo3\\fos.txt");
//创造缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
//输出:
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1){
System.out.println(new String(bys,0,len));
}
//清空
bis.close();
}
}
案例:复制视频
需求:把D:\Test\mm.avi视频转移到Demo3\mmm.avi
下面给出代码实例:
import java.io.*;
public class Demo2 {
public static void main(String[] args) throws IOException {
//创造开始时间
long setTime = System.currentTimeMillis();
//第1种:基本字节流一次读写一个字节
method1();
//第2种:基本字节流一次读写一个字节数组
method2();
//第3种:缓存字节流一次读写一个字节
method3();
//第4种:缓存字节流一次读写一个字节数组
method4();
//创造结束时间
long endTime = System.currentTimeMillis();
System.out.println("一共用时:" + (endTime-setTime) +"毫秒");
//当文件适中(速度来说):4>2>3>>1
}
public static void method1() throws IOException {
FileOutputStream fos = new FileOutputStream("D:\\Test\\mm.avi");
FileInputStream fis = new FileInputStream("Demo3\\mmm.avi");
int i;
while ((i = fis.read()) != -1){
fos.write(i);
}
fos.close();
fis.close();
}
public static void method2() throws IOException {
FileOutputStream fos = new FileOutputStream("D:\\Test\\mm.avi");
FileInputStream fis = new FileInputStream("Demo3\\mmm.avi");
byte[] bys = new byte[1024];
int i;
while ((i = fis.read(bys)) != -1){
fos.write(bys,0,i);
}
fos.close();
fis.close();
}
public static void method3() throws IOException {
FileOutputStream fos = new FileOutputStream("D:\\Test\\mm.avi");
BufferedOutputStream bos = new BufferedOutputStream(fos);
FileInputStream fis = new FileInputStream("Demo3\\mmm.avi");
BufferedInputStream bis = new BufferedInputStream(fis);
int i;
while ((i = bis.read()) != -1){
bos.write(i);
}
bos.close();
bis.close();
}
public static void method4() throws IOException {
FileOutputStream fos = new FileOutputStream("D:\\Test\\mm.avi");
BufferedOutputStream bos = new BufferedOutputStream(fos);
FileInputStream fis = new FileInputStream("Demo3\\mmm.avi");
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] bys = new byte[1024];
int i;
while ((i = bis.read(bys)) != -1){
bos.write(bys,0,i);
}
bos.close();
bis.close();
}
}
字符流分界线
下面介绍均为字符流
字符流基本介绍
为什么会出现字符流呢?
- 因为字节流操作中文并不方便
- 字符流 = 字节流 + 编码表
如何标识中文:
- 无论哪种编码存储方式,中文的第一个字节都是负数
针对字符流:
- GBK -> 二位数
- UTF-8 -> 三位数
编码表
基本知识:
- 计算机存储的信息都是用二进制存储的,我们在屏幕中看到的英文汉字都是二进制转换之后的结果
- 编码:按照某种规则,将字符存储到计算机中
- 解码:将存储在计算机中的二进制按照某种规则解析出来
- 字符编码:自然语言字符与二进制之间的对应关系(A <-> 65)
字符集:
- 是一个系统支持的所有字符的集合,包括各国家文字,标点符号,图形符号,数字等
- 计算机要精准存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码
- 常见字符编码:ASCII字符集,GBXXX字符集,Unicode字符集
ASCII字符集:
- ASCII字符集:基于拉丁字母的一套电脑编码系统,主要显示现代英语,主要包括控制字符和可显示字母
- 基本ASCII字符集,使用7位一体,共128字符。
GBXXX字符集:
-
GB2312:简体中文码表,127以内字符意义相同,但大于127字符相连标识文字,共7000多文字
-
GBK:最常用的中文码表,在GB2312上进行扩充,共21003汉字,包括繁体汉字以及日韩汉字等
-
GB18030:最新的中文码表,共70244汉字,包括少数民族,繁体,日韩等
Unicode字符集:
- 为表达任意语言的任意字符而设计的,是业界的一种标准,称为统一码,标准万国码
- 最多使用4个字节的数字来表达字母,符号或文字
- 包括:UTF-8,UTF-16,UTF-32
UTF-8:
- 用来表示Unicode标准中任意字符,优先采用编码
- 使用一至四字节为每个字符编码
- 128个US-ASCII字符,只需一个字符编码
- 拉丁文等字符,需要两个字符编码
- 大部分常用字(含中文),使用三个字符编码
- 其他极少使用的UTF辅助字符,使用四个字符编码
字符串的编码解码问题
编码:
- byte[] getByte():使用平台默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
- byte[] getByte(String charsetNAme):使用指定字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码:
- String(byte[] bytes):通过使用平台的默认字符集解码指定的字符数组来构造新的String
- String(byte[] bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
下面给出示例代码:
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) throws UnsupportedEncodingException {
//设置String
String s ="中国";
//编码:
byte[] bys1 = s.getBytes("UTF-8");//这里使用UTF-8编码
byte[] bys2 = s.getBytes("GBK");//这里采用GBK编码
//这里采用Arrays.toString将其变成字符串输出
System.out.println(Arrays.toString(bys1));
System.out.println(Arrays.toString(bys2));
//解码:
String s1 = new String(bys1);//这里采用默认UTF-8
String s2 = new String(bys1,"UTF-8");//这里使用UTF-8
String s3 = new String(bys1,"GBK");//这里采用GBk解码
//输出解码内容:
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
}
字符流的编码解码问题
字符流抽象基类:
- Reader:字符输入流抽象类
- Writer:字符输出流抽象类
字符流中的编码解码问题相关类
- InputStreamReader
- OutputStreamWriter
下面给出示例代码:
//下面仅对于讲解纯净版
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("Demo4\\fos.txt");
OutputStreamWriter osr = new OutputStreamWriter(fos);
osr.write("中国人");
osr.close();
FileInputStream fis = new FileInputStream("Demo4\\fos.txt");
InputStreamReader isr = new InputStreamReader(fis);
int ch;
while ((ch = isr.read()) != -1){
System.out.println((char)ch);
}
}
}
//下方给出不同类型进行讲解
import java.io.*;
public class Demo2 {
public static void main(String[] args) throws IOException {
//创建字符流编码
OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("Demo4\\osw.txt"));//这里直接编码
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("Demo4\\osw.txt"),"UTF-8");//这里采用UTF编码
OutputStreamWriter osw3 = new OutputStreamWriter(new FileOutputStream("Demo4\\osw.txt"),"GBk");//这里采用GBK编码
osw1.write("中国");//这里写入中国
osw2.write("中国");//这里写入中国
osw3.write("中国");//这里写入乱码,因为编译器默认解码UTF-8,这里采用GBK编码,无法正确编译
osw1.close();
osw2.close();
osw3.close();
//创建字符流解码
InputStreamReader isr1 = new InputStreamReader(new FileInputStream("Demo4\\osw.txt"));//正常解码(UTF-8)
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("Demo4\\osw.txt"));//特殊解码(GBK)
int ch1;
while ((ch1 = isr1.read()) != -1){
System.out.println((char)ch1);
}
int ch2;
while ((ch2 = isr1.read()) != -1){
System.out.println((char)ch2);
}
}
}
字符流基本方法
方法如下:
方法名 | 说明 |
---|---|
flush() | 刷新流,还可以继续写数据 |
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) | 写一个字符串的一部分 |
下面给出示例代码:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Demo1 {
public static void main(String[] args) throws IOException {
//首先创建对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Demo5\\osw.txt"));
//第一种:
osw.write(97);
//第二种:
char[] chars = {'a','b','c'};
osw.write(chars);
//第三种:
osw.write("abcde");
//第四种:
osw.write("abcde",0,5);
//第五种:
osw.write("abcde",0,"abcde".length());
//flush方法:
osw.flush();//采用这种方法,使数据刷新出来
//close()方法:
osw.close();//关闭接口,但在关闭前会刷新数据,同时使用flush方法
}
}
字符流读数据
方法如下:
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
下面给出代码实例:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo2 {
public static void main(String[] args) throws IOException {
//创建字符流读取对象
InputStreamReader isr = new InputStreamReader(new FileInputStream("Demo5\\osw.txt"));
//第一种读取:(一次读一个字符)
int ch;
while ((ch = isr.read()) != -1){
System.out.print((char)ch);
}
//第二种读取:(一次读取多个)
char[] chars = new char[1024];
int len;
while ((len = isr.read(chars)) != -1){
System.out.println(new String(chars,0,chars.length));
}
}
}
案例:复制java文件
需求:把该模块下的Demo5\src\Demo2.java文件复制到Demo5\src\Demo4.txt
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws IOException {
//创建输入流对象
InputStreamReader isr = new InputStreamReader(new FileInputStream("Demo5\\src\\Demo2.java"));
//创建输出流对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Demo5\\src\\Demo4.txt"));
//读取数据,复制文件
char[] ch = new char[1024];
int len;
while ((len = isr.read(ch)) != -1){
osw.write(ch);
}
osw.close();
isr.close();
}
}
案例:复制java文件(改进版)
需求:把该模块下的Demo5\src\Demo2.java文件复制到Demo5\src\Demo4.txt
import java.io.*;
public class Demo4 {
public static void main(String[] args) throws IOException {
//创建输入流对象(简化版)
FileReader fr = new FileReader("Demo5\\src\\Demo2.java");
//创建输出流对象(简化版)
FileWriter fw = new FileWriter("Demo5\\src\\Demo4.txt");
//读取数据,复制文件
char[] ch = new char[1024];
int len;
while ((len = fr.read(ch)) != -1){
fw.write(ch);
}
fw.close();
fr.close();
}
}
这里主要是用FileReader和FileWriter子类来更换InputStreamReader和OutputStreamWriter类,减少代码冗杂
字符缓冲流
字符缓冲流关键类:
- BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可指定缓冲区大小
- BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小
构造方法:
- BufferedWriter(Writer out)
- BufferedReader(Reader in)
下面给出示例代码:
import java.io.*;
public class Demo1 {
public static void main(String[] args) throws IOException {
//创建缓冲流字符输出流
FileWriter fw = new FileWriter("Demo6\\fw.txt");
BufferedWriter bw = new BufferedWriter(fw);
fw.write("Hello");
fw.write("World");
//创建缓冲流字符输入流
FileReader fr = new FileReader("Demo6\\fw.txt");
BufferedReader br = new BufferedReader(fr);
int ch;
while ((ch = br.read()) != -1) {
System.out.println((char)ch);
}
bw.close();
br.close();
}
}
字符缓冲流特有功能
BufferedWrier:
- void newLine():写一行行分隔符
BufferedReader:
- public String readLine():读一行文字,不包括终止字符;若到结尾为null
下面给出示例代码:
import java.io.*;
public class Demo2 {
public static void main(String[] args) throws IOException {
//创建对象
BufferedWriter bw = new BufferedWriter(new FileWriter("Demo6\\Demo.txt"));
for (int i = 0; i < 2; i++) {
bw.write("Hello" + i);
bw.newLine();//换行(各操作系统通用)
}
bw.close();
//创建对象
BufferedReader br = new BufferedReader(new FileReader("Demo6\\Demo.txt"));
//读取第一行
String s = br.readLine();//每次读取一行
System.out.println(s);
//读取第二行
s = br.readLine();//每次读取一行
System.out.println(s);
//读取第三行
s = br.readLine();//每次读取一行
System.out.println(s);//没有内容,输出null
//循环输出方法
while ((s = br.readLine()) != null){
System.out.println(s);
}
}
}
案例:复制java文件(字符缓冲流特有功能改进版)
需求:把该模块下的Demo6\src\Demo1.java文件复制到Demo6\src\Demo.txt
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws IOException {
//创建对象
BufferedReader br = new BufferedReader(new FileReader("Demo6\\src\\Demo1.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("Demo6\\src\\Demo.txt"));
//读取并复制:
String s;
while ((s = br.readLine()) != null){
bw.write(s);
bw.newLine();
bw.flush();
}
//释放资源
br.close();
bw.close();
}
}
案例:集合->文件
需求:把ArrayList集合中的字符串数据写入到文本文件中。
要求:每个字符串文件作为文件中的一行数据
代码如下:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Demo {
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("Demo7\\src\\java.txt"));
//遍历并写入
for(String s : array){
bw.write(s);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
}
案例:文件->集合
需求:把文本文件的数据读取到集合中,并遍历集合
要求:文件中每一行数据是个集合元素
代码如下:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Demo1 {
public static void main(String[] args) throws IOException {
//创建字符流输入流对象
BufferedReader br = new BufferedReader(new FileReader("Demo7\\src\\java.txt"));
//创建ArrayList集合
ArrayList<String> array = new ArrayList<String>();
//逐步遍历并add
String line;
while ((line = br.readLine()) != null){
array.add(line);
}
//释放资源
br.close();
//遍历验证
for(String s : array){
System.out.println(s);
}
}
}
案例:点名器
需求:我有一个文件里面存储了班级同学的名称,每个名称占一行,要求通过点名程序实现随机点名
代码如下:
刘备
关羽
张飞
诸葛亮
赵云
黄忠
司马懿
曹操
孙策
孙权
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class Demo2 {
public static void main(String[] args) throws IOException {
//创建字符流输入流对象
BufferedReader br = new BufferedReader(new FileReader("Demo7\\src\\names"));
//创建ArrayList集合
ArrayList<String> array = new ArrayList<String>();
//逐步遍历并add
String line;
while ((line = br.readLine()) != null){
array.add(line);
}
//释放资源
br.close();
//设立随机数
Random r = new Random();
int i = r.nextInt(array.size());
//取随机数并输出
System.out.println("幸运儿是:" + array.get(i));
}
}
案例:集合->文件(改进版)
需求:把ArrayList集合中的Student学生对象数据写入到文本文件中。
要求:每个Student学生对象作为文件中的一行数据
代码如下:
public class Student {
String sid;
String name;
String age;
public Student(){
}
public Student(String sid,String name,String age){
this.sid = sid;
this.name = name;
this.age = age;
}
}
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Demo3 {
public static void main(String[] args) throws IOException {
//创建字符流输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("Demo7\\src\\student.txt"));
//创建ArrayList对象
ArrayList<Student> array = new ArrayList<>();
//创建学生对象并加入
Student s1 = new Student("001","刘备","30");
Student s2 = new Student("002","关羽","35");
Student s3 = new Student("003","张飞","39");
array.add(s1);
array.add(s2);
array.add(s3);
//遍历并拼接
for(Student s : array){
StringBuilder sb = new StringBuilder();
sb.append(s.sid + " " + s.name + " " + s.age);
bw.write(String.valueOf(sb));
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
}
案例:文件->集合(改进版)
需求:把文本中的数据读取到集合中,并遍历集合
要求:文本中每一行数据是一个学生对象的成员变量值(每个数据用空号隔开,每个对象占一行)
代码如下:
001 刘备 30
002 关羽 35
003 张飞 39
public class Student {
String sid;
String name;
String age;
public Student(){
}
public Student(String sid,String name,String age){
this.sid = sid;
this.name = name;
this.age = age;
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Demo4 {
public static void main(String[] args) throws IOException {
//创建缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("Demo7\\src\\student.txt"));
//创建ArrayList集合
ArrayList<Student> array = new ArrayList<>();
//遍历
String line;
while ((line = br.readLine()) != null){
//创造String数组储存分开元素
String[] s = new String[3];
s = line.split(" ");
//元素放入Student对象
Student student = new Student();
student.sid = s[0];
student.name = s[1];
student.age = s[2];
//将对象加入集合
array.add(student);
}
//释放资源
br.close();
//遍历
for(Student s : array){
System.out.println(s.sid + s.name + s.age);
}
}
}
案例:复制单级文件夹
需求:把"IO流\Demo6"下的文件复制到"IO流"中(文件夹内只包含文件,不包含目录)
代码如下:
import java.io.*;
public class Demo1 {
public static void main(String[] args) throws IOException{
//创建数据源目录File对象
File srcFolder = new File("IO流\\Demo6");
//创建数据目录名File对象的名称
String srcFolderName = srcFolder.getName();
//创建目的地目录File对象,这里名字和源目录名一致
File destFolder = new File("IO流",srcFolderName);
//判断目的地目录对应的File是否存在,若不存在则创建
if(!destFolder.exists()){
destFolder.mkdir();
}
//获得数据源目录下所有文件File数组
File[] files = srcFolder.listFiles();
//遍历数组得到所有文件
for(File f : files){
//得到文件名并在目的目录创造文件
String filename = f.getName();
File destFile = new File(destFolder,filename);
//将文件复制进来(我们采用方法来复制)
copy(f,destFile);
}
}
public static void copy(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();
}
}
案例:复制多级文件夹
需求:把"IO流\Demo1"下的文件复制到"IO流\Demo8"中(文件夹内既包含文件,又包含目录)
import java.io.*;
public class Demo2 {
public static void main(String[] args) throws IOException{
//首先创建数据源对象,这里指定Demo1
File srcFile = new File("D:\\程序代码\\第1部分javase\\code\\IO流\\Demo1");
//然后创建被复制位置对象,这里指定Demo8
File destFile = new File("D:\\程序代码\\第1部分javase\\code\\IO流\\Demo8");
//接下来我们创建方法来实现效果(方法中包含递归)
copyFolder(srcFile,destFile);
}
//copyfolder复制文件夹
public static void copyFolder(File srcFile,File destFile) throws IOException{
//首先判断复制文件是否为文件夹:
if(srcFile.isDirectory()){
//这里判断成功,为文件夹
//那么我们需要获取名字,在粘贴地点创造相同名字的文件夹
File destFloder = new File(destFile,srcFile.getName());
//判断是否存在,若不存在创建一个文件夹
if(!destFloder.exists()){
destFloder.mkdir();
}
//有文件夹后,将文件夹内容增添进去
//首先获得文件夹内所有文件
File[] files = srcFile.listFiles();
//逐步将文件加入
for (File file : files){
//这里一直递归
copyFolder(file,destFloder);
}
}else {
//这里书写文件复制:
File newFile = new File(destFile,srcFile.getName());
copyFile(srcFile,newFile);
}
}
//copyfile复制文件
public 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();
}
}
复制文件的异常处理
直接抛出异常写法:
//直接抛出异常写法
public static void method1() throws IOException {
FileReader fr = new FileReader("Demo1.txt");
FileWriter fw = new FileWriter("Demo2.txt");
char[] ch = new char[1024];
int len;
while ((len = fr.read(ch)) != -1){
fw.write(ch,0,len);
}
fr.close();
fw.close();
}
try-catch-finally方法:
//try--catch--finally方法
public static void method2() {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("Demo1.txt");
fw = new FileWriter("Demo2.txt");
char[] ch = new char[1024];
int len;
while ((len = fr.read(ch)) != -1){
fw.write(ch,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(fr != null){
try {
fr.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(fw != null){
try {
fw.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
jdk7改进后写法:
//jdk7之后改进做法
public static void method3() {
try(FileReader fr = new FileReader("Demo1.txt");
FileWriter fw = new FileWriter("Demo2.txt");) {
char[] ch = new char[1024];
int len;
while ((len = fr.read(ch)) != -1){
fw.write(ch,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
}
特殊操作流分界线
下面介绍均为特殊操作流
标准输入输出流
System类中有两个静态的成员变量:
- public static final InputStream in:标准输入流(对标Scanner)
- public static final PrintStream out:标准输出流(对标System.out.print)
下面给出代码实例:
import java.io.*;
public class Demo1 {
public static void main(String[] args) throws IOException {
//创建最基本的:
InputStream is = System.in;
int by;
while ((by = is.read()) != -1){
System.out.println((char)by);
}
//这里标准类指向Scanner
//我们可以创建缓冲流字符流标准输出流
//这里采用BufferedReader,InputStreamReader,InputStream共同创建
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入一句话:");
String s = br.readLine();
System.out.println("你输入的是:" + s);
System.out.println("请输入一个数字:");
int i = Integer.parseInt(br.readLine());
System.out.println("你输入的是:" + i);
}
}
import java.io.PrintStream;
public class Demo2 {
public static void main(String[] args) {
PrintStream ps = System.out;
//完全等同于System.out.print()
ps.print("123");
ps.println("hello");
}
}
打印流
打印流分类:
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
打印流特点:
- 只负责输出数据,不负责读取数据
- 有自己特有方法
字节打印流
构造方法:
方法名 | 说明 |
---|---|
PrintStream(String fileName) | 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新 |
特点:
- 使用继承父类的方法写数据,查看时会转码
- 使用自己特有方法写数据,数据直接原样输出
代码如下:
import java.io.IOException;
import java.io.PrintStream;
public class Demo3 {
public static void main(String[] args) throws IOException {
PrintStream ps = new PrintStream("Demo9\\src\\Demo1\\java.txt");
//正常方法(这里采用的是ASCII码)
ps.write(98);
//特殊方法(这里直接输出)
ps.println(99);
ps.print(98);
}
}
字符打印流
构造方法:
方法名 | 说明 |
---|---|
PrintWriter(String fileName) | 使用指定文件名创建一个新的PrintWriter,而不需要自动执行刷新 |
PrintWriter(Writer out,boolean autoFlush) | 创建一个新的PrintWriter |
代码如下:
import java.io.IOException;
import java.io.PrintWriter;
public class Demo4 {
public static void main(String[] args) throws IOException {
//两种构造方法
//第一种,不能自动刷新flush,需要手动刷新
PrintWriter pw1 = new PrintWriter("Demo9\\src\\Demo1\\java.txt");
//第二种,不需要手动刷新flush
PrintWriter pw2 = new PrintWriter(new PrintWriter("Demo9\\src\\Demo1\\java.txt"),true);
//正常方法
pw1.write(98);
//特殊方法
pw1.println("123");
pw1.print("2");
}
}
案例:复制java文件(打印流改进版)
需求:把模块目录下的"Demo9\src\Demo1\Demo1.java"复制到"Demo9\src\Demo1\java1.txt"
代码如下:
import java.io.*;
public class Demo5 {
public static void main(String[] args) throws IOException {
//输入流无法用print代替,所以正常缓冲流
BufferedReader br = new BufferedReader(new FileReader("Demo9\\src\\Demo1\\Demo1.java"));
//输出流采用print方法
PrintWriter pw = new PrintWriter(new FileWriter("Demo9\\src\\Demo1\\java1.txt"));
//采用逐个复制
String s;
while ((s=br.readLine()) != null){
pw.println(s);
}
//释放资源
br.close();
pw.close();
}
}
对象序列化
对象序列化:把对象保存到磁盘中,或者在网络中传输对象
这种机制使用一个字节序列表示一个对象,该字节序列包含:对象的类型,对象的数据以及对象中存储的属性等信息
对象序列化流
对象序列化流:ObjectOutputStream
- 将java对象的原始数据类型和图形写入OutputStream
- 可以采用ObjectInputStream读取对象
- 可以通过使用流的文件来实现对象的持久存储
- 如果流是网络套接字流,则可以在另一个主机或进程中重构对象
构造方法:
- ObjectOutputStream(OutputStream out):创建一个写入指定OutputStream的ObjectOutputStream
序列化对象方法:
- void writeObject(Object obj):将指定对象写入ObjectOutputStream
注意:
- 一个对象想要被序列化,需要该类实现继承Serializable接口
- Serializable接口是一个标记接口,实现该接口不需要写任何方法
代码如下:
import java.io.Serializable;
//序列化类需要接口Serializable作为标识
public class Student implements Serializable {
public String name;
public int age;
public Student(){
}
public Student(String name,int age){
this.age = age;
this.name = name;
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
public class Demo1 {
public static void main(String[] args) throws IOException {
//构造方法
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Demo9\\src\\Demo2\\java.txt"));
//创建对象
Student student = new Student("张飞",20);
//对象序列化流特殊方法
oos.writeObject(student);
//释放资源
oos.close();
}
}
对象反序列化
对象反序列化:ObjectInputStream
- ObjectInputStream反序列化先使用ObjectOutputStream编写的原始数据和对象
构造方法:
- ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
反序列化方法:
- Object readObject():从ObjectInputStream读取一个对象
代码如下:
import java.io.Serializable;
//序列化类需要接口Serializable作为标识
public class Student implements Serializable {
public String name;
public int age;
public Student(){
}
public Student(String name,int age){
this.age = age;
this.name = name;
}
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Demo2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创造反序列化流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Demo9\\src\\Demo2\\java.txt"));
//调用特有方法
Object obj = ois.readObject();
//需要向下转型
Student s = (Student) obj;
//输出测试
System.out.println(s.name + " " + s.age);
//释放资源
ois.close();
}
}
对象序列化三问题
- 用对象序列化流列化了一个对象后,假如我们修改了对象所属的类文件,读取文件是否出错?
- 会出问题,抛出InvalidClassException异常
- 如果出现问题,如何解决?
- 给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L
- 如果一个对象中的某个成员变量的值不想被序列化,该如何实现?
- 给该成员变量加上transient关键词修饰,该关键词标记的成员变量不参与序列化过程
properties类
properties类概述:
- 是一个Map体系的集合类
- Properties可以保存到流中或者从流中加载
练习代码如下:
import java.util.Properties;
import java.util.Set;
public class Demo1 {
public static void main(String[] args) {
//创造类集合,这里不是正常集合,不需要<>指定类型,固定为Object类型
Properties prop = new Properties();
//添加元素
prop.put("001","胡桃");
prop.put("002","钟离");
prop.put("003","雷神");
//将键转移到Set集合中
Set<Object> keySet = prop.keySet();
//根据键得到值
for(Object obj : keySet){
Object value = prop.get(obj);
System.out.println(obj + " " + value);
}
}
}
properties特有方法
方法如下:
方法名 | 说明 |
---|---|
Object setProperty(String key,String value) | 设置集合的键和值,都是String类型;底层调用Hashtable方法put |
String getProperty(Strig key) | 使用此属性列表中指定的键搜索属性 |
Set |
从该属性列表中返回一个不可修改的键集,其中键对应的是String |
代码如下:
import java.util.Properties;
import java.util.Set;
public class Demo2 {
public static void main(String[] args) {
//创造集合
Properties prop = new Properties();
//设置方法(都为String类型)
prop.setProperty("001","温迪");
prop.setProperty("002","钟离");
prop.setProperty("003","雷神");
//得到所有键(返回String类型)
Set<String> names = prop.stringPropertyNames();
//循环输出
for(String key : names){
//通过key得到value
String value = prop.getProperty(key);
//输出检验
System.out.println(key + " " + value);
}
}
}
Properities和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)方法的格式写入输出字符流 |
代码如下:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Demo3 {
public static void main(String[] args) throws IOException {
//调用方法1
myStore();
//调用方法2
myLoad();
}
//myLoad方法
private static void myLoad() throws IOException{
Properties prop = new Properties();
//采用方法把文件集合写入类对象中
FileReader fr = new FileReader("D:\\程序代码\\第1部分javase\\code\\IO流\\Demo10\\src\\Demo1\\java.txt");
prop.load(fr);
System.out.println(prop);
}
//myStore方法
public static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("001","温迪");
prop.setProperty("002","钟离");
prop.setProperty("003","雷神");
//采用方法把类数据写到文件中:
FileWriter fw = new FileWriter("D:\\程序代码\\第1部分javase\\code\\IO流\\Demo10\\src\\Demo1\\java.txt");
prop.store(fw,null);
fw.close();
}
}
案例:游戏次数
需求:请写程序实现猜数字小游戏,只能试玩三次,如果超过三次不能再游玩
在同目录下创造一个count.txt文档用来记录次数
#Fri Jun 24 15:55:49 CST 2022
count=0
代码如下:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Demo1 {
public static void main(String[] args) throws IOException {
//创造集合对象
Properties prop = new Properties();
//读取count.txt
FileReader fr = new FileReader("D:\\程序代码\\第1部分javase\\code\\IO流\\Demo10\\src\\Demo2\\count.txt");
prop.load(fr);
//判断是否达到3次
int count = Integer.parseInt(prop.getProperty("count"));
if(count >= 3){
//大于3次不能继续游玩
System.out.println("sorry,you can not play!");
}else {
//未到3次,玩游戏,count+1,并再次写入文件
playGame();
count++;
prop.setProperty("count",String.valueOf(count));
FileWriter fw = new FileWriter("D:\\程序代码\\第1部分javase\\code\\IO流\\Demo10\\src\\Demo2\\count.txt");
prop.store(fw,null);
fw.close();
}
fr.close();
}
//游戏内容未书写
private static void playGame() {
}
}
结束语
好的,关于IO操作我们讲到这里