File operation learning (two) byte stream and character stream

introduction

It is far from enough for JVM to only add, delete and check for file operations. Think about it, in addition to the above main functions, we also need to modify the file, that is, edit the file. Editing the file must involve data flow, usually in java, data Stream includes byte stream and character stream. The inheritance framework of byte stream and character stream is shown below.
Insert picture description here
Among the many streams, InputStream, OutputStream, Reader, and Writer are the top-level parent of many streams. Among these many streams, the most common stream has been marked with a red box in the figure above. First, let me review it. Knowledge about byte streams, in the operating system, we can treat everything as file objects, and file objects are divided into specific files and folders, and the objects faced by many streams are specific files. The modification operation of the file will be discussed with emphasis.

Byte stream

The following issues should be paid attention to in the byte stream:
1. How to improve the read and write efficiency of the byte stream
2. The byte stream can be written as it is.
3. How to wrap the byte stream (operating system)
4. In the byte stream The difference between the flush and close methods in the output stream The
above questions are the core problems of the byte stream operation.
For question 1 , the essential problem is that the byte stream can only read one byte at a time, if the file size is 1024 1024Byte, then the algorithm has to be executed 1024 1024 times. The time complexity is too high, resulting in low file read and write efficiency. At this time, we consider whether to increase the space complexity appropriately in exchange for the reduction of the program time complexity. The answer is obviously yes. , Set the buffer array to read and write files. For a 1M file, if the set buffer array size is 1024Byte, then at least the number of reads and writes is 1024. In theory, the time complexity is reduced by 1024 times compared with the previous example.
For question 2 , you can continue writing as long as you turn on the append switch. The append is of Boolean type, so just set the append switch to true.
For question 3 , when encountering a newline character ("\n") in Linux, the carriage return + line feed operation will be performed, while in windows, carriage return + line feed ("\r\n") will be required to carry out carriage return + line feed , In Mac, it uses ("\r") as the operation of retracement + line feed .
In response to question 4 , the flush method in the output stream is to flush the data in the memory to the disk, and close is to perform the refresh operation first, and then flush the data to the disk.
notes: The default size of the byte buffer stream is 8192Bytes

Case number one

The music skewer case requires two pieces of music to be played at intervals with each other. The playing interval is 10 seconds. The case implementation code is shown below.

public class Demo03MehodHomeWork {
    public static void main(String[] args) throws IOException {
        String path="G:\\testfile";
        String src1="\\杨宗纬;张碧晨 - 凉凉.mp3";
        String src2="\\刘珂矣 - 一袖云.mp3";
        String dest1="\\file1.mp3";
        String dest2="\\file2.mp3";
        String dest="\\dest3.mp3";
        File f1= new File(path + src1);

        File f2= new File(path + src2);
        BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream(path + src1));
        BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(path + src2));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + dest, true));
        int f1Length = 0;
        int f2Length =0;
        //判断文件是否存在,否则抛异常
        if(f1.exists()&&f2.exists()){
            f1Length = (int) f1.length();
            f2Length = (int) f2.length();
        }else {
            throw new IOException("file may not exists ");
        }
        //两首歌曲baudrate不一致
        int songBaudrate1=320;
        int songBaudrate2=320;
        //创建时间起始坐标,使得文件不超过4960KBytes,相当于文件分割定位
        int[] timeStamp1 = new int[30];
        for (int i = 0,j=0;j<=244 &&i < timeStamp1.length; i++) {
            j=0+i*10;
            timeStamp1[i] =j;
        }
        int[] timeStamp2 = new int[30];
        //创建时间起始坐标,使得文件不超过4960KBytes,相当于文件按照时间分割定位
        for (int i = 0,j=0;j<252 &&i < timeStamp2.length; i++) {
            j=10+i*10;
            timeStamp2[i] = j;
        }
        //System.out.println("-----------------------");
        int file_counter1=0,file_counter2=0;
        //int counter=0;
        byte[] bytes = new byte[256];
        int len=0;
        int index1=0,index2=0;
        int totalCounter=0;
        int totalSize = (songBaudrate2*244+songBaudrate1*242)*1024/8;
        boolean flag=true;
        while (true){
            //文件大小不能超过超过设定大小
            if(totalCounter>totalSize){
                break;
            }
            if(flag){

                int start=songBaudrate2*1024*timeStamp1[index1]/8;
                int end=songBaudrate2*1024*timeStamp1[index1+1]/8;
                if(end<start){
                    break;
                }
                while ((len=bis1.read(bytes))!=-1){
                    if(file_counter1>start&& file_counter1<end){
                        bos.write(bytes,0,len);
                    }
                    file_counter1+=len;
                    if(file_counter1>(songBaudrate2*1024*timeStamp1[index1+1]/8)){
                        for (int i = 0; i < bytes.length; i++) {
                            bytes[i]=0;
                        }
                        bos.flush();
                        len=0;
                        totalCounter+=(end-start);
                        break;
                    }
                }
                index1++;
                flag = false;
            }else{
                int start=songBaudrate1*1024*timeStamp2[index2]/8;
                int end=songBaudrate1*1024*timeStamp2[index2+1]/8;
                if(end<start){
                    break;
                }
                while ((len=bis2.read(bytes))!=-1){
                    if(file_counter2>start&&
                            file_counter2<end){
                        bos.write(bytes,0,len);
                        //bos.flush();
                    }
                    file_counter2+=len;
                    if(file_counter2>end){
                        //清空数组
                        for (int i = 0; i < bytes.length; i++) {
                            bytes[i]=0;
                        }
                        bos.flush();
                        len=0;
                        totalCounter+=(end-start);
                        break;
                    }
                }
                index2++;
                flag=true;
            }
            //System.out.println("----------------------------");
        }
        bis1.close();
        bis2.close();
        bos.close();
    }
}

