JavaSE basics-(21) IO stream & character stream & recursion

table of Contents

One, character stream

1.1 Overview of Character Stream

1.2FileReader

1.3FileWriter

1.4 Copy of character stream

1.5 Character stream usage

1.6 Whether the character stream can copy non-plain text files

1.7 Buffered character stream

1.7.1 Buffer Character Stream Copy

1.7.2 readLine() and newLine() methods

1.8 Reverse the text

1.9LineNumberReader

Two, decorative design mode

3. Use the specified code table to read and write files

Fourth, the trial version software function realization

Five, recursion


 

One, character stream

1.1 Overview of Character Stream

The character stream is an IO stream that can directly read and write characters,

The character stream reads characters, that is, first reads the byte data, and then converts it into a character.

If you want to write a character, you need to convert the character to a byte and then write it out.

 

1.2FileReader

FileReader is a class used to read character streams. If you want to read a native byte stream, FileInputStream is generally used.

FileReader mainly has the following construction methods,

FileReader(File file)//创建一个新的FileReader,给出File读取
FileReader(String fileName)//创建一个新的FileReader,给定要读取的文件的名称。

Let’s take a look at how to use it,

import java.io.*;

public class IOTest{
    public static void main(String[] args) throws IOException {
        FileReader fr=new FileReader("data.txt");
        int x;
        while((x=fr.read())!=-1){
            System.out.print((char)x);
        }
        fr.close();
    }
}

 

1.3FileWriter

The write() method in the FileWriter class can automatically convert characters to bytes and write out. Its main constructor is as follows,

FileWriter(File file)//给一个File对象构造一个FileWriter对象
FileWriter(File file, boolean append)//给一个File对象构造一个FileWriter对象,append为true时从文件末尾写入而不是文件开头
FileWriter(String fileName)//构造一个给定文件名的FileWriter对象
FileWriter(String fileName, boolean append)//构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据

Let’s take a look at how to use this object to write characters.

FileWriter fw=new FileWriter("data.txt",true);
fw.write("\r\nFileWriter中文写入测试");
fw.close();

 

1.4 Copy of character stream

The copy of the character stream is the same, one character by character is read into the program, and then written one by one,

        FileReader fr=new FileReader("data.txt");
        FileWriter fw=new FileWriter("dataCopy.txt");

        int c;
        while((c=fr.read())!=-1){
            fw.write(c);
        }

        fr.close();
        fw.close();

We can see that the content has been copied to the target file,

Note that the fw character stream object must be closed here, because when the FileWriter class writes characters, the bottom layer calls the buffer write, and the buffer size is 2k.

If the content is not full of the buffer, it will not be flushed to the file, so we need to call the close method to flush the buffer and write the content to the target file.

 

1.5 Character stream usage

The character stream can copy text files, but it is not recommended.

Because the bytes are converted into characters when reading, and characters are converted back to bytes when writing, it is more convenient and faster to use the byte stream directly.

When the program needs to read a piece of text, or need to write a piece of text, you can use the character stream,

When reading, it is read according to the size of the character, and there will be no half of Chinese; when writing, you can directly write the string without converting it into a byte array.

 

1.6 Whether the character stream can copy non-plain text files

Character streams cannot copy non-plain text files, such as pictures and videos.

When reading, the two bytes will be converted into characters, and the corresponding characters may not be found during the conversion process, so it will be replaced by ?.

When writing out, the characters will be converted into bytes and written out. If it is written directly, the file will be garbled.

 

1.7 Buffered character stream

Similarly, there are buffered read and write classes in the character stream, namely BufferedReader and BufferedWriter, the buffer size is 16k,

The read() method of BufferedReader will read several characters to the buffer at a time when reading characters, and then return them to the program one by one, reducing the number of times to read files and improving efficiency.

The write() method of BufferedWriter writes characters to the buffer first, and writes to the file when the buffer is full, reducing the number of times to write files and improving efficiency.

 

1.7.1 Buffer Character Stream Copy

Let’s take a look at how to use the read() and write() methods to copy.

import java.io.*;

public class IOTest{
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("data.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("dataCopy.txt"));

        int c;
        while((c=br.read())!=-1){
            bw.write(c);
        }
        
        br.close();
        bw.close();
    }
}

 

1.7.2 readLine() and newLine() methods

The readLine() method of BufferedReader can read a line of characters (excluding line breaks),

The return value is a string, if the end of the file is reached, a null is returned,

The newLine() method of BufferedWriter can output a cross-platform newline symbol,

