1.IO流
 
1.1IO流概念及其分类
 
1.1.1IO流概念
 
IO流用于处理设备之间的数据传输。
 
JAVA对数据的操作是通过流的方式。
 
JAVA用于操作流的对象都在IO包中。
 
1.1.2IO流分类
 
a.按照数据流向
 
输入流 读入数据
 
输出流 读出数据
 
b.按照数据类型
 
字节流 可以读写任何类型的文件
 
字符流 只能读写文本文件
 
不清楚该用什么,就用字节流。
 
1.2IO流基本类和FileOutoutStream
 
1.2.1IO流基本类概念
 
a.字节流的抽象类
 
InputStream ,OutputStream。
 
b.字符流的抽象基类
 
Reader , Writer。
 
注意:
 
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
 
案例:
 
往一个文本文件中写一串数据 Hello,IO
 
因为我们要写数据,所以我们应该使用字节流中输出流    OutputStream
 
package westos;
import java.io.*;
public class MyTest1 {
    //往一个文本文件中写一串数据 Hello,IO
    public static void main(String[] args) throws IOException{
        FileOutputStream out = new FileOutputStream("a.txt");
        out.write("HELLO IO".getBytes());
        out.close();
    }
} 
结果:
 
 
 
 
1.2.2FileOutputStream的三个write()方法以及换行和追加写入
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        FileOutputStream out = new FileOutputStream("a.txt",true);\\true的作用是实现数据的追加写入
        out.write("\r\n".getBytes());\\windows下的换行符是 \r\n( Linux下的换行符是\n,Mac下的换行符是\r)  
        out.write(97);//写一个字节  超过一个字节 砍掉前面的字节
        out.write(98);
        out.write(99);
        /*......................................*/
        out.write("\r\n".getBytes());
        out.write(new byte[]{65,66,67});//写一个字节数组
        /*......................................*/
        out.write("\r\n如果没有见过光明,我本可以忍受黑暗".getBytes(),0,26);//写一个字节数组的一部分
        out.write("\r\n如果没有见过光明,我本可以忍受黑暗".getBytes(),0,53);
        out.close();
    }
} 
结果:
 
 
1.2.3写出数据加入异常处理
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream("a.txt",true);
            
            out.write(97);
            out.write(98);
            out.write(99);
            
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
} 
1.3FileInputStream
 
1.3.1读取数据一次一个字节和读取数据一次一个字节数组
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        FileOutputStream out = new FileOutputStream("a.txt");
        out.write("a如果没有见过光明,我本可以忍受黑暗".getBytes());
        out.close();
        FileInputStream in = new FileInputStream(new File("a.txt"));;
        int a = in.read();//一次读取一个字节
        System.out.println(a);//如果没有数据返回的就是-1
        byte[] b = new byte[1024];//把文件中的数据,读取到容器中,返回值是,读取到的有效字节个数
        int c = in.read(b);
        System.out.println(c);
        String s = new String(b, 0, c);
        System.out.println(s);
        in.close();
    }
    } 
结果:
 
97 51 如果没有见过光明,我本可以忍受黑暗
 
1.4字节流复制
 
1.4.1复制文件
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        FileInputStream in = new FileInputStream("a.txt");
        //关联目标文件
        FileOutputStream out = new FileOutputStream("F:\\Test 3\\a2.txt");
        //循环的读写
        int len=0;
        while ((len=in.read())!=-1){
            out.write(len);
            out.flush();//刷新
        }
        //释放资源
        in.close();
        out.close();
    }
    } 
1.4.2复制MP3
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        //我们读取一个字节,写入一个字节,来复制音频文件
        FileInputStream in = new FileInputStream("F:\\Test1\\城府.mp3");
        FileOutputStream out = new FileOutputStream("F:\\Test 3\\城府1.mp3");
        int len=0;//定义一个变量,记录读取到的字节
        //循环读写
        while ((len=in.read())!=-1){
            out.write(len);
            out.flush();
        }
        //释放资源
        in.close();
        out.close();
    }
    } 
1.4.3结果
 
 
1.5BufferedInputStream读取数据
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        BufferedInputStream b = new BufferedInputStream(new FileInputStream("a.txt"));
        byte[] bytes = new byte[52];
         int q=0;
        while ((q=b.read(bytes))!=-1){
            
            b.read(bytes,0,q);\\
高效的字符输入流
       //高效的字符输出流:    BufferedWriter        }
        System.out.println(new String(bytes));
    }
    } 
结果:
 
a如果没有见过光明,我本可以忍受黑暗
 
1.6练习
 
1.6.1把集合中的数据存储到文本文件
 
package westos;
import java.io.*;
import java.util.ArrayList;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        ArrayList<String> list = new ArrayList<>();
        list.add("李一 ");
        list.add("张三");
        list.add("宁一");
        list.add("徐四");
        list.add("刘五");
        list.add("李二 ");
        list.add("张四");
        list.add("宁二");
        list.add("徐五");
        list.add("刘六");
        //遍历集合,取出数据写入文本文件
        BufferedWriter writer = new BufferedWriter(new FileWriter("a.txt"));
        for (String s : list) {
            writer.write(s);
            writer.newLine();
            writer.flush();
        }
        writer.close();
    }
    } 
结果:
 
 
1.6.2随机获取文本文件中的姓名
 
package westos;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
public class MyTest1 {
    public static void main(String[] args) throws IOException{
        BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
        ArrayList<String> list = new ArrayList<>();
        while (true) {
            String s = bfr.readLine();
            if (s != null) {
                list.add(s);
            } else {
                break;
            }
        }
        // System.out.println(list);\\输出[李一 , 张三, 宁一, 徐四, 刘五, 李二 , 张四, 宁二, 徐五, 刘六]
        Random random = new Random();
        //生成一个随机索引
        int index = random.nextInt(list.size());
        String s = list.get(index);
        System.out.println(s);//随机输出
    }
    } 
