相关链接
try {
//尝试对此部分代码捕获异常
} catch (Exception e) {
//捕获异常后的处理逻辑
//e.printStackTrace(); //默认处理方式打印异常信息
} finally {
//无论是否捕获异常,都会执行
}
//以IOException为例,只有使用BufferedReader就会出现找不到文件IO异常,需要进行处理
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("name.txt"));
}
案例代码一 JVM默认处理异常方式
package com.groupies.base.day13;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction JVM默认处理异常方式
*
* 处理方案:
* A:把异常的名称,异常的原因,异常出现的位置等信息在控制台输出
* B:让程序停止执行
*/
public class Demo1Exception {
public static void main(String[] args) {
/*
程序开始执行
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.groupies.base.day13.Demo1Exception.method(Demo1Exception.java:28)
at com.groupies.base.day13.Demo1Exception.main(Demo1Exception.java:21)
*/
System.out.println("程序开始执行");
method();//【报错定位】第21行
System.out.println("程序结束执行");
}
public static void method(){
int a = 10;
int b = 0;
System.out.println(a / b);//【报错定位】第28行
}
}
try {
//尝试对此部分代码捕获异常
} catch (Exception e) {
//捕获异常后的处理逻辑
//e.printStackTrace(); //默认处理方式打印异常信息
} finally {
//无论是否捕获异常,都会执行
}
//以IOException为例,只有使用BufferedReader就会出现找不到文件IO异常,需要进行处理
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("name.txt"));
}
public void printStackTrace()
:把异常的错误信息输出在了控制台。案例代码二 try…catch处理异常
package com.groupies.base.day13;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction try..catch处理异常
*
* 为什么要有throws处理方式?
* 我们通过try...catch可以对异常进行处理了,但是并不是所有的时候我们都有权限进行异常的处理。
* 也就是说,有些时候我们处理不了,但是,这个时候异常时存在的,不处理也不行,怎么办?
* 这个时候,Java就提供了throws的处理方案。
*
* try..catch的格式和执行流程为
* 格式:
* try {
* 可能出现异常的代码;
* }catch(异常类名 变量名) {
* 异常的处理代码;
* }
*
* 执行流程:
* 程序从try开始执行,执行到哪里出现了问题,就会跳转到catch里面执行。
* 执行完毕后,程序还能继续往下执行。
*
* 捕获异常后, 如何处理?
* public void printStackTrace():把异常的错误信息输出在了控制台。
* 在实际开发中,我们遇见了异常,会给出一个页面进行提示,而我们目前做不了,
* 所以,就用异常对象调用printStackTrace()就可以了。
*
* try..catch处理方式&JVM的默认处理方式有什么不同
* 首先要明确try..cathc处理方式的特点, 产生了问题, 是自己将问题处理掉, 不影响后续代码的运行.
* JVM默认处理方式是将程序终止, 并将异常信息打印在控制台.
* 但这种方式很显然用户体验度不佳, 所以这时候就可以考虑使用try..cathc将问题捕获并处理掉.
* 这样就不会影响程序的继续执行了
*/
public class Demo2TryCatch {
public static void main(String[] args) {
System.out.println("-----程序开始执行-----");
System.out.println("method: 编译时异常");
method();//日期格式不合法,请重新输入
System.out.println("method2: 运行时异常");
method2();//除数不能为0
System.out.println("-----程序结束执行-----");
}
//编译时异常ParseException
public static void method() {
//String s = "2088-08-08";
String s = "abcd";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = null;
try {
//如果不抛出异常,也不使用try catch捕获异常,则会提示如下信息:不能通过编译
//java: 未报告的异常错误java.text.ParseException; 必须对其进行捕获或声明以便抛出
d = sdf.parse(s);
} catch (ParseException e) {
//e.printStackTrace();//不打印异常信息
System.out.println("日期格式不合法,请重新输入");
}
System.out.println(d);
}
//运行时异常
public static void method2() {
try {
int a = 10;
int b = 0;
System.out.println(a / b);
} catch (ArithmeticException e) {
//e.printStackTrace();//不打印异常信息
System.out.println("除数不能为0");
}
}
}
//实例
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader("name.txt"));
}
案例代码三 throws处理异常
package com.groupies.base.day13;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction throws处理异常
*
* 为什么要有throws处理方式?
* 我们通过try...catch可以对异常进行处理了,但是并不是所有的时候我们都有权限进行异常的处理。
* 也就是说,有些时候我们处理不了,但是,这个时候异常时存在的,不处理也不行,怎么办?
* 这个时候,Java就提供了throws的处理方案。
*
* throws使用的格式&注意事项?
* 格式:
* throws 异常类名
* 注意:这个格式必须跟在方法的括号的后面
*
* 注意:
* 编译时异常时必须要进行处理的,两种处理方案:try...catch...或者throws
* 如果你采用了throws这种方案,将来谁调用,还得进行处理。
*
* 运行时异常可以不用处理,出现问题后我们需要回来修改代码。
*/
public class Demo3Throws {
public static void main(String[] args) {
System.out.println("程序开始执行");
try {
/*
java.text.ParseException: Unparseable date: "abc"
at java.text.DateFormat.parse(DateFormat.java:366)
at com.groupies.base.day13.Demo3Throws.method(Demo3Throws.java:55)
at com.groupies.base.day13.Demo3Throws.main(Demo3Throws.java:38)
*/
method();//【报错定位】第38行
} catch (ParseException e) {
e.printStackTrace();
}
/*
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.groupies.base.day13.Demo3Throws.method2(Demo3Throws.java:63)
at com.groupies.base.day13.Demo3Throws.main(Demo3Throws.java:47)
*/
method2();
System.out.println("程序结束执行");
}
//编译时异常 注意导包 import java.text.ParseException;
public static void method() throws ParseException {
String s = "abc";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(s);//【报错位置】第55行
System.out.println(d);
}
//运行时异常
public static void method2() throws ArithmeticException {
int a = 10;
int b = 0;
System.out.println(a / b);//【报错定位】第63行
}
}
//a. 通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String pathname)
//b. 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(String parent, String child)
//c. 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实
File(File parent, String child)
案例代码四 File类的构造方法
package com.groupies.base.day13;
import java.io.File;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction File类的构造方法
*
* file构造方法:
* a. File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
* b. File(String parent, String child):根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
* c. File(File parent, String child):根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实
*
*/
public class Demo4File {
public static void main(String[] args) {
//以下的f1,f2,f3做的是同样的事情,就是把d:\\aa\\b.txt转换为了一个File对象
//a. File(String pathname)
File f1 = new File("d:\\aa\\b.txt");
//b. File(String parent, String child)
File f2 = new File("d:\\aa", "b.txt");
//c. File(File parent, String child)
File f3_path = new File("d:\\aa");
File f3 = new File(f3_path, "b.txt");
}
}
//a.创建文件 如果文件不存在,创建文件并返回true 如果文件存在,创建文件失败并返回false
public boolean createNewFile():
//b.创建目录 如果目录不存在,创建目录并返回true 如果目录存在,创建目录失败并返回false
public boolean mkdir()
//c.创建多级目录
public boolean mkdirs()
案例代码五 File类方法–创建
package com.groupies.base.day13;
import java.io.File;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction File类方法--创建
*
* 创建功能
* a. File.createNewFile():创建文件
* 如果文件不存在,创建文件并返回true
* 如果文件存在,创建文件失败并返回false
* b. File.mkdir():创建目录
* 如果目录不存在,创建目录并返回true
* 如果目录存在,创建目录失败并返回false
* c. File.mkdirs():创建多级目录
*
* File.separator
* 其实File.separator 的作用相当于 '\'
* 在 windows 中文件文件分隔符 用 '\' 或者'/' 都可以
* 但是在 Linux 中,是不识别 '\'的,而File.separator 是系统默认的文件分隔符号,在 UNIX 系统上,此字段的值为'/'
* 在Microsoft Windows 系统上,它为 '\'屏蔽了这些系统的区别。
* 所以用 File.separator 保证了在任何系统下不会出错。
*
* 需求:
* 1:【createNewFile】 在d盘目录下创建一个文件a.txt
* 2:【mkdir】 在d盘目录下创建一个目录bb
* 3:【mkdirs】 在d盘目录下创建一个多级目录cc\\dd
* 4:【mkdir + createNewFile】 在d盘目录下创建一个文件ee\\f.txt
*/
public class Demo5FileMethodCreate {
public static void main(String[] args) {
//需求1:我要在d盘目录下创建一个文件a.txt
File f1 = new File("D:\\a.txt");//1.createNewFile:true
try {
System.out.println("1.createNewFile:" + f1.createNewFile());
} catch (IOException e) {
System.out.println("IO异常,创建失败");
}
//需求2:我要在d盘目录下创建一个目录bb
File f2 = new File("D:" + File.separator + "bb");
System.out.println("2.mkdirs:" + f2.mkdirs());//2.mkdirs:true
//需求3:我要在d盘目录下创建一个多级目录cc\\dd
File f3 = new File("D:\\cc" + File.separator + "dd");
System.out.println("3.mkdirs:" + f3.mkdirs());//3.mkdirs:true
//需求4:我要在d盘目录下创建一个文件ee\\f.txt
File f4_path = new File("D:\\ee");
File f4_file = new File(f4_path, "f.txt");
System.out.println("4.mkdir:" + f4_path.mkdirs());//5.mkdir:true
try {
System.out.println("4.createNewFile:" + f4_file.createNewFile());//5.createNewFile:true
} catch (IOException e) {
System.out.println("IO异常,创建失败");
}
}
}
public boolean delete():删除文件和目录
案例代码六 File类方法–删除
package com.groupies.base.day13;
import java.io.File;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction File类方法--删除
*
* 相对路径&绝对路径
* 绝对路径:是以盘符开始的路径。d:\\aa\\b.txt
* 相对路径:不以盘符开始。相对于当前的项目而言,在项目的目录下(与src同级目录)。如何显示出来呢?刷新项目就可以了。
*
* 方法摘要&注意事项
* 删除功能
* public boolean delete():删除文件和目录
*
* 注意:
* 如果一个目录中有内容(目录,文件),就不能直接删除。
* 应该先删除目录中的内容,最后才能删除目录。
*
* 需求:
* 1. createNewFile:相对路径创建一个文件a.txt
* 2. mkdir+createNewFile:相对路径创建一个文件cc\\d.txt
* 3. getAbsolutePath:获取项目根目录路径
* 4. delete:相对路径删除a.txt这个文件
* 5. delete: 相对路径删除cc这个目录(先删除d.txt这个文件,再删除cc这个目录)
*/
public class Demo6FileMethodDelete {
public static void main(String[] args) throws InterruptedException, IOException {
//需求1. createNewFile:相对路径创建一个文件a.txt.
File f1 = new File("a.txt");
System.out.println("1.创建一个文件a.txt: " + f1.createNewFile());
//需求2. mkdir+createNewFile:相对路径创建一个文件cc\\d.txt
File f2_path = new File("cc");
File f2_file = new File("cc" + File.separator + "a.txt");
System.out.println("3.创建一个目录cc: " + f2_path.mkdirs());
System.out.println("3.创建一个文件cc\\d.txt: " + f2_file.createNewFile());
//等待10秒
File projectPath = new File("");//参数为空,表示当前项目根目录
System.out.println("全部创建完毕,请进入 " + projectPath.getAbsolutePath() + " 目录查看文件,15秒后开始删除");
Thread.sleep(15000);//线程等待15秒
//需求4.delete:相对路径删除a.txt这个文件
File f4 = new File("a.txt");
System.out.println("删除a.txt: " + f4.delete());
//需求5. delete: 相对路径删除cc这个目录(先删除d.txt这个文件,再删除cc这个目录)
File f5_file = new File("cc" + File.separator + "a.txt");
File f5_path = new File("cc");
System.out.println("删除cc\\a.txt文件: " + f5_file.delete());
System.out.println("删除cc目录: " + f5_path.delete());
}
}
/**
* @introduction 遍历File目录,删除所有文件
* @param f
*/
public static void deleteFile(File f) {//传一个File对象f进去 因为要调用其方法
if (f != null) {//判断f数据是否为空 因为可能有人会传null值进来
if (f.exists()) {//判断该抽象路径的目录和文件是否存在
if (f.isDirectory()) {//判断是否是目录
File[] listFiles = f.listFiles();//调用listFiles()方法返回一个File对象组成的数组集合
if (listFiles == null) {//如果该数组为Null说明没有文件和目录对象 就是一个空的文件夹
f.delete();//直接删除
} else {//不为空的文件夹
for (File file : listFiles) {//遍历该集合
deleteFile(file);//遍历到的每个File对象传入demo()方法
}
f.delete();//最后将这个不为空的文件夹删除
}
} else {//不是目录可能是是文件或者不存在
f.delete();//直接删除
}
} else {//为Null
return;//结束方法调用
}
}
}
/******a.判断功能******/
//a1.判断是否是目录
public boolean isDirectory()
//a2.判断是否是文件
public boolean isFile()
//a3.判断是否存在
public boolean exists()
/******b.获取功能******/
//b1.获取绝对路径
public String getAbsolutePath()
//b2.获取相对路径
public String getPath()
//b3.获取名称
public String getName()
案例代码七 File类方法–判断、获取
package com.groupies.base.day13;
import java.io.File;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction File类方法--判断、获取
*
* 判断功能
* a. File.isDirectory():判断是否是目录
* b. File.isFile():判断是否是文件
* c. File.exists():判断是否存在
* 获取功能
* d. File.getAbsolutePath():获取绝对路径
* e. File.getPath():获取相对路径
* f. File.getName():获取名称
*/
public class Demo7FileMethodJudgeGet {
public static void main(String[] args) {
//创建File对象
File f = new File("aaa" + File.separator + "bbb.txt");
//判断功能
System.out.println("-----a. File.isDirectory():判断是否是目录-----");
System.out.println(f.isDirectory());//false
System.out.println("-----b. File.isFile():判断是否是文件-----");
System.out.println(f.isFile());//false
System.out.println("-----c. File.exists():判断是否存在-----");
System.out.println(f.exists());//false
System.out.println("-----d. File.getAbsolutePath():获取绝对路径-----");
System.out.println(f.getAbsolutePath());//F:\Data_bak\java\base\aaa\bbb.txt
System.out.println("-----e. File.getPath():获取相对路径-----");
System.out.println(f.getPath());//aaa\bbb.txt
System.out.println("-----f. File.getName():获取名称-----");
System.out.println(f.getName());//bbb.txt
}
}
IO流的分类汇总
//指定输入流
//FileInputStream fis = new FileInputStream(new File("fis.txt"));//效果同下行代码
FileInputStream fis = new FileInputStream("fis.txt");
//a.一次读取一个字符
int by;
//如果fis.read不等于-1说明还有数据,则继续读文件
while ((by = fis.read()) != -1) {
System.out.print((char) by);//打印结果
}
//b.一次读取一个字符数组
byte[] bys = new byte[1024];//每次读取最大bys长度个字节存入数组,长度建议1024或1024的整数倍
int len;//代表有效个数
//将数据读取到数组中, 并用len记录读取到的有效字节个数
//fis.read(bys)=>读取一次bys长度内容写入bys(每次覆盖之前内容),如果剩余文件内容不足以写满bys,(长度1024,剩余1000字节)则bys中最后字节(24字节)保持上一次写入的内容 => 所以每次要截取new String(bys,0,len),避免读到上一次剩余的内容
while ((len = fis.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));//打印结果
}
//释放资源
fis.close();
//字节流一次读写一个数组的速度比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓冲区流
//Q:为什么字节缓冲流的构造方法需要传入一个In/OutputStream
//A:字节缓冲区流仅仅提供缓冲区,而真正的底层的读写数据还得需要基本的流对象进行操作。
//指定输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("name.txt"));
//a.一次读取一个字符(不能读取中文,中文一般2-4字节,一个一个字节读会乱码)
int by;
while ((by = bis.read()) != -1) {
System.out.print((char) by);
}
//b.一次读取一个字符数组
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));
}
//释放资源
bis.close();
//指定输出流
//FileOutputStream fos = new FileOutputStream(new File("fos.txt"));//效果同下行代码
//FileOutputStream fos = new FileOutputStream("fos.txt" , false);//false表示不追加文件->每次写入覆盖之前的内容
FileOutputStream fos = new FileOutputStream("fos.txt");
FileInputStream fis = new FileInputStream("fis.txt");
//a.一次写入一个字符(不能读取中文,中文一般2-4字节,一个一个字节读会乱码)
int by;
while ((by = fis.read()) != -1) {
System.out.print((char) by);//打印结果
}
//b.一次写入一个字符数组
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
//释放资源
fos.close();
fis.close();
//字节流一次读写一个数组的速度比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓冲区流
//Q:为什么字节缓冲流的构造方法需要传入一个In/OutputStream
//A:字节缓冲区流仅仅提供缓冲区,而真正的底层的读写数据还得需要基本的流对象进行操作。
//指定输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
//a.一次读取一个字符
int by;
while ((by = bis.read()) != -1) {
bos.write(by);//写入字符串
bos.flush();//刷新该流的缓冲,写入文件
}
//b.一次读取一个字符数组
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
System.out.println(new String(bytes,0,len));
bos.write(bytes,0,len);//写入字符串
bos.flush();//刷新该流的缓冲,写入文件
}
//释放资源
bis.close();
bos.close();
//指定编码为UTF-8的字符输出流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("source.txt"),"UTF-8");
//指定编码为UTF-8的字符输入流
InputStreamReader isr = new InputStreamReader(new FileInputStream("target.txt"),"UTF-8");
/*
常见的编码表:
ASCII : 美国标准信息交换码, 用一个字节的7位表示数据
ISO-8859-1 : 欧洲码表, 用一个字节的8位表示数据, 兼容ASCII
GB2312 : 中文码表的升级版, 融合了更多的中文文字符号, 兼容ASCII
UTF-8 : 是一种可变长度的字符编码, 用1-3个字节表示数据, 又称为万国码, 兼容ASCII用在网页上可以
统一页面中的中文简体繁体和其他语言的显示.
*/
//指定输入流 目标文件和字符集 ,如果不指定字符集则按照默认编码表 (java7=GBK,java8=UTF-8)
InputStreamReader isr = new InputStreamReader(new FileInputStream(""),"GBK");
//转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流InputStreamReader提供了对应的子类InputStreamReader
/*
(子类)FileWriter:用来写入字符文件的便捷类
(父类)OutputStreamWriter: FileWriter + 默认编码表(java7=GBK,java8=UTF-8)
(子类)FileReader:用来读取字符文件的便捷类
(父类)InputStreamReader: FileReader + 默认编码表(java7=GBK,java8=UTF-8)
*/
//封装数据源
FileReader fr = new FileReader("source.txt");
//封装目的地
FileWriter fw = new FileWriter("target.txt");
//指定输入流
BufferedReader br = new BufferedReader(new FileReader("source.txt"));
//指定输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("target.txt"));
//a.一次读取一个字符
int ch;
while ((ch = br.read()) != -1) {
//对应Unicode编码10进制的值 查询工具 =>
//http://www.mytju.com/classcode/tools/encode_gb2312.asp
System.out.println(ch);
}
//b.一次读取多个字符【注意 换行符也算字符】
char[] bytes = new char[1024];//一次取出1024个字符
int len;//代表有效个数
while((len = br.read(bytes)) != -1)
{
System.out.print(new String(chars, 0, len));//注意是print不是println
}
//c.读取一整行字符串【注意 不包括换行符,需要手动newLine()换行】
//String line = br.readLine();
String line;//代表一整行字符串
//按行读取整篇文章的内容
while((line = br.readLine()) != null)
{
System.out.println(line);
}
//释放资源
br.close();
bw.close();
//指定输出流 目标文件和字符集,如果不指定字符集则按照默认编码表 (java7=GBK,java8=UTF-8)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("target.txt"),"GBK");
//转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流OutputStreamWriter提供了对应的子类FileWriter
/*
(子类)FileWriter:用来写入字符文件的便捷类
(父类)OutputStreamWriter: FileWriter + 默认编码表(java7=GBK,java8=UTF-8)
(子类)FileReader:用来读取字符文件的便捷类
(父类)InputStreamReader: FileReader + 默认编码表(java7=GBK,java8=UTF-8)
*/
//封装数据源
FileReader fr = new FileReader("source.txt");
//封装目的地
FileWriter fw = new FileWriter("target.txt");
//指定输入流
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
//指定输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
//a.一次读取一个字符
int ch;
while ((ch = br.read()) != -1) {
bw.write(ch);//写入字符串
bw.flush();//刷新该流的缓冲,写入文件
}
//b.一次读取多个字符【注意 换行符也算字符】
char[] bytes = new char[1024];//一次取出1024个字符
int len;//代表有效个数
while((len = br.read(bytes)) != -1)
{
bw.write(new String(bytes, 0 , len));//写入字符串
bw.newLine();
bw.flush();//刷新该流的缓冲,写入文件
}
//c.读取一整行字符串【注意 不包括换行符,需要手动newLine()换行】
//String line = br.readLine();
String line;//代表一整行字符串
//按行读取整篇文章的内容
while((line = br.readLine()) != null)
{
bw.write(line);//写入字符串
bw.newLine();
bw.flush();//刷新该流的缓冲,写入文件
}
//释放资源
br.close();
bw.close();
a.字节流 (支持图片等格式的文件,直接用记事本打开文件是看不懂的乱码)
//创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name)
案例代码八 字节流FileOutputStream写出数据
package com.groupies.base.day13;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction 字节流FileOutputStream写出数据
*
* 字节流:
* InputStream 字节输入流
* OutputStream 字节输出流
* 字符流:
* Reader 字符输入流
* Writer 字符输出流
*
* 字节流写数据
* OutputStream:此抽象类是表示输出字节流的所有类的超类
* FileOutputStream:文件输出流是用于将数据写入 File
*
* 构造方法:
* FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。
*
* 字节流写数据的步骤:
* A:创建字节输出流对象
* B:调用写数据的方法
* C:释放资源
*/
public class Demo8FileOutputStream {
public static void main(String[] args) throws IOException {
//创建字节输出流对象 throws FileNotFoundException
FileOutputStream fos = new FileOutputStream("a.txt");
/*
创建字节输出流对象做了3件事
a. 调用File类创建了文件
b. 创建字节输出流对象
c. 让fos这个对象指向a.txt这个文件
*/
//throws IOException (包含FileNotFoundException)
System.out.println("fos.write");
//FileOutputStream.write(int b); b = 十进制的unicode编码
fos.write(65);//A
fos.write(66);//B
System.out.println("写入结束");
//关闭IO流,回收系统资源
fos.close();
}
}
//a.写出数据的三个方法
//一次写一个字节
public void write(int b)
//一次写一个字节数组
public void write(byte[] b)
//一次写一个字节数组的一部分
public void write(byte[] b,int off,int len)
//b.String类中的方法
//将字符串转换为字节数组
byte[] getBytes()
案例代码九 字节流FileOutputStream写数据的三种方式
package com.groupies.base.day13;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction 字节流FileOutputStream写数据的三种方式
*
* A.构造方法的三种方式:
* 1. FileOutputStream(String name)
* 2. FileOutPutStream(File file)
* 3. FileOutPutStream(new File(xxx))
* 4. FileOutputStream(xxx,true) //true=追加数据,默认为false,清空后重新写入数据
*
* B.写数据的三种方式: throws IOException
* 1. FileOutputStream.write(int b):一次写一个字节
* 2. FileOutputStream.write(byte[] b):一次写一个字节数组
* 3. FileOutputStream.write(byte[] b,inf off,int len):一次写一个字节数组的一部分
*
* 字节流写数据的步骤:
* a: 创建字节输出流对象 new FileOutPutStream(String name)
* b: 调用写数据的方法
* c: 释放资源 fos.close()
*/
public class Demo9FileOutPutStreamMethod {
public static void main(String[] args) throws IOException {
//A1. FileOutputStream构造方式1 FileOutputStream(String name)
FileOutputStream fos1 = new FileOutputStream("b.txt");
//A2. FileOutputStream构造方式2 FileOutPutStream(File file)
File f2 = new File("c.txt");
FileOutputStream fos2 = new FileOutputStream(f2);
//A3. FileOutPutStream构造方式3 FileOutPutStream(new File(xxx))
FileOutputStream fos3 = new FileOutputStream(new File("d.txt"));
//B1. 写入数据方式1 FileOutputStream.write(int b):一次写一个字节
//throws IOException
fos1.write(65);
//B2. 写入数据方式2 FileOutputStream.write(byte[] b):一次写一个字节数组
byte[] bys = {65, 66, 67, 68, 69};
fos2.write(bys);
//B3. 写入数据方式3 FileOutputStream.write(byte[] b,inf off,int len):一次写一个字节数组的一部分
fos3.write("ABCDE".getBytes(), 0, 3);
File path = new File("");
System.out.println("文件路径:" + path.getAbsolutePath());
//释放资源
fos1.close();
fos2.close();
fos3.close();
}
}
FIS = FileInPutStream
案例代码十 字节流FileOutputStream写数据换行、追加
package com.groupies.base.day13;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction 字节流FileOutputStream写数据换行、追加
*/
public class Demo10FileOutPutStreamNewLine {
public static void main(String[] args) throws IOException {
//先清空文件
FileOutputStream clear = new FileOutputStream("b.txt");
clear.write("".getBytes());
//如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处(默认为false)
FileOutputStream fos = new FileOutputStream("b.txt", true);
//循环写入三次hello和换行
for (int i = 0; i < 3; i++) {
fos.write("hello".getBytes());
fos.write("\r\n".getBytes());
}
System.out.println("文件路径为:" + new File("").getAbsolutePath());
//释放资源
fos.close();
}
}
FIS = FileInPutStream
//格式
try{
可能发生问题的代码
}catch(){
处理异常代码
}finally{
一定会被执行的代码. // 通常用于释放资源, 做善后的动作
}
案例代码十一 字节流FileOutputStream写数据加入异常处理
package com.groupies.base.day13;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction 字节流FileOutputStream写数据加入异常处理
*
* 格式:
* try{
* 可能发生问题的代码
* }catch(){
* 处理异常代码
* }finally{
* 一定会被执行的代码. // 通常用于释放资源, 做善后的动作
* }
*/
public class Demo11FOSTryCatch {
public static void main(String[] args) {
//fos放在外面是为了在finally中可以关闭
FileOutputStream fos = null;
try {
fos = new FileOutputStream("d.txt");
fos.write("hello".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
//释放资源
try {
fos.close();
} catch (IOException e) {
System.out.println("fos关闭失败");
}
}
}
}
}
FIS = FileInPutStream
案例代码十二 字节流FileInputStream读数据方式1
package com.groupies.base.day13;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction 字节流FileInputStream读数据方式1
*
* 读数据方式1: 一次读取一个字节
* int by;
* while((by=fis.read())!=-1) {
* System.out.print((char)by);
* }
*
* 读数据方式2: 一次读取一个字节数组
* //数组长度为1024或者1024的整数倍
* byte[] bys = new byte[1024];
* int len;
* //将数据读取到数组中, 并用len记录读取到的有效字节个数
* while((len=fis.read(bys))!=-1) {
* //byte --> String new String(bys,0,len)
* System.out.print(new String(bys,0,len));
* }
*/
public class Demo12FileInputStreamType1 {
public static void main(String[] args) throws IOException {
System.out.println("读数据方式1: 一次读取一个字节");
//创建字节输入流对象
FileInputStream fis1 = new FileInputStream("b.txt");//刚才在b.txt写入了3行hello
for (int i = 0; i < 200; i++) {
/*
104 => h
101 => e
108 => l
108 => l
111 => o
13 => \r
10 => \n
...
-1 => 没有数据
-1 => 没有数据
-1 => 没有数据
...
*/
System.out.println(fis1.read());
}
System.out.println("改进为循环方式打印");
FileInputStream fis2 = new FileInputStream("b.txt");//刚才在b.txt写入了10行helloWorld
int by;
//如果fis.read不等于-1说明还有数据,则继续读文件
while ((by = fis2.read()) != -1) {
/*
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
*/
System.out.print((char) by);
}
}
}
/*从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中
返回值是读入缓冲区的字节总数,也就是实际的读取个数
如果因为已经到达文件末尾而没有更多的数据,则返回 -1。*/
public int read(byte[] b):
案例代码十三 字节流FileInputStream读数据方式2
package com.groupies.base.day13;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/23
* @introduction FileInputStream读数据方式2
*
* public int read(byte[] b):
* 从次输入流中将最多b.length 个字节的数据读入一个byte数组中
* 返回值是读入缓冲区的字节总数
*
* 读数据方式1: 一次读取一个字节
* int by;
* while((by=fis.read())!=-1) {
* System.out.print((char)by);
* }
* byte -> String 通过构造方法转换
* String(byte[] bytes)
* String(byte[] bytes,int offset,int length) offset 开始位置;length 截取长度
*
* byte数组长度为1024或者1024的整数倍:
* 1G=1024MB
* 1MB=1024KB
*
* 读数据方式2: 一次读取一个字节数组
* //数组长度为1024或者1024的整数倍
* byte[] bys = new byte[1024];
* int len;
* //将数据读取到数组中, 并用len记录读取到的有效字节个数
* while((len=fis.read(bys))!=-1) {
* //byte --> String new String(bys,0,len)
* System.out.print(new String(bys,0,len));
* }
*/
public class Demo13FileInputStreamType2 {
public static void main(String[] args) throws IOException {
System.out.println("-----读数据方式2: 一次读取一个字节数组-----");
FileInputStream fis1 = new FileInputStream("b.txt");//刚才在b.txt写入了3行hello
//标准代码字符缓冲区bys1长度应为1024或1024的整数倍,这里先用8演示读取的原理
byte[] bys1 = new byte[8];
//第一次读取
int len1 = fis1.read(bys1);
System.out.println(len1);//8
/*
第一次读取: hello
h
*/
System.out.println("第一次读取: " + new String(bys1));
//第二次读取
len1 = fis1.read(bys1);
System.out.println(len1);//8
/*
第二次读取: ello
he
*/
System.out.println("第二次读取: " + new String(bys1));
//第三次读取
len1 = fis1.read(bys1);
System.out.println(len1);//5 => 只读取了5个字符,就返回了5
/*
第三次读取: llo
he
*/
/* 解析:
文件内容为
hello\r\n
hello\r\n
hello\r\n
第一次读取8个字节为 [h] [e] [l] [l] [o] [\r][\n] [h]
第二次读取8个字节为 [e] [l] [l] [o] [\r][\n] [h] [e]
第三次读取8个字节为 [l] [l] [o] [\r][\n]
但数组写入方式是每次覆盖前一次的,所以第二次写入的还保留着
bys[5] = \r
bys[6] = h
bys[7] = e
所以第三次数组内容为 [l] [l] [o] [\r][\n][\n] [h] [e]
所以才会打印出以上内容
*/
System.out.println("第三次读取: " + new String(bys1));
//第四次读取
len1 = fis1.read(bys1);
System.out.println(len1);//-1 => 表示没有数据了
System.out.println("-----改进为循环读取文件-----");
//创建字节输入流对象
FileInputStream fis2 = new FileInputStream("b.txt");
byte[] bys2 = new byte[1024]; //1024或者1024的整数倍
int len2;
//将数据读取到数组中, 并用len记录读取到的有效字节个数
while ((len2 = fis2.read(bys2)) != -1) {
//只读取到len的长度,否则会出现
System.out.print(new String(bys2, 0, len2));
}
System.out.println("\r\n读取结束");
fis2.close();
}
}
《窗里窗外》是林青霞近5年所写的46篇散文的结集,虽是旧作,但该书记录她19岁以《窗外》成名后多方面的人生经历,字字真实深刻。《窗里窗外》共分为六个章节:“戏”里说的是她的出道故事、拍戏的甘苦、对于作品的内心话;“亲”谈她的家人亲情;“友”则书写她与挚友的交往,细谈她与三毛、黄霑、张国荣、龙应台、琼瑶、徐克等人的往来互动;“趣”是她的生活记趣,有旅行见闻,也有她与影迷的邂逅;“缘”则书写她一生难忘的相遇,像是和记者的友谊,和季羡林的会面之缘;“悟”里记录了她对人生的体悟和感动,以及她向圣严法师求道的故事。此外,书中还完整收录了林青霞一些未公开的照片。
第1节:人生小语(1)…
案例代码十四 字节流练习之复制文本文件
package com.groupies.base.day13;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction 字节流练习之复制文本文件
*
* 需求:
* 拷贝文本文件
* 分析:
* 第一步: 创建输入输出流对象关联数据源和数据目的
* 第二步: 定义字节数组,为了提高效率
* 第三步: 将数据通过while循环不断读取到字节数组中
* 第四步: 将数据从字节数组中取出并写出
* 第五步: 释放资源
*/
public class Demo14FileCopy {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("d:" + File.separator + "窗里窗外.txt");
//封装目的地(目标文件,追加true清空重写false)
FileOutputStream fos = new FileOutputStream("d:" + File.separator + "林青霞.txt", false);
//a.一次写入一个字符
int by;
while ((by = fis.read()) != -1) {
fos.write(by);
}
//b.一次写入一个字符数组
byte[] bys = new byte[1024];
int len;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
//释放资源
fos.close();
fis.close();
}
}
案例代码十五 字节流练习之复制图片
package com.groupies.base.day13;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction 字节流练习之复制图片
*/
public class Demo15PictureCopy {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis1 = new FileInputStream("d:" + File.separator + "01_字节流体系图.jpg");
FileInputStream fis2 = new FileInputStream("d:" + File.separator + "01_字节流体系图.jpg");
//封装目的地
FileOutputStream fos1 = new FileOutputStream("d:" + File.separator + "copy1.jpg");
FileOutputStream fos2 = new FileOutputStream("d:" + File.separator + "copy2.jpg");
//读写数据
int by;
//方式1:一次读取一个字节
//如果fis.read不等于-1说明还有数据,则继续读文件
while ((by = fis1.read()) != -1) {
fos1.write(by);
}
//方式2:一次读取一个字节数组
byte[] bys = new byte[1024];
int len;
while ((len = fis2.read(bys)) != -1) {
fos2.write(bys, 0, len);
}
//释放资源
fis1.close();
fis2.close();
fos1.close();
fos2.close();
}
}
a.字节流 (支持图片等格式的文件,直接用记事本打开文件是看不懂的乱码)
案例代码十六 字节缓冲流概述
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/04/27
* @introduction 字节缓冲流
*
* 构造方法
* BufferedOutputStream(OutputStream out)
* BufferedInputStream(InputStream in)
*
* 方法摘要
* BufferedOutputStream.write(byte b[])
*/
public class Demo16BufferedOutputStream {
public static void main(String[] args) throws IOException {
//指定字符缓冲输出流
// FileOutputStream fos = new FileOutputStream("a.txt");
// BufferedOutputStream bos = new BufferedOutputStream(fos);
// 上面的两句等价于下面的这一句
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));
byte[] bytes = "hello".getBytes();
bos.write(bytes);//写入字符数组
bos.close();
//指定字符缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
//方式1 : 一次读取一个字节
int by;
while ((by = bis.read()) != -1) {
System.out.println((char) (by));
}
//方式2 : 一次读取一个字节数组
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
System.out.println(new String(bys, 0, len));
}
//释放资源
bos.close();
bis.close();
}
}
方法摘要
//返回以毫秒为单位的当前时间。
public static long currentTimeMillis()
案例代码十七 字节流&字节缓冲区流四种方式复制AVI并测试效率
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/04/27
* @introduction 字节流&字节缓冲区流四种方式复制AVI并测试效率
*
* 源文件: d:\\复制视频.avi
* 大小: 34904KB
*
* method1: 基本字节流,一次读取一个字节 => method1.avi => 198001毫秒
* method2: 基本字节流,一次读写一个字节数组 => method2.avi => 278毫秒
* method3: 缓冲字节流,一次读取一个字节 => method3.avi => 384毫秒
* method4: 缓冲字节流,一次读写一个字节数组 => method4.avi => 190毫秒
*
* 结论: method4 > method2 > method3 > method1
*/
public class Demo17BufferedOutputStreamCopyAVITest {
public static void main(String[] args) throws IOException {
//记录method1时间
long start1 = System.currentTimeMillis();
method1();//method1共耗时198001毫秒
long end1 = System.currentTimeMillis();
System.out.println("method1共耗时" + (end1 - start1) + "毫秒");
//记录method2时间
long start2 = System.currentTimeMillis();
method2();//method2共耗时278毫秒
long end2 = System.currentTimeMillis();
System.out.println("method2共耗时" + (end2 - start2) + "毫秒");
//记录method3时间
long start3 = System.currentTimeMillis();
method3();//method3共耗时384毫秒
long end3 = System.currentTimeMillis();
System.out.println("method3共耗时" + (end3 - start3) + "毫秒");
//记录method4时间
long start4 = System.currentTimeMillis();
method4();//method4共耗时190毫秒
long end4 = System.currentTimeMillis();
System.out.println("method4共耗时" + (end4 - start4) + "毫秒");
}
//method1: 基本字节流,一次读取一个字节 => method1.avi
private static void method1() throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("d:\\复制视频.avi");
//封装目的地
FileOutputStream fos = new FileOutputStream("d:\\method1.avi");
int by;
while ((by = fis.read()) != -1) {
fos.write(by);
}
//释放资源
fis.close();
fos.close();
}
//method2: 基本字节流,一次读写一个字节数组 => method2.avi
private static void method2() throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("d:\\复制视频.avi");
//封装目的地
FileOutputStream fos = new FileOutputStream("d:\\method2.avi");
byte[] bys = new byte[1024];
int len;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
//释放资源
fis.close();
fos.close();
}
//method3: 缓冲字节流,一次读取一个字节 => method3.avi
private static void method3() throws IOException {
//封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\复制视频.avi"));
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\method3.avi"));
int by;
while ((by = bis.read()) != -1) {
bos.write(by);
}
//释放资源
bis.close();
bos.close();
}
//method4: 缓冲字节流,一次读写一个字节数组 => method4.avi
private static void method4() throws IOException {
//封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\复制视频.avi"));
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\method4.avi"));
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
//释放资源
bis.close();
bos.close();
}
}
c. 转换流 (字符流) = 字节流 + 编码表
案例代码十八 转换流出现的原因
package com.groupies.base.day13;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
/**
* @author GroupiesM
* @date 2021/04/27
* @introduction 转换流出现的原因
*
* 转换流出现的原因
* 由于字节流操作中文不是特别方便,所以,java就提供了转换流
* 转换流 = 字节流 + 编码表
*
* 字节流读数据可能出现问题
* 字节流一次读取一个字节的方式读取带有汉字的文件是有问题的,因为你读取到一个字节后就转为字符在控制台输出了,而汉字是由2个字节组成的,所以这里会出问题。
* 文件复制的时候,字节流读取一个字节,写入一个字节,这个没有出现问题,是因为最终底层会根据字节做拼接,得到汉字。
*
* 汉字存储的规则 : 左边的字节数据肯定是负数,右边的字节数据可能是负数,也可能是正数,大部分情况下是负数。
*
* a.txt内容:
* hi
* 张三
*/
public class Demo18FileInputStream {
public static void main(String[] args) throws IOException {
//基本字节流一次读取一个字节
FileInputStream fis = new FileInputStream("a.txt");
int by;
while ((by = fis.read()) != -1) {
/*
hi
å¼ ä¸‰
*/
System.out.print((char) by);
}
//释放资源,刷新缓冲区
fis.close();
System.out.println("");
String s = "你";
byte[] bys = s.getBytes("GBK");
/*常见的编码表测试 中文"你"转换为字节数组
UTF-8 => [-28, -67, -96] => JDK8中不指定编码则默认为 UTF-8
GBK/GB2312 => [-60, -29] => JDK7中不指定编码则默认为 GBK/GB2312
ISO-8859-1 => [63]
ASCII => [63]
UNICODE/UTF-16 => [-2, -1, 79, 96] => UNICODE 默认使用的是UTF-16的实现方式
*/
System.out.println(Arrays.toString(bys));
}
}
ASCII
‘a’ 97
‘A’ 65
‘0’ 48
常见的编码表
案例代码十九 遍历编码表_int转char
package com.groupies.base.day13;
/**
* @author GroupiesM
* @date 2021/04/27
* @introduction 遍历编码表_int转char
*
* 遍历ASCII码表 0~255
*/
public class Demo19ASCIIFor {
public static void main(String[] args) {
int count = 0;
for (int i = 8; i < 127; i++) {
//每打印5个换行一次
if (count == 5) {
System.out.println("");
count = 0;
}
//13换行一次,否则CR归位键会回到行最左侧位置,导致控制台打印的10-12被吞掉
if (i == 13) {
System.out.println("");
}
char ch = (char) i;
System.out.print("【" + ch + " = " + i + "】\t");
count++;
}
}
/* 8 为/b 退格
13 为\r 归为 导致 【 符号被吞掉
【 = 0】 【 = 1】 【 = 2】 【 = 3】 【 = 4】
【 = 5】 【 = 6】 【 = 7】 = 8】 【 = 9】
【
= 10】 【 = 11】 【 = 12】
= 13】 【 = 14】
【 = 15】 【 = 16】 【 = 17】 【 = 18】 【 = 19】
【 = 20】 【 = 21】 【 = 22】 【 = 23】 【 = 24】
【 = 25】 【 = 26】 【 = 27】 【 = 28】 【 = 29】
【 = 30】 【 = 31】 【 = 32】 【! = 33】 【" = 34】
【# = 35】 【$ = 36】 【% = 37】 【& = 38】 【' = 39】
【( = 40】 【) = 41】 【* = 42】 【+ = 43】 【, = 44】
【- = 45】 【. = 46】 【/ = 47】 【0 = 48】 【1 = 49】
【2 = 50】 【3 = 51】 【4 = 52】 【5 = 53】 【6 = 54】
【7 = 55】 【8 = 56】 【9 = 57】 【: = 58】 【; = 59】
【< = 60】 【= = 61】 【> = 62】 【? = 63】 【@ = 64】
【A = 65】 【B = 66】 【C = 67】 【D = 68】 【E = 69】
【F = 70】 【G = 71】 【H = 72】 【I = 73】 【J = 74】
【K = 75】 【L = 76】 【M = 77】 【N = 78】 【O = 79】
【P = 80】 【Q = 81】 【R = 82】 【S = 83】 【T = 84】
【U = 85】 【V = 86】 【W = 87】 【X = 88】 【Y = 89】
【Z = 90】 【[ = 91】 【\ = 92】 【] = 93】 【^ = 94】
【_ = 95】 【` = 96】 【a = 97】 【b = 98】 【c = 99】
【d = 100】 【e = 101】 【f = 102】 【g = 103】 【h = 104】
【i = 105】 【j = 106】 【k = 107】 【l = 108】 【m = 109】
【n = 110】 【o = 111】 【p = 112】 【q = 113】 【r = 114】
【s = 115】 【t = 116】 【u = 117】 【v = 118】 【w = 119】
【x = 120】 【y = 121】 【z = 122】 【{ = 123】 【| = 124】
【} = 125】 【~ = 126】
*/
}
方法摘要
编码 : 把看得懂的变成看不懂的
//使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
解码 : 把看不懂的变成看得懂的
//通过使用指定的 charset解码指定的 byte 数组,构造一个新的 String。
public String(byte[] bytes, String charsetName)
案例代码二十 String 类的编解码
package com.groupies.base.day13;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
/**
* @author GroupiesM
* @date 2021/04/28
* @introduction String 类的编解码
*
* 方法摘要
* a.编码 : 把看得懂的变成看不懂的
* 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
* public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
*
* b.解码 : 把看不懂的变成看得懂的
* 通过使用指定的 charset解码指定的 byte 数组,构造一个新的 String。
* public String(byte[] bytes, String charsetName)
*
* 常见的编码表测试 中文"你"转换为字节数组
* UTF-8 => [-28, -67, -96] => JDK8中不指定编码则默认为 UTF-8
* GBK/GB2312 => [-60, -29] => JDK7中不指定编码则默认为 GBK/GB2312
* ISO-8859-1 => [63]
* ASCII => [63]
* UNICODE/UTF-16 => [-2, -1, 79, 96] => UNICODE 默认使用的是UTF-16的实现方式
*/
public class Demo20StringEncodeDecode {
public static void main(String[] args) throws UnsupportedEncodingException {
//定义一个字符串
String s = "你好";
//a.编码 getBytes => throws UnsupportedEncodingException 不支持的编码异常
byte[] encodeGBK = s.getBytes("GBK");
System.out.println(Arrays.toString(encodeGBK));//[-60, -29, -70, -61]
byte[] encodeUTF = s.getBytes("UTF-8");
System.out.println(Arrays.toString(encodeUTF));//[-28, -67, -96, -27, -91, -67]
//b.解码
byte[] bytesGBK = {-60, -29, -70, -61};
String decodeGBK = new String(bytesGBK);
//Java8默认编解码字符集为UTF8 用UTF8解码 GBK编码的字节码文件就会出现乱码
System.out.println(decodeGBK);//���
String decodeGBKAgain = new String(bytesGBK, "GBK");
//指定用GBK解码
System.out.println(decodeGBKAgain);//你好
byte[] bytesUTF = {-28, -67, -96, -27, -91, -67};
//不指定解码字符集,Java8环境默认使用UTF8字符集进行编解码,刚好和字节数组匹配
String decodeUTF = new String(bytesUTF);
System.out.println(decodeUTF);//你好
}
}
//根据【默认编码】把字节流的数据转换为字符流
public OutputStreamWriter(OutputStream out)
//根据【指定编码】把字节流数据转换为字符流
public OutputStreamWriter(OutputStream out,String charsetName)
//用【默认编码】读数据
public InputStreamReader(InputStream in)
//用【指定编码】读数据
public InputStreamReader(InputStream in,String charsetName)
IDEA设置文件编码
查看文件结果显示是乱码,原因是输出时指定编码为GBK,java8查看默认编码为UTF-8,需要修改文件解码格式
选择 File => File Properties => File Encoding
选择GBK
重新查看文件内容,显示已正常
案例代码二十一 Stream转换流的编解码
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/04/28
* @introduction Stream转换流的编解码
*
* OutputStreamWriter 字符输出流
* public OutputStreamWriter(OutputStream out) 根据【默认编码】把字节流的数据转换为字符流
* public OutputStreamWriter(OutputStream out,String charsetName) 根据【指定编码】把字节流数据转换为字符流
*
* InputStreamReader** 字符输入流
* public InputStreamReader(InputStream in) 用【默认编码】读数据
* public InputStreamReader(InputStream in,String charsetName) 用【指定编码】读数据
*/
public class Demo21StreamEncodeDecode {
public static void main(String[] args) throws IOException {
//指定输出流 目标文件和字符集
OutputStreamWriter oswGBK = new OutputStreamWriter(new FileOutputStream("osw.txt"), "GBK");
//指定输入流 目标文件和字符集
InputStreamReader isrGBK = new InputStreamReader(new FileInputStream("osw.txt"), "GBK");
InputStreamReader isrUTF = new InputStreamReader(new FileInputStream("osw.txt"), "utf-8");
//调用写数据的方法
oswGBK.write("你好");
oswGBK.flush();//刷新缓冲流(执行一次写入)
//用GBK解码GBK文本
int byGBK;
while ((byGBK = isrGBK.read()) != -1) {
System.out.print((char) byGBK);//你好
}
System.out.println("");
//用UTF-解码GBK文本
int byUTF;
while ((byUTF = isrUTF.read()) != -1) {
System.out.print((char) byUTF);//���
}
//释放资源
oswGBK.close();
isrGBK.close();
isrUTF.close();
}
}
d. 字符流 (字符流数据通过Windows自带的记事本软件打开是可以读懂里面内容的)
案例代码二十二 字符流 复制java文件
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/04/28
* @introduction 字符流 复制Java文件
*
* 需求 : 把项目目录下的 StringDemo.java内容复制到项目目录下的Copy.java中
*
* 三种方式:
* √ 1.字符流 InputStreamReader & OutputStreamWriter
* √ 2.字符流 FileReader & FileWriter
* x 3.字符缓冲区流 BufferedReader & BufferedWriter
*/
public class Demo22StreamCopyJava {
public static void main(String[] args) throws IOException {
long start1 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
method1("StringDemo.java","Copy.java");//method1共耗时2153毫秒
}
long end1 = System.currentTimeMillis();
System.out.println("method1共耗时" + (end1 - start1) + "毫秒");
long start2 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
method2("StringDemo.java","Copy.java");
}
long end2 = System.currentTimeMillis();
System.out.println("method2共耗时" + (end2 - start2) + "毫秒");//method2共耗时1957毫秒
}
/**
* @introduction InputStreamReader & OutputStreamWriter
* 需求 : 把项目目录下的 StringDemo.java内容复制到项目目录下的Copy.java中
* 数据源 : StringDemo.java---读数据---字符流---InputStreamReader
* 目的地 : Copy.java---写数据---字符流---OutputStreamWriter
*
* @param source 数据源
* @param target 目标数据
* @throws IOException
*/
public static void method1(String source, String target) throws IOException {
//封装数据源
InputStreamReader isr = new InputStreamReader(new FileInputStream(source));
//封装目的地
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(target));
//读写数据
//方式1:一次读写一个字符
/*
int ch;
while((ch= isr.read())!=-1){
osw.write(ch);
}
*/
//方式2:一次读写一个字符数组
char[] chArr = new char[1024];
int len;
while ((len = isr.read(chArr)) != -1) {
osw.write(chArr,0,len);
}
//释放资源
osw.close();
isr.close();
}
/**
* @introduction 优化method1 FileReader & FileWriter
* 需求 : 把项目目录下的 StringDemo.java内容复制到项目目录下的Copy.java中(改进版)
* 转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类
*
* (子类)FileWriter:用来写入字符文件的便捷类
* (父类)OutputStreamWriter: FileWriter + 默认编码表(java7=GBK,java8=UTF-8)
*
* (子类)FileReader:用来读取字符文件的便捷类
* (父类)InputStreamReader: FileReader + 默认编码表(java7=GBK,java8=UTF-8)
*
* OutputStreamWriter = FileOutputStream + 默认编码表(java7=GBK,java8=UTF-8)
* FileWriter = FileOutputStream + 默认编码表(java7=GBK,java8=UTF-8)
* 构造方法:
* FileWriter(String fileName)
*
* InputStreamReader = FileInputStream + 默认编码表(java7=GBK,java8=UTF-8)
* FileReader = FileInputStream + 默认编码表(java7=GBK,java8=UTF-8)
* 构造方法:
* FileReader(String fileName)
*
* @param source 数据源
* @param target 目标数据
* @throws IOException
*/
public static void method2(String source, String target) throws IOException {
//封装数据源
FileReader fr = new FileReader(source);
//封装目的地
FileWriter fw = new FileWriter(target);
//读写数据
//方式1:一次读写一个字符
/* int ch;
while((ch= fr.read())!=-1){
fw.write(ch);
}*/
//方式2:一次读写一个字符数组
char[] chArr = new char[1024];
int len;
while ((len = fr.read(chArr)) != -1) {
fw.write(chArr,0,len);
}
//释放资源
fw.close();
fr.close();
}
}
方法摘要
/* @introduction 写一个字符
* @param c 要写入的字符
*/
public void write(char c)
/* @introduction 写一个字符
* @param c 要写入的字符对应码表中int值
*/
public void write(int c)
/* @introduction 写一个字符数组
* @param cbuf 要写入的字符数组
*/
public void write(char[] cbuf)
/* @introduction 写一个字符数组的一部分
* @param cbuf 要写入的字符数组
* @param off 起始索引
* @param len 从起始索引起,写入字符数组长度
*/
public void write(char[] cbuf,int off,int len)
/* @introduction 写一个字符串
* @param str 要写入的字符串
*/
public void write(String str)
/* @introduction 写一个字符串的一部分
* @param str 要写入的字符串
* @param off 起始索引
* @param len 从起始索引起,写入字符串长度
*/
public void write(String str,int off,int len)
案例代码二十三 OutputStreamWriter写数据的6种方式
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/04/28
* @introduction OutputStreamWriter写数据的6种方式
*
* a. public void write(char c); 写一个字符
* b. public void write(int c); 写一个字符
* c. public void write(char[] cbuf); 写一个字符数组
* d. public void write(char[] cbuf,int off,int len); 写一个字符数组的一部分
* e. public void write(String str); 写一个字符串
* f. public void write(String str,int off,int len); 写一个字符串的一部分
*
* void flush():刷新该流的缓冲
* 调用close();时也会调用flush();但close()后无法继续写入
* 字节流可以直接写入,但字符流需要刷新缓冲
* 因为字符会先写入字符流缓冲区(内存),到字符流缓冲区满了才会写入一次文件
* 缓冲区写满之前需要手动flush()或调用close()才会将缓冲区字符写入目标文件(硬盘)
*
*/
public class Demo23OutputStreamWriter6Type {
public static void main(String[] args) throws IOException {
//创建字符输出流对象 (同时创建文件)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("target.txt"));
//a. public void write(char c); 写一个字符
methodA(osw);//写入一个字符a
osw.write('\r');//换行
//b. public void write(int c); 写一个字符
methodB(osw);//写入一个字符b
osw.write('\r');//换行
//c. public void write(char[] cbuf); 写一个字符数组
methodC(osw);//写入abcde
osw.write('\r');//换行
//d. public void write(char[] cbuf,int off,int len); 写一个字符数组的一部分
methodD(osw);//写入c
osw.write('\r');//换行
//e. public void write(String str); 写一个字符串
methodE(osw);//写入hello
osw.write('\r');//换行
//f. public void write(String str,int off,int len); 写一个字符串的一部分
methodF(osw);//写入lo
osw.write('\r');//换行
//释放资源
osw.close();//关闭此流,关闭前将缓冲区(内存)字符刷新(flush=>写入硬盘)
}
/**
* @introduction OutputStreamWriter写数据方式1:写一个字符
* @param osw
* @throws IOException
*/
public static void methodA(OutputStreamWriter osw) throws IOException {
//a. public void write(char c); 写一个字符
osw.write('a');
//void flush():刷新该流的缓冲
//osw.flush();
}
/**
* @introduction OutputStreamWriter写数据方式2:写一个字符
* @param osw
* @throws IOException
*/
public static void methodB(OutputStreamWriter osw) throws IOException {
//b. public void write(int c); 写一个字符
osw.write(98);
//void flush():刷新该流的缓冲
//osw.flush();
}
/**
* @introduction OutputStreamWriter写数据方式3:写一个字符数组
* @param osw
* @throws IOException
*/
public static void methodC(OutputStreamWriter osw) throws IOException {
char[] chs = {'a', 'b', 'c', 'd', 'e' };
//c. public void write(char[] cbuf); 写一个字符数组
osw.write(chs);//写入 abcde
//void flush():刷新该流的缓冲
//osw.flush();
}
/**
* @introduction OutputStreamWriter写数据方式4:写一个字符数组的一部分
* @param osw
* @throws IOException
*/
public static void methodD(OutputStreamWriter osw) throws IOException {
char[] chs = {'a', 'b', 'c', 'd', 'e' };
//d. public void write(char[] cbuf,int off,int len); 写一个字符数组的一部分
osw.write(chs, 2, 1);//写入bcd
//void flush():刷新该流的缓冲
//osw.flush();
}
/**
* @introduction OutputStreamWriter写数据方式5:写一个字符串
* @param osw
* @throws IOException
*/
public static void methodE(OutputStreamWriter osw) throws IOException {
String s = "hello";
//e. public void write(String str); 写一个字符串
osw.write(s);//写入hello
//void flush():刷新该流的缓冲
//osw.flush();
}
/**
* @introduction OutputStreamWriter写数据方式6:写一个字符串的一部分
* @param osw
* @throws IOException
*/
public static void methodF(OutputStreamWriter osw) throws IOException {
String s = "hello";
//f. public void write(String str,int off,int len); 写一个字符串的一部分
osw.write(s, 3, 2);
//void flush():刷新该流的缓冲
//osw.flush();
}
}
方法摘要
//一次读取一个字符
public int read()
//一次读取一个字符数组
public int read(char[] cbuf)
案例代码二十四 InputStreamReader读数据的2种方式
package com.groupies.base.day13;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author GroupiesM
* @date 2021/04/28
* @introduction InputStreamReader读数据的2种方式
*
* a. public int read(); 一次读取一个字符
* b. public int read(char[] cbuf); 一次读取一个字符数组
*/
public class Demo24InputStreamReader2Type {
public static void main(String[] args) throws IOException {
//创建字符流输入对象
InputStreamReader isrA = new InputStreamReader(new FileInputStream("a.txt"));
InputStreamReader isrB = new InputStreamReader(new FileInputStream("a.txt"));
//a. public int read(); 一次读取一个字符
methodA(isrA);
System.out.println("\r\n==========================");
//b. public int read(char[] cbuf); 一次读取一个字符数组
methodB(isrB);
//释放资源
isrA.close();
isrB.close();
}
/**
* @introduction InputStreamReader读数据方式1:一次读取一个字符
* @param isr
* @throws IOException
*/
public static void methodA(InputStreamReader isr) throws IOException {
int ch;
while ((ch = isr.read()) != -1) {
System.out.print((char)ch);
}
}
/**
* @introduction InputStreamReader读数据方式2:一次读取一个字符数组
* @param isr
*/
public static void methodB(InputStreamReader isr) throws IOException {
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs)) != -1) {
System.out.println(new String(chs, 0, len));
}
}
}
d. 字符流 (字符流数据通过Windows自带的记事本软件打开是可以读懂里面内容的)
BufferedWriter(Writer out)
BufferedReader(Reader in)
案例代码二十五 字符缓冲区流概述
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/05/08
* @introduction 字符缓冲区流概述
*
* BufferedWriter
* 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
* 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
* 构造方法:
* BufferedWriter(Writer out)
* BufferedReader
* 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
* 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
* 构造方法:
* BufferedReader(Reader in)
*/
public class Demo25Buffered {
public static void main(String[] args) throws IOException {
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
//调用写数据的方法
bw.write("hello");
//释放资源
bw.close();
//创建字符缓冲输入流对象
BufferedReader br1 = new BufferedReader(new FileReader("BufferedStreamDemo.java"));
BufferedReader br2 = new BufferedReader(new FileReader("BufferedStreamDemo.java"));
//方式1:一次读取一个字符
method1(br1);
//方式2:一次读取一个字符数组
method2(br2);
//释放资源
br1.close();
br2.close();
}
/**
* @introduction 方式1:一次读取一个字符
* @param br
* @throws IOException
*/
public static void method1(BufferedReader br) throws IOException {
int ch;
while((ch=br.read())!=-1) {
System.out.print((char)ch);
}
}
/**
* @introduction 方式2:一次读取一个字符数组
* @param br
* @throws IOException
*/
public static void method2(BufferedReader br) throws IOException {
char[] chs = new char[1024];
int len;
while ((len = br.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
}
}
案例代码二十六 字符缓冲区流 复制文本文件
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/04/28
* @introduction 字符缓冲区流 复制文本文件
*
* 需求 : 把项目目录下的a.txt内容复制到项目目录下的b.txt中
* 数据源 : a.txt---读数据---字符流---InputStreamReader---FileReader---BufferedReader
* 目的地 : b.txt---写数据---字符流---OutputStreamWriter---FileWriter---BufferedWriter
*/
public class Demo26StreamCopyTXT {
public static void main(String[] args) throws IOException {
//封装数据源
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
//封装目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
//读写数据
char[] chs = new char[1024];
int len;
while ((len = br.read(chs)) != -1) bw.write(chs, 0, len);
//释放资源
bw.close();
br.close();
}
}
需求
三种方式
案例代码二十七 字符缓冲区流 复制Java文件
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/05/08
* @introduction 字符缓冲区流复制Java文件
*
* 需求 : 把项目目录下的StringDemo.java内容复制到项目目录下的Copy.java中
*
* 三种方式:
* x 1.字符流 InputStreamReader & OutputStreamWriter
* x 2.字符流 FileReader & FileWriter
* √ 3.字符缓冲区流 BufferedReader & BufferedWriter
*/
public class Demo27BufferedCopyJava {
public static void main(String[] args) throws IOException {
long start3 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
method3("StringDemo.java","Copy.java");
}
long end3 = System.currentTimeMillis();
System.out.println("method3共耗时" + (end3 - start3) + "毫秒");//method3共耗时2840毫秒
}
/**
* @introduction BufferedReader & BufferedWriter
* 需求 : 把项目目录下的 StringDemo.java内容复制到项目目录下的Copy.java中
* 数据源 : StringDemo.java---读数据---字符流---InputStreamReader---FileReader---BufferedReader
* 目的地 : Copy.java---写数据---字符流---OutputStreamWriter---FileWriter---BufferedWriter
*
* @param source 数据源
* @param target 目标数据
* @throws IOException
*/
public static void method3(String source,String target) throws IOException {
//封装数据源
BufferedReader br = new BufferedReader(new FileReader(source));
//封装目的地
BufferedWriter bw = new BufferedWriter(new FileWriter(target));
//读写数据
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
}
BufferedWriter
//写入一个行分隔符,这个行分隔符是由系统决定的
void newLine()
BufferedReader
//包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
String readLine()
案例代码二十八 字符缓冲区流 特殊功能
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/05/08
* @introduction 字符缓冲区流 特殊功能
*
* BufferedWriter
* a. void newLine():写入一个行分隔符,这个行分隔符是由系统决定的
*
* BufferedReader
* b. String readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
*/
public class Demo28BufferedMethod {
public static void main(String[] args) throws IOException {
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
//写数据
for (int x = 0; x < 3; x++) {
bw.write("hello");
//a. void newLine():写入一个行分隔符,这个行分隔符是由系统决定的
bw.newLine();//等价于 <=> bw.write("\r\n");
bw.flush();
}
//释放资源
bw.close();
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
//创建line对象接收每一行数据
String line;
//b. String readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
while ((line = br.readLine()) != null) {
/*
hello
hello
hello
*/
System.out.println(line);
}
//释放资源
br.close();
}
}
//4.1 根据给定的URI来确定文件路径
public static Path get(URI uri)
//5.1 复制文件
public static long copy(Path source,OutputStream out)
//5.2 把集合的数据写到文件
public static Path write(Path path,Iterable<? extends CharSequence> lines,
Charset cs, OpenOption... options)
案例代码二十九 nio(new IO)简化代码
package com.groupies.base.day13;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
/**
* @author GroupiesM
* @date 2021/06/15
* @introduction nio(new IO)简化代码
*/
public class Demo29NIO {
public static void main(String[] args) throws IOException {
//5.1 复制文件
Files.copy(Paths.get("a.txt"), new FileOutputStream("copyA.txt"));
ArrayList<String> array = new ArrayList<>();
array.add("hello");
array.add("world");
array.add("java");
//5.2 把集合的数据写到文件
Files.write(Paths.get("array.txt"), array, Charset.forName("UTF-8"));
}
}
练习1 Scanner通过Buffer写入文件
package com.groupies.base.day13;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction 课后基础练习1 Scanner通过Buffer写入文件
*
* 需求:请用户从控制台输入信息,程序将信息存储到文件Info.txt中。
* 可以输入多条信息,每条信息存储一行。当用户输入:”886”时,程序结束。
*
* 123456
* abcdef
* 886
*/
public class HomeWork1Buffer {
public static void main(String[] args) throws IOException {
//1.指定输出流,对应的文件Info.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("Info.txt"));
//2.采用循环的方式,把每条信息存储到一行的Info.txt中
Scanner sc = new Scanner(System.in);
while (true){
//获取键盘输入的一行内容
System.out.println("请输入内容:");
String next = sc.next();
//当用户输入886时,程序结束
if(next.equals("886")) break;
//把内容写入到Info.txt中
bw.write(next);//写入字符串
bw.newLine();//写入一个行分隔符
//bw.flush();//刷新该流的缓冲(可以省略,最后close的时候会自带一次flush)
}
bw.close();
}
}
练习2 Scanner接收学生信息写入文件 【a.实体学生类】
package com.groupies.base.day13;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction
*/
public class HomeWork2POJOStudent {
private String id;
private String name;
private String gender;
private int age;
public HomeWork2POJOStudent(String id, String name, String gender, int age) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "{id='" + id + "'" + ", name='" + name + "'" + ", gender='" + gender + "'" + ", age=" + age + '}';
}
}
练习2 Scanner接收学生信息写入文件 【b.测试类】
package com.groupies.base.day13;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction 测试类 课后基础练习2 Scanner接收学生信息写入文件
*
* 需求:
* 从控制台接收3名学员的信息,每条进行存储到一个Student对象中,
* 将多个Student对象存储到一个集合中。输入完毕后,将所有学员信息存储到文件Student.txt中。
* 每名学员信息存储一行,多个属性值中间用逗号隔开。
* 分析:
* 1. 创建Student类,有如下属性:
* 学号、姓名、性别、年龄
* 全部属性使用String类型。要求有无参,全参构造方法。所有属性私有,并提供公有get/set方法。
* 2. 创建MainApp类,包含main()方法
* 3. 在main()方法中:
* 1) 定义一个存储Student对象的集合;
* 2) 循环3次,从控制台接收3名学员信息,每条信息封装一个Student对象,将每个Student对象存储到集合中。
* 3) 遍历集合,获取每个Student对象,取出所有属性值,输出到文件Test2_2.txt中。每名学员信息占一行。
*/
public class HomeWork2Buffer {
public static void main(String[] args) throws IOException {
//PrintWriter pw = new PrintWriter(new );
Scanner sc = new Scanner(System.in);
ArrayList<String[]> list = new ArrayList<>();
int forCount = 0;//用于循环计数
for (int i = 1; i < 4; i++) {
System.out.println("请输入第" + i + "学生信息,用逗号分隔(学号,姓名,性别,年龄)");
String strStudent = sc.next();
int commaCount = 0;//逗号计数
//校验1:判断字符串是否包含三个逗号
String temp = strStudent;
while (temp.contains(",")) {
temp = temp.substring(temp.indexOf(",") + 1);
commaCount++;
}
//如果不是三个逗号则重新输入
if (commaCount != 3) {
System.out.println("输入信息有误,请重新输入");
i--;
continue;
}
//校验2:判断输入的年龄是否为合法数字
String[] splitStudent = strStudent.split(",");
try {
Integer.parseInt(splitStudent[3]);
} catch (NumberFormatException e) {
System.out.println("输入年龄有误,请输入正确数字");
i--;
continue;
}
//将学生信息暂时放入数组缓存
list.add(splitStudent);
}
//创建字符流目标对象
BufferedWriter bw = new BufferedWriter(new FileWriter("student.txt"));
//遍历list数组中的学生信息
for (String[] sInfo : list) {
bw.write(new HomeWork2POJOStudent(sInfo[0], sInfo[1], sInfo[2], Integer.parseInt(sInfo[3])).toString());//写入字符串
bw.newLine();//写入一个行分隔符
bw.flush();//刷新该流的缓冲
}
//释放资源
bw.close();
}
}
it001,武松,男,22
it002,林冲,男,20
it003,卢俊义,男,18
it004,石宝,男,23
练习3 Buffer读取文件后修改指定内容并写入
package com.groupies.base.day13;
import java.io.*;
import java.util.ArrayList;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction 课后基础练习3 Buffer读取文件后修改指定内容并写入
*
* 需求:
* 将文件name.txt中的数据“卢俊义”修改为:“史文恭”。
* 在项目目录下创建文件name.txt,并写入以下内容:
* it001,武松,男,22
* it002,林冲,男,20
* it003,卢俊义,男,18
* it004,石宝,男,23
*/
public class HomeWork3Buffer {
public static void main(String[] args) throws IOException {
//指定输入流
BufferedReader br = new BufferedReader(new FileReader("name.txt"));
//定义一个数组接收学生信息
ArrayList<String[]> arrayList = new ArrayList<String[]>();
//每次读取内容
String line;
String[] strArr;
boolean b = false;
System.out.println("开始读取文件.....");
while ((line = br.readLine()) != null) {
strArr = line.split(",");
if (strArr[1].equals("卢俊义")) {
System.out.println("检测到【卢俊义】,已修改为【史文恭】");
strArr[1] = "史文恭";
b = true;
}
arrayList.add(strArr);
}
if (!b) System.out.println("未检测到【卢俊义】,无需修改文件");
if (b) {
System.out.println("开始重新写入文件....");
BufferedWriter bw = new BufferedWriter(new FileWriter("name.txt"));
for (String[] sInfo : arrayList) {
bw.write(sInfo[0] + "," + sInfo[1] + "," + sInfo[2] + "," + sInfo[3]);//写入字符串
bw.newLine();//写入一个行分隔符
bw.flush();//刷新该流的缓冲
}
//释放资源
bw.close();
try {
//尝试对此部分代码捕获异常
} catch (Exception e) {
//捕获异常后的处理逻辑
//e.printStackTrace(); //默认处理方式打印异常信息
} finally {
//无论是否捕获异常,都会执行
}
}
}
}
我爱黑马
123456
123456
我爱黑马
练习4 读取文件反转行
package com.groupies.base.day13;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
/**
* @author GroupiesM
* @date 2021/04/25
* @introduction 数组逆序
*
* 需求:
* 项目根路径下有test.txt文件,内容如下:
* 我爱黑马
* 123456
* 利用IO流的知识读取text.txt文件的内容反转后写入test.txt文件中,内容如下:
* 123456
* 我爱黑马
*
* 思路:
* 创建集合,读取内容放入集合
* 反转集合
* 把集合内容写入源文件
* 方法:
* BufferedWriter.write(String); 写入字符串的某一部分。
* BufferedWriter.newLine(); 写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 ('\n') 符。
* BufferedWriter.flush(); 刷新该流的缓冲,也就是会把数据写入到目的文件里。如果没有在里面的for()循环中添加 bw.flush(); 这句话,
* 在循环的时候重新 new BufferedWriter();就把原来bw(缓冲区)中的覆盖掉了。于是就不能写进文件字符。
* BufferedWriter.close(); 关闭此流,关闭流前或默认先调用flush先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。关闭以前关闭的流无效。
*/
public class HomeWork4Buffer {
public static void main(String[] args) throws IOException {
//封装数据源
BufferedReader br = new BufferedReader(new FileReader("d:" + File.separator + "test.txt"));
//定义字符数组,存放读取到的数据
ArrayList<String> list = new ArrayList<String>();
//每次读取到的数据
String line;
while ((line = br.readLine()) != null) {
list.add(line);
}
//反转集合
//方式1:逆向遍历集合 list.fori
/* for (int i = 0; i < list.size() / 2; i++) {
//第一个和最后一个交换,第二个和倒数第二个交换..
String first = list.get(i);
String last = list.get(list.size() - i - 1);
list.set(i, last);//第i个值
list.set(list.size() - i - 1, last);
}*/
//方式2:Collections.revers
Collections.reverse(list);
//封装目标
BufferedWriter bw = new BufferedWriter(new FileWriter("d:" + File.separator + "test.txt"));
//写入数据
for (int i = 0; i < list.size(); i++) {
//写入字符串
//bw.write(list.get(i), 0, list.get(i).length());
bw.write(list.get(i));
//写入一个行分隔符
bw.newLine();
bw.flush();//将缓冲区内容 写入目标文件
}
//释放资源
br.close();
bw.close();
}
}
字符流五种方式
基本字符流 FileReader
基本字符流一次读写一个字符
//method1
int ch;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
基本字符流一次读写一个字符数组
//method2
char[] chs = new char[1024];
int len;
while((len=fr.read(chs))!=-1) {
fw.write(chs, 0, len);
}
缓冲字符流 BufferedReader
缓冲字符流一次读写一个字符
//method3
int ch;
while((ch=br.read())!=-1) {
bw.write(ch);
}
缓冲字符流一次读写一个字符数组
//method4
char[] chs = new char[1024];
int len;
while((len=br.read(chs))!=-1) {
bw.write(chs, 0, len);
}
缓冲字符串一次读写一行
//method5
String line;
while((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
默认编码 JDK7 GBK / JDK8 UTF-8
)练习5 字符流复制文本文件的五种方式
package com.groupies.base.day13;
import java.io.*;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction 字符流复制文本文件的五种方式
*
* 需求:
* 复制文件到指定目录(字符流五种方式)
* 数据源:
* d:\\林青霞.txt
* 目标:
* 窗里窗外.txt
*
*
* 五种方式:
* 基本字符流一次读写一个字符
* 基本字符流一次读写一个字符数组
* 缓冲字符流一次读写一个字符
* 缓冲字符流一次读写一个字符数组
* 缓冲字符串一次读写一行
*
* 注意:
* 因为这五种方法读取数据时不能指定编码,所以写入数据时一定要注意读写编码一致(默认编码 JDK7 GBK / JDK8 UTF-8)
*/
public class HomeWork5CopyTxt {
public static void main(String[] args) throws IOException {
/*
创建数据源 d:\\林青霞.txt
使用java8环境(默认读写字符集为UTF-8)
因为这五种方法读取数据时不能指定编码,所以写入数据时一定要注意读写编码一致(默认编码 JDK7 GBK / JDK8 UTF-8)
*/
createFile();
//基本字符流一次读写一个字符
Long start1 = System.currentTimeMillis();
method1("d:" + File.separator + "林青霞.txt", "窗里窗外1.txt");
Long end1 = System.currentTimeMillis();
System.out.println("method1共耗时:" + (end1 - start1) + "毫秒");//method1共耗时:436毫秒
//基本字符流一次读写一个字符数组
Long start2 = System.currentTimeMillis();
method2("d:" + File.separator + "林青霞.txt", "窗里窗外2.txt");//method2共耗时:43毫秒
Long end2 = System.currentTimeMillis();
System.out.println("method2共耗时:" + (end2 - start2) + "毫秒");
//缓冲字符流一次读写一个字符
Long start3 = System.currentTimeMillis();
method3("d:" + File.separator + "林青霞.txt", "窗里窗外3.txt");//method3共耗时:22毫秒
Long end3 = System.currentTimeMillis();
System.out.println("method3共耗时:" + (end3 - start3) + "毫秒");
//缓冲字符流一次读写一个字符数组
Long start4 = System.currentTimeMillis();
method4("d:" + File.separator + "林青霞.txt", "窗里窗外4.txt");//method4共耗时:22毫秒
Long end4 = System.currentTimeMillis();
System.out.println("method4共耗时:" + (end4 - start4) + "毫秒");
//缓冲字符串一次读写一行
Long start5 = System.currentTimeMillis();
method5("d:" + File.separator + "林青霞.txt", "窗里窗外5.txt");//method5共耗时:22毫秒
Long end5 = System.currentTimeMillis();
System.out.println("method5共耗时:" + (end5 - start5) + "毫秒");
}
/**
* @introduction 创建数据源 d:\\林青霞.txt 供下一步读取使用
* @throws IOException
*/
public static void createFile() throws IOException {
//指定输出流 目标文件和字符集
OutputStreamWriter oswGBKSource = new OutputStreamWriter(new FileOutputStream("d:\\林青霞.txt"), "UTF-8");
oswGBKSource.write("林青霞1\r\n");
oswGBKSource.write("林青霞2\r\n");
oswGBKSource.write("林青霞3\r\n");
oswGBKSource.close();
}
/**
* @introduction 基本字符流一次读写一个字符
* @param source 数据源
* @param target 目标文件
* @throws IOException
*/
private static void method1(String source, String target) throws IOException {
FileReader fr = new FileReader(source);
FileWriter fw = new FileWriter(target);
int ch;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
/**
* @introduction 基本字符流一次读写一个字符数组
* @param source 数据源
* @param target 目标文件
* @throws IOException
*/
private static void method2(String source, String target) throws IOException {
FileReader fr = new FileReader(source);
FileWriter fw = new FileWriter(target);
char[] chs = new char[1024];
int len;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}
fw.close();
fr.close();
}
/**
* @introduction 缓冲字符流一次读写一个字符
* @param source 数据源
* @param target 目标文件
* @throws IOException
*/
private static void method3(String source, String target) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(source));
BufferedWriter bw = new BufferedWriter(new FileWriter(target));
int ch;
while ((ch = br.read()) != -1) {
bw.write(ch);
}
bw.close();
br.close();
}
/**
* @introduction 缓冲字符流一次读写一个字符数组
* @param source 数据源
* @param target 目标文件
* @throws IOException
*/
private static void method4(String source, String target) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(source));
BufferedWriter bw = new BufferedWriter(new FileWriter(target));
char[] chs = new char[1024];
int len;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
bw.close();
br.close();
}
/**
* @introduction 缓冲字符流一次读写一个字符串
* @param source 数据源
* @param target 目标文件
* @throws IOException
*/
private static void method5(String source, String target) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(source));
BufferedWriter bw = new BufferedWriter(new FileWriter(target));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
练习6 字符流-ArrayList到TXT
package com.groupies.base.day13;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction 字符流-ArrayList到TXT
*
* 需求:
* A:创建集合对象
* B:往集合中添加字符串元素
* C:创建字符缓冲输出流对象
* D:遍历集合,得到每一个字符串元素,把字符串元素作为数据写入到文本文件
* E:释放资源
*/
public class HomeWork6ArrayListToTxt {
public static void main(String[] args) throws IOException {
//创建集合对象
ArrayList<String> array = new ArrayList<>();
//往集合中添加字符串元素
array.add("hello");
array.add("world");
array.add("java");
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt"));
//遍历集合,得到每一个字符串元素,把字符串元素作为数据写入到文本文件
for (String s : array) {
bw.write(s);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
}
student.txt
练习7 字符流-TXT到ArrayList
package com.groupies.base.day13;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction
*
* 需求:
* 从文本文件中读取数据到ArrayList集合中,并遍历集合
* 每一行数据作为一个字符串元素
*
* 分析:
* A:创建字符缓冲输入流对象
* B:创建集合对象
* C:读取数据,每一次读取一行,并把该数据作为元素存储到集合中
* D:释放资源
* E:遍历集合
*/
public class HomeWork7TxtToArrayList {
//指定数据源
final static String sourceFile = "array.txt";
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader(sourceFile));
//创建集合对象
ArrayList<String> array = new ArrayList<>();
//读取数据,每次读取一行,并把改数据作为元素存储到集合中
String line;
while ((line = br.readLine()) != null) {
array.add(line);
}
//释放资源
br.close();
//遍历集合
for (String s : array) {
System.out.println(s);
}
}
}
需求
定义一个学生类
it001,张曼玉,35,北京
it002,王祖贤,33,上海
it003,林青霞,30,西安
练习8 Array
package com.groupies.base.day13;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction
*/
public class HomeWork8POJOStudent {
private String id;
private String name;
private int age;
private String location;
public HomeWork8POJOStudent() {
}
public HomeWork8POJOStudent(String id, String name, int age, String location) {
this.id = id;
this.name = name;
this.age = age;
this.location = location;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
/**
* @introduction 逗号分隔学生信息
* @return
*/
@Override
public String toString() {
return id + "," + name + "," + age + "," + location;
}
}
练习8 Array
package com.groupies.base.day13;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction
*/
public class HomeWork8ArrayListToTxt {
//写入目标文件
final static String targetFile = "student.txt";
public static void main(String[] args) throws IOException {
//创建集合对象
ArrayList<HomeWork8POJOStudent> array = new ArrayList<>();
//创建学生对象
HomeWork8POJOStudent s1 = new HomeWork8POJOStudent("it001", "张曼玉", 35, "北京");
HomeWork8POJOStudent s2 = new HomeWork8POJOStudent("it002", "王祖贤", 33, "上海");
HomeWork8POJOStudent s3 = new HomeWork8POJOStudent("it003", "林青霞", 30, "西安");
// 把学生对象添加到集合中
array.add(s1);
array.add(s2);
array.add(s3);
//创建字符缓冲流输出对象
BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile));
//拼接学生信息到字符串中
StringBuilder sb = new StringBuilder();
//遍历集合,得到每一个学生对象,然后把该对象的数据接成一个指定格式的字符串写到文本文件
for (HomeWork8POJOStudent s : array) {
sb.append(s.toString());
sb.append("\r\n");
}
/*
正在将以下信息写入目标文件=>student.txt
it001,张曼玉,35,北京
it002,王祖贤,33,上海
it003,林青霞,30,西安
*/
System.out.println("正在将以下信息写入目标文件=>" + targetFile);
System.out.println(sb);
bw.write(sb.toString());
//刷新缓存并释放资源 flush
bw.close();
}
}
it001,张曼玉,35,北京
it002,王祖贤,33,上海
it003,林青霞,30,西安
student.txt
练习9 Array
package com.groupies.base.day13;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction
*/
public class HomeWork9POJOStudent {
private String id;
private String name;
private int age;
private String location;
public HomeWork9POJOStudent() {
}
public HomeWork9POJOStudent(String id, String name, int age, String location) {
this.id = id;
this.name = name;
this.age = age;
this.location = location;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@Override
public String toString() {
return "{" + "id='" + id + "', name='" + name + "', age=" + age + ", location='" + location + "'" + '}';
}
}
练习9 Array
package com.groupies.base.day13;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author GroupiesM
* @date 2021/05/10
* @introduction
*/
public class HomeWork9TxtToArrayList {
//指定数据源
final static String sourceFile = "student.txt";
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader(sourceFile));
//创建集合对象
ArrayList<HomeWork9POJOStudent> array = new ArrayList<>();
//读取数据,每次读取一行数据,把该行业数据想办法封装成学生对象,并把学生对象存储到集合中
String line;
HomeWork9POJOStudent student;
while ((line = br.readLine()) != null) {
//按逗号分隔字符串对象,存入字符数组
String[] strArray = line.split(",");
student = new HomeWork9POJOStudent();
student.setId(strArray[0]);
student.setName(strArray[1]);
student.setAge(Integer.parseInt(strArray[2]));
student.setLocation(strArray[3]);
array.add(student);
}
// 释放资源
br.close();
// 遍历集合
for (HomeWork9POJOStudent s : array) {
/*
{id='it001', name='张曼玉', age=35, location='北京'}
{id='it002', name='王祖贤', age=33, location='上海'}
{id='it003', name='林青霞', age=30, location='西安'}
*/
System.out.println(s.toString());
}
}
}
21/05/10
M