==主要部分:IO流的分类,字节流和字符流的区别,io流的实际应用,熟悉io流的常见方法,异常处理==
一、概念题
-
流是什么
-
io流的分类,以及各个流的特性
-
字节流和字符流的区别,简要描述
-
什么是Java序列化,如何实现Java序列化?(深浅拷贝)
下面代码展示Java的序列化与反序列化:
@SuppressWarnings({"all"}) class Dog implements Serializable{//如果要序列化某个对象,必须实现 Serializable 接口 private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public int getAge() { return age; } } @SuppressWarnings({"all"})//镇压警告 public class TestIO { public static void main(String[] args) throws Exception{ ObjectOutputStreamTest(); ObjectInputStreamTest(); } //演示ObjectInputStream的数据反序列化 public static void ObjectInputStreamTest() throws Exception{ //数据反序列化文件 String filepath="D:\\date.dat"; ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filepath)); //反序列化数据读取顺序必须与序列化保存时顺序相同!!!! 否则会出现异常 System.out.println(objectInputStream.readInt()); System.out.println(objectInputStream.readBoolean()); System.out.println(objectInputStream.readChar()); System.out.println(objectInputStream.readUTF()); //System.out.println(objectInputStream.readObject()); 将会抛出异常!!! Object dog =objectInputStream.readObject(); System.out.println("Object o 运行类型"+dog.getClass()); System.out.println("dog 信息:"+dog); objectInputStream.close();//记得关流 System.out.println("数据读出成功!!!"); //试着调用dog的get方法 //由于此时的dog时Object类的,调用get方法需要进行向下转型 Dog dog1=(Dog) dog; System.out.println("名字:"+dog1.getName()); System.out.println("年龄:"+dog1.getAge()); } //演示ObjectOutputStream的数据序列化 public static void ObjectOutputStreamTest() throws Exception{ //序列化后,文件保存格式不是文本,而是按照他自己的格式来保存 String filepath="D:\\date.dat"; ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(filepath)); //Java 的序列化不能对 static 和 transient(短暂的)修饰的属性进行保存 // 也就是说Java 不能序列化tatic 和 transient(短暂的)修饰的属性 //序列化数据到D:\\date.dat oos.writeInt(129);//int -> Integer (实现了 Serializable) oos.writeBoolean(true);//boolean -> Boolean (实现了 Serializable) oos.writeChar('K');//char ->Character (实现了 Serializable) oos.writeUTF("马俊毅.JAVA");//String //保存一个Dog 对象 构造Dog类 oos.writeObject(new Dog("旺财",4)); oos.close();//关流 System.out.println("数据保存完毕!!!"); }
运行示例:
-
缓冲区的原理
-
缓读缓写
利用缓读缓写复制文件:
public class TestIO { public static void main(String[] args) throws Exception{ InputStreamTest(); } //文件字节流转字符流复制 public static void InputStreamTest(){ BufferedInputStream in=null; PrintStream out=null; BufferedReader br =null; try{ in = new BufferedInputStream(new FileInputStream( "D:\\student_file.txt")); out = new PrintStream( new BufferedOutputStream( new FileOutputStream("D:\\student_score.txt"))); System.setIn(in); System.setOut(out); System.setErr(out); br = new BufferedReader(new InputStreamReader(System.in)); String s; while((s = br.readLine()) != null){ System.out.println(s); } } catch(IOException iox){ System.out.println("复制失败!!!!!"); }finally { try { br.close(); in.close(); } catch (IOException e) { e.printStackTrace(); } out.close(); } } }
-
异常的定义,异常的分类,不同异常之间的区别
-
异常的处理方法
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结 束当前方法的执行。
使用的格式:
1. 抛出异常throw
throw new 异常类名(参数);
示例:
public class DemoThrow {
public static void main(String[] args) {
int a = DemoThrow.div(4,0);
System.out.println(a);
}
public static int div(int a,int b)
{
if(b==0)
throw new ArithmeticException("异常信息:除数不能为0");//抛出具体问题,编译时不检测
return a/b;
}
}
2. 声明抛出异常throws
运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常
使用格式:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2 ... { }
示例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DemoThrows {
public static void main(String[] args) throws FileNotFoundException{
readFile();
}
public static void readFile() throws FileNotFoundException {
InputStream is = new FileInputStream("E:/iodemo/ch01.txt");
}
}
3.try代码块
使用格式:
try {
... //监视代码执行过程,一旦返现异常则直接跳转至catch,
// 如果没有异常则直接跳转至finally
} catch (SomeException e) {
... //可选执行的代码块,如果没有任何异常发生则不会执行;
//如果发现异常则进行处理或向上抛出。
} finally {
... //必选执行的代码块,不管是否有异常发生,
// 即使发生内存溢出异常也会执行,通常用于处理善后清理工作。
}
示例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DemoTryCatch {
public static void main(String[] args) {
//捕获异常
try {
//可能产生异常的代码
readFile();
} catch (FileNotFoundException e) {
//异常的处理逻辑,将异常记录日志,异常封装后显示
System.out.println("系统找不到指定的路径");
}
System.out.println("后续代码");
}
public static void readFile() throws FileNotFoundException {
InputStream is = new FileInputStream("E:/iodemo/ch01.txt");
}
}
自定义异常
除了JDK定义好的异常类外,在开发过程中根据业务的异常情况自定义异常类。
示例:
package com.example.springbootmybatis;
/**
* 自定义异常类
* 用户不存在异常信息类
*/
public class UserNotExistsException extends RuntimeException{
public UserNotExistsException() {
super();
}
public UserNotExistsException(String message) {
super(message);
}
}
二、编程题
-
向a.txt中输入以下中文。(注意乱码问题和异常处理问题)(异常包括流打开异常,读取异常等等)
public class InputStreamReader_ {
public static void main(String[] args) {
String FilePath = "D:\\a.txt";
PrintStream out = null;
BufferedWriter sr = null;
try {
out = new PrintStream(new BufferedOutputStream(new FileOutputStream(FilePath)));
System.setOut(out);
System.setErr(out);
sr= new BufferedWriter(new OutputStreamWriter(out,"UTF-8"));
sr.write("你好");
sr.newLine();//换行
sr.write("世界");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
sr.close();
} catch (IOException e) {
e.printStackTrace();
}
out.close();
}
}
}
a.txt 中的内容示例:
2. 将a.txt文件中的文本内容复制到copy.txt中。(同样考虑异常)
方法一:
public class InputStreamReader_ {
public static void main(String[] args) {
String FileIn ="D:\\a.txt";
String FileOut ="D:\\copy.txt";
BufferedInputStream in=null;
PrintStream out=null;
BufferedReader br=null;
try{
in = new BufferedInputStream(new FileInputStream(FileIn));
out = new PrintStream( new
BufferedOutputStream( new FileOutputStream(FileOut)));
System.setIn(in);
System.setOut(out);
System.setErr(out);
br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
String s;
while((s = br.readLine()) != null){
System.out.println(s);
}
}
catch(IOException iox){
System.out.println("复制失败!!!!!");
}finally {
try {
br.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
out.close();
}
}
}
方法二:
public class InputStreamReader_ {
public static void main(String[] args) {
String sc="D:\\copy.txt";//输出文件
BufferedWriter bs=null;
BufferedReader br=null;
try {
bs = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(sc), "utf-8"));
String scr = "D:\\a.txt";//输入文件
br = new BufferedReader(new InputStreamReader(new FileInputStream(scr), "utf-8"));
String s;
while ((s = br.readLine()) != null) {
bs.write(s);
bs.newLine();
}
}catch (IOException e){
System.out.println("复制失败!!!");
}finally {
try {
bs.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
copy.txt 中的内容示例:
三、挑战题(不交也可以,挑战自我)
自己创建一个文件in.txt,统计in.txt中各个字母出现频率:A:1,B:2,C:3 ..................冒号后代表出现次数,并写入out.txt。如果可以的话,输出时按字典序排更好,若你再厉害一点,还可以统计各个符号的个数;
提示:用到了集合嗷
package javaIO.com;
import java.io.*;
import java.util.*;
@SuppressWarnings({"all"})
public class FileTest {
public static void main(String[] args) {
String FileIn ="D:\\in.txt";
String FileOut ="D:\\out.txt";
PrintStream out =null;
BufferedInputStream in =null;
BufferedReader br =null;
// 创建TreeMap 对象用于排序
TreeMap<Character, Integer> map = new TreeMap<>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o1-o2;
}
});
try {
in=new BufferedInputStream(new FileInputStream(FileIn));
out=new PrintStream(new BufferedOutputStream(new FileOutputStream(FileOut)));
System.setOut(out);
br=new BufferedReader(new InputStreamReader(in,"UTF-8"));
String s=null;
// 读出D:\\in.txt 中的内容
while((s= br.readLine())!=null){
// 将读到的字符串转换为字符数组
char[] chars = s.toCharArray();
for (int i=0; i<chars.length; i++){
// 先判断是不是字母
if (!(chars[i]>='A'&&chars[i]<='Z'||chars[i]>='a'&&chars[i]<='z')){
continue;
}
// 使用遍历到的字母作为key 去查表看是否存在value
Integer value = map.get(chars[i]);
if (value==null){// 如果没有这个值 则加入
map.put(chars[i],1);
}else {// 如果有这个值 替换累加
value++;
map.put(chars[i],value);
}
}
}
// 遍历map 将内容输出到 D:\\out.txt 中
Set<Map.Entry<Character, Integer>> entries = map.entrySet();
Iterator<Map.Entry<Character, Integer>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<Character, Integer> next = iterator.next();
System.out.print(next.getKey()+":"+next.getValue()+",");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// 关流
try {
in.close();
out.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
in.txt 中的内容示例:
out.txt 中的内容示例:
我这里只展示了对字母出现次数的记录和排序,如果想要对字符的出现次数做统计,只需将 :
// 先判断是不是字母
if (!(chars[i]>='A'&&chars[i]<='Z'||chars[i]>='a'&&chars[i]<='z')){
continue;
}
这个判断条件删除即可,当然你也可以规定你想要的排序方式。
就到这里啦,有问题欢迎评论,谢谢大家!!!