Java学习记录 Day17(IO流)

seuleyang

关注

阅读 79

2022-09-06


文章目录

  • ​​Day 17​​
  • ​​IO流​​
  • ​​IO流的异常处理​​
  • ​​IO流的经典算法​​

Day 17

2019年5月18日。
这是我学习Java的第十七天。
这一天,我学到了以下的知识。

IO流

IO流,用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,而Java用于操作流的对象都在IO包中

IO流按照数据流向,可分为:输入流(从硬盘读取数据到内存),输出流(从内存写入数据到硬盘)

IO流按照数据类型,可分为:

  • 字节流
    可以读写任何类型的文件,比如音频、视频、文本文件
    抽象基类如下:
  • InputStream
    常用具体子类:1.FileInputStream
    构造方法:​FileInputStream(File file)​​:通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定
    ​FileInputStream(String name)​​:通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定
    常用的成员方法
  • 读取功能
  • ​int read(byte[] b)​​:一次读取一个字节数组
    - 当该方法返回 -1 时,表明已经读完了数据。一般可用该值来判断数据是否已经遍历完成
  • 关闭功能
  • ​public void close() throws IOException​​:关闭文件流,释放资源

2.BufferedInputStream
为了对应BufferedOutputStream,Java提供了BufferedInputStream
构造方法:​BufferedInputStream(InputStream in)​​:创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用

  • OutputStream
    常用具体子类:1.FileOutputStream
    构造方法:​FileOutputStream(File file)​​:创建一个向指定 File 对象表示的文件中写入数据的文件输出流
    ​FileOutputStream(String name)​​:创建一个向具有指定名称的文件中写入数据的输出文件流
    常用的成员方法
  • 写入功能
  • ​public void write(int b)​​:写一个字节 超过一个字节 砍掉前面的字节
  • ​public void write(byte[] b)​​:写一个字节数组
  • ​public void write(byte[] b,int off,int len)​​:写一个字节数组的一部分
  • 关闭功能
  • ​public void close() throws IOException​​:关闭文件流,释放资源
    面试题:为什么一定要close()?
    a: 通知系统释放关于管理a.txt文件的资源
    b: 让Io流对象变成垃圾,等待垃圾回收器对其回收

2.BufferedOutputStream
字节流一次读写一个数组的速度,明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流,即BufferedOutputStream
构造方法:​BufferedOutputStream(OutputStream out)​​:创建一个新的缓冲输出流,以将数据写入指定的底层输出流

  • 字符流
    只能读写文本文件
    由于字节流操作中文不是特别方便,所以,java就提供了字符流
    介绍字符流之前,首先介绍编码和解码的概念:
  • 编码
    - 把一个字符串转换成一个字节数组
    - ​​public byte[] getBytes()​​:使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中
    - ​​public byte[] getBytes(String charsetName)​​:使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
  • 解码
    - 把字节数组转换成字符串
    - ​​public String(byte[] bytes)​​:通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
    - ​​public String(byte[] bytes, String charsetName)​​:通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String

抽象基类如下:

  • Writer
    常用具体子类:1.OutputStreamWriter——FileWriter(便携类)
    构造方法:​OutputStreamWriter(OutputStream out)​​:根据默认编码(GBK)把字节流的数据转换为字符流
    ​OutputStreamWriter(OutputStream out,String charsetName)​​:根据指定编码把字节流数据转换为字符流
    常用的成员方法
  • 写入功能
  • ​public void write(int c)​​:写一个字符
  • ​public void write(char[] cbuf)​​:写一个字符数组
  • ​public void write(char[] cbuf,int off,int len)​​:写一个字符数组的一部分
  • ​public void write(String str)​​:写一个字符串
  • ​public void write(String str,int off,int len)​​:写一个字符串的一部分

2.BufferedWriter
高效的字符输出流
构造方法:​public BufferedWriter(Writer w)​​:创建一个使用默认大小输出缓冲区的缓冲字符输出流
特殊方法:​public void newLine()​​:根据系统来决定换行符,具有系统兼容性的换行符l

  • Reader
    常用具体子类:1.InputStreamReader——FileReader(便携类)
    构造方法:​InputStreamReader(InputStream is)​​:用默认的编码(GBK)读取数据
    ​InputStreamReader(InputStream is,String charsetName)​​:用指定的编码读取数据
    常用的成员方法
  • 读取功能
  • ​public int read()​​:一次读取一个字符
  • ​public int read(char[] cbuf)​​:一次读取一个字符数组,如果没有读到,则返回-1

2.BufferedReader
高效的字符输入流
构造方法:​public BufferedReader(Reader e)​​:创建一个使用默认大小输入缓冲区的缓冲字符输入流
特殊方法:​public String readLine()​​:一次读取一行数据 ,是以换行符为标记的,读到换行符就换行,没读到数据返回null

IO流的异常处理