The code has been successfully tested, dest3 has been successfully completed and
Insert picture description here
can be played normally. There must be some optimizations in the code. Please optimize yourself for the friends who read this article. In addition, it needs to be clearly stated that the music objects to be skewed must maintain the same baud rate, otherwise the synthesized music cannot be played during the skewering process .
The above cases basically cover common byte streams in data streams, byte streams with input and output, and byte buffer input and output streams.

Character stream

Before learning the case of character flow, we must first understand the following questions?
1. Why is there a character stream?
2. What is byte stream?
3. What problems can the emergence of character streams solve?
Regarding question 1 , usually read characters directly with bytes, due to inconsistent encoding rules will cause garbled, in order to solve the problem of garbled, the character stream is born.
For question 2 , the character flow is more grounded here, then the character stream can be summarized as:
character stream = byte stream + encoding table.
For question 3 , after the character stream is introduced, as long as the encoding rules are correctly configured, it can effectively prevent Chinese or other The garbled characters help people manipulate characters more effectively.
For question 3 , the
notes for reading and writing characters : The encoding method and decoding method of the string must be the same, otherwise there will be garbled characters . The default size of the character buffer stream is 8192Bytes .

Case two character stream copy java file

public class CharBuffer {
    public static void main(String[] args) throws IOException {
        //copyFile01();
        //copyFile02();
        copyFile03();
    }

    public static void copyFile01() throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("reader&writer\\src\\charbuffer\\CharBuffer.java"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("reader&writer\\CharBuffer01.java"));
        //读写数据,复制文件
        //一次读写一个字符数据
         /*int ch;
         while ((ch=isr.read())!=-1) {
             osw.write(ch);
         }*/
        char[] chars = new char[1024];
        int len;
        while((len = isr.read(chars)) !=-1){
            osw.write(chars,0,len);
        }
        osw.flush();
        isr.close();
        osw.close();
    }

    //采用filereader 和filewriter来实现
    public static void copyFile02() throws IOException {
        FileReader fr = new FileReader("reader&writer\\src\\charbuffer\\CharBuffer.java");
        FileWriter fw = new FileWriter("reader&writer\\CharBuffer02.java");
        /*int ch;
        while((ch=fr.read())!=-1){
            fw.write(ch);
        }*/
        int len;
        char[] chars = new char[1024];
        while ((len=fr.read(chars))!=-1){
            fw.write(chars,0,len);
        }
        fw.flush();
        fr.close();
        fw.close();
    }

    //字符缓冲流复制java文件
    public static void copyFile03() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("reader&writer\\src\\charbuffer\\CharBuffer.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("reader&writer\\CharBuffer03.java"));
        BufferedReader br1 = new BufferedReader(new FileReader("reader&writer\\CharBuffer03.java"));
        char [] chars = new char[1024];
        int len;
        while ((len = br.read(chars))!=-1){
            bw.write(chars,0,len);
        }
        bw.write("hello\r\n");
        bw.write("world\r\n");
        bw.flush();
        //特殊方式写入
        for (int i = 0; i < 10; i++) {
            bw.write("hello" + i);
            //bw.write("\r\n");
            bw.newLine();
            bw.flush();
        }
        bw.close();
        br.close();
        //FileReader 特有方式读取
        String line;
        while ((line=br1.readLine())!=null){
            System.out.println(line);
        }
        System.out.println("-----------------------");
        br1.close();

    }
}