结果:
 
在“a.txt”中随机输出一个名字
 
1.6.3复制指定目录下指定后缀名的文件并修改名称
 
package westos;
import java.io.*;
public class MyTest1 {
    public static void main(String[] args) throws IOException {
        File f1 = new File("F:\\Test 2\\fff");
        File[] f2 = f1.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                //System.out.println(pathname);
                if (pathname.isFile() && pathname.getName().endsWith(".png")) {
                    return true;
                } else {
                    return false;
                }//筛选出后缀为".png"的文件
            }
        });
        FileInputStream in = null;
        FileOutputStream out= null;
        for (File j : f2) {
            String str1 = j.getName();
            String str2 = j.getName().replace(".png", ".jpg");
            //File f3 = new File("F:\\Test 2\\fff\\" + str2);
             in = new FileInputStream("F:\\Test 2\\fff\\" + str1);
             out = new FileOutputStream("F:\\Test 3\\"+ str2);
            int len = 0;//定义一个变量,记录读取到的字节
            //循环读写
            while ((len = in.read()) != -1) {
                out.write(len);
                out.flush();
            }
        }
        //释放资源
        in.close();
        out.close();
    }
} 
要复制照片:
 
 
复制完成:
 
 
1.6.4键盘录入学生信息按照总分排序并写入文本文件
 
package Asd;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Scanner;
import java.util.TreeSet;
public class MyTest {
    public static void main(String[] args) throws IOException {
        TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //按照总分来排序
                int num = s1.getTotalScore() - s2.getTotalScore();
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return -num2;
            }
        });
        for (int i = 1; i <= 3; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第" + i + "个学生的姓名");
            String name = sc.nextLine();
            Student student = new Student();
            student.setName(name);
            System.out.println("请输入第" + i + "个学生的语文成绩");
            int yw = sc.nextInt();
            student.setChineseScore(yw);
            System.out.println("请输入第" + i + "个学生的数学成绩");
            int sx = sc.nextInt();
            student.setMathScore(sx);
            System.out.println("请输入第" + i + "个学生的英语成绩");
            int yy = sc.nextInt();
            student.setEnglishScore(yy);
            //把学生添加到集合里面
            treeSet.add(student);
        }
        //把集合中的数据存到文本文件中存起来
        long time = System.currentTimeMillis();
        Date date = new Date(time);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");//获取现在的时间
        String s = simpleDateFormat.format(date);
        BufferedWriter bfw = new BufferedWriter(new FileWriter(s+".txt",true));
        bfw.write("序号  姓名  语文成绩  数学成绩  英语成绩  总分");
        bfw.newLine();
        bfw.flush();
        //遍历
        int index = 1;
        for (Student student : treeSet) {
            bfw.write(index + "   " + student.getName() + "   " + student.getChineseScore() + "    " + student.getMathScore() + "    " + student.getEnglishScore() + "    " + student.getTotalScore());
            bfw.newLine();
            bfw.flush();
            index++;
        }
        bfw.close();
        System.out.println("学生成绩录入完成");
    }
} 
package Asd;
public class Student {
    private String name;
    private int chineseScore;
    private int mathScore;
    private int englishScore;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getChineseScore() {
        return chineseScore;
    }
    public void setChineseScore(int chineseScore) {
        this.chineseScore = chineseScore;
    }
    public int getMathScore() {
        return mathScore;
    }
    public void setMathScore(int mathScore) {
        this.mathScore = mathScore;
    }
    public int getEnglishScore() {
        return englishScore;
    }
    public void setEnglishScore(int englishScore) {
        this.englishScore = englishScore;
    }
    //获取总分的方法
    public int getTotalScore() {
        return chineseScore + mathScore + englishScore;
    }
} 
键盘录入:
 
请输入第1个学生的姓名 qaz 请输入第1个学生的语文成绩 34 请输入第1个学生的数学成绩 45 请输入第1个学生的英语成绩 56 请输入第2个学生的姓名 wsx 请输入第2个学生的语文成绩 67 请输入第2个学生的数学成绩 78 请输入第2个学生的英语成绩 89 请输入第3个学生的姓名 edc 请输入第3个学生的语文成绩 12 请输入第3个学生的数学成绩 34 请输入第3个学生的英语成绩 56 学生成绩录入完成
 
存入文本:
 
 
1.7序列化流和反序列化流的概述和问题
 
1.7.1序列化流和反序列化流的概述
 
所谓的序列化:就是把对象通过流的方式存储到文件中。
 
注意:此对象 要重写Serializable 接口才能被序列化。
 
反序列化:就是把文件中存储的对象以流的方式还原成对象
 
序列化流:    ObjectOutputStream
 
反序列化流:    ObjectInputStream
 
一个对象可以被序列化的前提是这个对象对应的类必须实现Serializable接口
 
1.7.2序列化流时的黄色警告线问题
 
我们的一个类可以被序列化的前提是需要这个类实现Serializable接口,就需要给这个类添加一个标记.
 
在完成序列化以后,序列化文件中还存在一个标记,然后在进行反序列化的时候, 会验证这个标记和序列化前的标记是否一致,如果一致就正常进行反序列化,如果 不一致就报错了. 而现在我们把这个类做了修改,将相当于更改了标记,而导致这两个标记不一致,就报错了.
 
解决问题: 只要让这个两个标记一致,就不会报错了