IO流的异常处理,分为字节流和字符流

  • 字节流
    以FileOutputStream为例,代码如下

public class MyTest {
public static void main(String[] args) {
//流的异常处理
FileOutputStream out = null;
try {
out = new FileOutputStream("d.txt");
out.write(100);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

  • 字符流

以InPutStreamReader和OutputStreamWriter为例,代码如下

public class MyTest {
public static void main(String[] args) {
//处理流的异常
//一次多写一些
InputStreamReader in = null;
OutputStreamWriter out = null;
try {
in = new InputStreamReader(new FileInputStream("MyTest.java"));
out = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\MyTest.java"));
//定义一个字符缓冲区
char[] chars = new char[2000];
int len = 0;//记录每次读取到的有效字符个数
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);
out.flush();
}
} catch (IOException e) {
//处理逻辑,默认打印异常的详细堆栈信息
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

IO流的经典算法

  • ArrayList集合中的字符串数据存储到文本文件中,以及将文本文件中的数据反向读入到ArrayList集合中
    代码如下

//1.ArrayList集合中的字符串数组存储到文本文件
public class MyTest {
public static void main(String[] args) throws IOException {
//需求:把ArrayList集合中的字符串数据存储到文本文件
ArrayList<String> list = new ArrayList<>();
list.add("冯小刚");
list.add("张艺谋");
list.add("宁浩");
list.add("徐峥");
list.add("小四");
//把集合中的数据保存到文件文件中
//思路,遍历集合,取出数据写入文本文件
BufferedWriter writer = new BufferedWriter(new FileWriter("username.txt"));
for (String s : list) {
writer.write(s);
writer.newLine();
writer.flush();
}
writer.close();
}
}

//2.文本文件中的数据反向读入到ArrayList集合
public class MyTest2 {
public static void main(String[] args) throws IOException {
//需求是,把文本文件中的数据读取到集合中
ArrayList<String> list = new ArrayList<>();
BufferedReader reader = new BufferedReader(new FileReader("username.txt"));
while (true){
String s = reader.readLine();
if(s!=null){
list.add(s);
}else{
break;
}

}

System.out.println(list);
}
}

  • 多级文件夹复制
    代码如下

public class HomeTest {
public static void main(String[] args) throws IOException {
//需求:复制多级文件夹
//1.封装源文件夹
File srcFolder = new File("C:\\test2");
//2.封装目标文件夹
File targetFolder = new File("D:\\test2");
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
//进行复制
copyFolder(srcFolder, targetFolder);
System.out.println("复制完成");

}

private static void copyFolder(File srcFolder, File targetFolder) throws IOException {
//遍历源文件夹下,所有的文件,复制到目标文件夹下去
File[] files = srcFolder.listFiles();
for (File f : files) {
if(f.isFile()){
copyFiles(f, targetFolder);
}else{
//targetFolder = new File(targetFolder.getPath() + "\\" + f.getName());
//递归
File file = new File(targetFolder,f.getName());
if (!file.exists()) {
file.mkdirs();
}
copyFolder(f, file);
}
}
}


//复制文件
private static void copyFiles(File f, File targetFolder) throws IOException {
//使用字节流来复制
FileInputStream in = new FileInputStream(f);//封装源文件
//封装目标文件
//File file = new File(targetFolder, f.getName());
//System.out.println(file);
FileOutputStream out = new FileOutputStream(new File(targetFolder, f.getName()));
int len = 0;
byte[] bytes = new byte[1024 * 8];
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
//是否资源
in.close();
out.close();
}
}

  • 录入学生信息到文件中
    代码如下

//学生类
public class Student implements Comparable<Student>{
private String name;
private int score;

public Student() {
}

public Student(String name, int age) {
this.name = name;
this.score = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return score;
}

public void setAge(int age) {
this.score = age;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", grade=" + score +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return score == student.score &&
Objects.equals(name, student.name);
}

@Override
public int hashCode() {
return Objects.hash(name, score);
}

@Override
public int compareTo(Student o) {
int num=this.score-o.score;
int num2=num==0?this.name.compareTo(o.name):num;
return num2;
}
}

//测试类
public class HomeTest {
public static void main(String[] args) throws IOException {
//需求: 键盘录入学生信息按照总分排序并写入文本文件
Scanner scanner = new Scanner(System.in);
Student student;
TreeSet<Student> treeSet = new TreeSet<>();
BufferedWriter buf = new BufferedWriter(new FileWriter("Student.txt"));
for (int i = 1; i < 4; i++) {
scanner = new Scanner(System.in);
student = new Student();
System.out.println("请输入第" + i + "位学生的姓名");
String name = scanner.nextLine();
student.setName(name);
System.out.println("请输入第" + i + "位学生的成绩");
int score = scanner.nextInt();
student.setAge(score);
treeSet.add(student);
}
buf.write(treeSet.toString());
buf.close();
}
}


精彩评论(0)

0 0 举报