Note It should be noted that when using bw.write("\r\n") when writing a newline character, it will reduce the portability of the code. It is better to use bw.newLine() to add a newline effect.

operation result
Insert picture description here
Insert picture description here

Case Three Pointer Case

The case requirement is to first write the data in the txt file according to the arraylist, then read the content of the txt file and store it in the arraylist collection, and then implement the
student class according to the random function

public class Student {
    private String sid;
    private String name;
    private int age;
    private String address;

    public Student() {
    }

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

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sid='" + sid + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

Test class

public class FileOperation {
    public static void main(String[] args) throws IOException {
        //arrayList2File();
        ArrayList<Student> students = file2ArrayList();

        ArrayList<Student> arrayList  = sortArrayList(students);

        callNameDemo(arrayList);
    }

    //将arraylist中的文件写到txt文件中
    public static void arrayList2File() throws IOException {
        ArrayList<Student> students = new ArrayList<>();
        Student s1 = new Student("001", "张君", 27, "北京");
        Student s2 = new Student("002", "唐三", 20, "唐门");
        Student s3 = new Student("003", "石大力", 22, "沧澜圣地");
        Student s4 = new Student("004", "陈思思", 22, "天音宗");
        Student s5 = new Student("005", "林动", 22, "浮屠道门");

        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.add(s5);

        BufferedWriter bw = new BufferedWriter(new FileWriter("reader&writer\\CharBuffer.txt"));

        for (Student s :
                students) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",")
                    .append(s.getAddress());
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }


    //将txt文件中的文件读取后存储到ArrayList中
    public static ArrayList<Student> file2ArrayList() throws IOException {
        System.out.println("---------------------开始读取文件---------------");
        BufferedReader br = new BufferedReader(new FileReader("reader&writer\\CharBuffer.txt"));
        ArrayList<Student> students = new ArrayList<>();
        String line;
        while ((line = br.readLine())!=null){
            String[] split = line.split(",");

            Student s = new Student();
            s.setSid(split[0]);
            s.setName(split[1]);
            s.setAge(Integer.parseInt(split[2]));
            s.setAddress(split[3]);
            students.add(s);
        }
        br.close();
        for (Student s :
                students) {
            System.out.println(s.getSid()+","+s.getName()+","+s.getAge()+","+s.getAddress());
        }
        System.out.println("---------------------文件读取结束---------------");
        return students;
    }

    //按照年龄需要对输出的文件进行改进
    public static ArrayList<Student> sortArrayList(ArrayList<Student> arrayList)  throws IOException {
        System.out.println("---------------生成排序文件-----------------");
        BufferedWriter bw = new BufferedWriter(new FileWriter("reader&writer\\CharBuffer2.txt"));
        Collections.sort(arrayList,(o1, o2)->{
             return o1.getAge()-o2.getAge() >=0 ? 1:-1;
        });

        for (Student s :
                arrayList) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",")
                    .append(s.getAddress());
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }

        arrayList.forEach(m-> System.out.println(m));

        bw.close();

        System.out.println("---------------排序文件生成结束----------------");

        return arrayList;
    }

    //开始点名
    public static  void callNameDemo(ArrayList<Student> list){
        System.out.println("--------------------开始点名------------------");
        Random r = new Random();
        int index = r.nextInt(list.size());
        Student s = list.get(index);
        System.out.println("幸运者是:"+s.getName());
        System.out.println("--------------------点名结束------------------");
    }
}

Operation result So
Insert picture description here
far, the operation of the file has come to an end, and the next blog post will continue.

Guess you like

Origin blog.csdn.net/xueshanfeitian/article/details/106918178