(The line break symbol is "\r\n" on the windows platform, the line break symbol is "\n" under the linux platform, and the line break symbol is "\r" under the mac platform).

        BufferedReader br=new BufferedReader(new FileReader("data.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("dataCopy.txt"));

        String str;
        while((str=br.readLine())!=null){
            bw.write(str);//写入一行文本
            bw.newLine();//换行
        }

        br.close();
        bw.close();

 

1.8 Reverse the text

It is required to reverse the text in a text document, exchange the contents of the first line and the last line, exchange the contents of the second line and the penultimate line, and so on,

import java.io.*;
import java.util.ArrayList;

public class IOTest{
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("data.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("dataReverse.txt"));

        ArrayList<String> list=new ArrayList<>();
        String line;
        while((line=br.readLine())!=null){
            list.add(line);
        }

        for (int i = list.size()-1; i >=0 ; i--) {
            bw.write(list.get(i));
            bw.newLine();
        }

        br.close();
        bw.close();
    }
}

 

1.9LineNumberReader

LineNumberReader is a subclass of BufferedReader, with the same function,

And you can count the row numbers, the default downlink number starts from 0,

  • getLineNumber() Get the current line number
  • setLineNumber() sets the current line number

Note that the line number set by the setLineNumber() method does not change the actual line position, but the value returned by the getLineNumber() method is changed.

        LineNumberReader lr=new LineNumberReader(new FileReader("data.txt"));

        String line;
        lr.setLineNumber(100);//设置初始行号为100
        while((line=lr.readLine())!=null){
            System.out.println(lr.getLineNumber()+":"+line);//输出行号和内容
        }

 

Two, decorative design mode

The decoration mode is also known as the wrapper mode,

The decoration mode expands the function of the object in a way that is transparent to the client, and is an alternative to the inheritance relationship.

public class WrapTest{
    public static void main(String[] args) throws IOException {
        ChineseDog cd=new ChineseDog(new Dog());
        cd.ability();
    }
}

interface Animal {
    public void ability();
}

class Dog implements Animal{
    @Override
    public void ability() {
        System.out.println("吃骨头");
    }
}

class ChineseDog implements Animal{
    private Dog d;
    public ChineseDog(Dog d){
        this.d=d;
    }
    @Override
    public void ability() {
        d.ability();
        System.out.println("看门");
    }
}

We can use inheritance to achieve such a function, but the inheritance relationship is too coupled, and the parent class will change the subclass if it is modified.

However, there is no such strong coupling when using the decoration mode. The two classes are independent, and the change of the decorated class has nothing to do with the change of the decoration class.

 

3. Use the specified code table to read and write files

FileReader uses the default code table to read the file. If you need to use the specified code table to read, you can use InputStreamReader (byte stream, code table),

FileWriter uses the default code table to write out the file. If you need to use the specified code table to write out, you can use OutputStreamReader (byte stream, code table).

        //读取uft-8编码格式的文本,将内容以gbk格式写入另一个文本中
        InputStreamReader isr=new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8");
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");

        int c;
        while((c=isr.read())!=-1){
            osw.write(c);
        }

        isr.close();
        osw.close();

 

Fourth, the trial version software function realization

When we use a software, we require a total of 10 trial opportunities. Every time we run the program, the trial opportunity will be reduced.

We store the number of used opportunities in a file, and read the remaining trial opportunities every time we run. When the trial opportunities are used up, the user is prompted to purchase genuine software.

        BufferedReader br=new BufferedReader(new FileReader("trialTimes.txt"));

        String str=br.readLine();
        int times=Integer.parseInt(str);
        br.close();

        if(times>0){
            System.out.println("您的剩余使用次数为:"+ --times);
            FileWriter fw=new FileWriter("trialTimes.txt");
            fw.write(times+"");//以字符串的形式写出
            fw.close();
        }else{
            System.out.println("试用次数已用完,请购买正版软件!");
        }

 

Five, recursion

Recursion is a method that continuously calls itself. Many recursion can be implemented with a for loop.

But when the number of loops is not clear, it is very simple to use recursion. Let's take an example to see how to use recursion.

Let’s calculate the factorial of 10.

    public static void main(String[] args) throws IOException {
        System.out.println(factorial(10));
    }

    public static int factorial(int num){
        if(num ==1){
            return 1;
        }else{
            return num * factorial(num-1);
        }
    }

There is an obvious disadvantage of using recursion. When using recursion, the method will continue to push the stack and will not release the memory space.

If the number of calls is too many, it is likely to cause stack memory overflow. Note: Recursion cannot be used in the construction method! Otherwise, there will always be an endless loop in the structure.

Guess you like

Origin blog.csdn.net/weixin_39478524/article/details/112958303