Java I / O system learning series three: I / O streams of typical use

  Although IO stream classes can be combined in different ways, but we will probably only use a combination of several of them. The following reference examples as a basic IO typical usage. In these examples, exception handling are simplified to pass the exception to the console, but this is only applicable in small samples and tools. In the code, you need to consider more sophisticated error handling.

  Also, this article will include the following aspects:

  Buffered input file

  Input from memory

  Formatted memory input

  Basic file output

  Store and retrieve data

  Read and write random access files

  Utilities

  to sum up

 

1. buffered input file

  If you want to open a file for character input, you can use a String or a File object as the file name FileReader. In order to improve the speed, we can buffer for that file, then we need to pass a reference BufferedReader constructor will be generated. By its use of the readLine () method to read the file line by line, when the readLine () returns null, on to the end of the file.

public class BufferedInputFile {

    public static String read(String fileName) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(fileName));
        StringBuilder str = new StringBuilder();
        String temp = null;
        while((temp = br.readLine()) != null) {
            str.append(temp + "\n");
        }
        br.close();
        return str.toString();
    }
    
    public static void main(String[] args) {
        try {
            System.out.println(BufferedInputFile.read("pom.xml"));
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

  All contents of the file are accumulated in the string str, and finally remember to call close () to close the stream.

2. Input from memory

  In the following example, from the above BufferedInputFile.read () String read results are used to create a StringReader. Then call read () read one character, and print it to the console.

public class MemoryInput {
    
    public static void main(String[] args) {
        try {
            StringReader sr = new StringReader(BufferedInputFile.read("pom.xml"));
            int c;
            while((c = sr.read()) != -1) {
                System.out.print((char)c);
            }
        }catch(Exception e) {
            
        }
    }

}

  Note that read () returns an int is under a byte, it must be strong into char type to display the correct results.

3. Formatted memory input

  To read the data format, DataInputStream may be used, which is a byte-oriented I / O class, we can use InputStream read any data in bytes.

public class FormattedMemoryInput {

    public static void main(String[] args) {
        try {
            DataInputStream di = new DataInputStream(new ByteArrayInputStream(BufferedInputFile.read("pom.xml").getBytes()));
            while(di.available() != 0) {
                System.out.print((char)di.readByte());
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  Note here that must be provided to the constructor ByteArrayInputStream byte array, and after performing a DataInputStream ByteArrayInputStream transmitted to "decorate", can be formatted input (such as direct read int, double type, etc.), where we only read by readByte take a single byte, the results are legitimate values ​​of any bytes when the method is called, the return value and therefore can not be used to detect whether the input end, here we use the available () method to see how much of accessible characters determine whether the end.

4. Basic file output

  FileWriter object can write to a file, which is usually packaged with BufferedWriter output to buffer to improve performance. In the present embodiment, in order to provide formatting mechanism, which is decorated PrintWriter:

public class BasicFileOutput {
    
    static String file = "BasicFileOutput.out";
    
    public static void main(String[] args) {
        try {
            BufferedReader in = new BufferedReader(new StringReader(BufferedInputFile.read("pom.xml")));
            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            String temp;
            int count = 0;
            while((temp = in.readLine()) != null) {
                out.println(count++ + temp);
            }
            in.close();
            out.close();
            System.out.println(BufferedInputFile.read(file));
        }catch(Exception e) {
            e.printStackTrace();
        }        
    }

}

  BasicFileOutput.out here before reading the contents of a close out the first call () to turn it off, partly because of the need for timely after the stream run off to conserve resources, on the other hand the buffer is used here, if not for all the output file calls the close (), refresh the contents of the buffer may not be cleared, this may lead to incomplete information.

  In addition Java SE5 adds an auxiliary constructor in PrintWriter, you can easily without having to perform a series of decorative work file name directly construct a PrintWriter by:

PrintWriter out = new PrintWriter(file);

5. Store and retrieve data

  PrintWriter can format data in order to read. But in order to output the data available to the other "flow" of recovery, we need to write data DataOutputStream, and restore data DataInputStream. Of course, these streams may be in any form, used in the following examples is a file.

public class StoringAndRecoveringData {
    
    public static void main(String[] args) {
        try {
            DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data.txt")));
            out.writeDouble(3.14159);
            out.writeUTF("That was pi");
            out.writeDouble(1.41413);
            out.writeUTF("Square root of 2");
            out.close();
            DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("data.txt")));
            System.out.println(in.readDouble());
            System.out.println(in.readUTF());
            System.out.println(in.readDouble());
            System.out.println(in.readUTF());
            in.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

}

  Use DataOutputStream write data, Java can guarantee that we can use DataInputStream accurately read the data - no matter how different platform data read and write. When we use DataOutputStream, write the string and let DataInputStream able to resume its only reliable way is to use UTF-8 encoding, in this case is by writeUTF () and readUTF () to achieve.

  writeDouble () and readDouble () method capable of writing and restoring data of type double. For other types of data, there are similar methods for reading and writing. But in order to ensure that all read and write methods to work properly, we need to know the exact location where the stream of data items, most likely because of double data will be saved as a simple sequence of bytes, char or other types of reading.

6. Read and write random access files

  RandomAccessFile use, and similar to the DataOutputStream DataInputStream used in combination, can be simultaneously read and write to a file, while using a seek () moving around in the document, is very convenient, detailed usage RandomAccessFile, in front of a special written << Java I / O system: File and RandomAccessFile >>.

  However, the use RandomAccessFile, you need to know the layout file, so as to operate it properly, RandomAccessFile with a variety of specific methods to read the basic types and UTF-8 string.

public class UsingRandomAccessFile{
    static String file = "rtest.dat";
    static void display() throws IOException{
        RandomAccessFile rf = new RandomAccessFile(file,"r");
        for(int i = 0; i < 7; i++){
            System.out.println("Value " + i + ": " + rf.readDouble());
        }
        System.out.println(rf.readUTF());
        rf.close();
    }
    public static void main(String[] args) throws IOException{
        RandomAccessFile rf = new RandomAccessFile(file,"rw");
        for(int i = 0; i < 7; i++){
            rf.writeDouble(i*1.414);
        }
        rf.writeUTF("The end of the file");
        rf.close();
        display();
        rf = new RandomAccessFile(file,"rw");
        rf.seek(5*8);
        rf.writeDouble(47.0001);
        rf.close();
        display();
    }
}

  We write by writeDouble () method to file Double data type and read by readDouble () method, which is the reason we need until typesetting, if not read data type Double likely not what we want result.

7. Utilities

  Here we study the typical use of a variety of I / O streams, such as buffered input file, the input from memory, basic file output, store and retrieve data, random read and write files, which are Java I / O stream typical usage. Here we find the file to read, modify, write in a common programming tasks, but the Java I / O library design has a problem that we need to write a lot of code to implement these operations, to remember how open the file is an advantage difficult thing. So, here are some helper classes to collect, you can easily accomplish these basic tasks for our record here, to facilitate future viewing.

  Collected here are two tools:

  • One is TextFile, help us to read and write files;
  • Another is BinaryFile, help us simplify read binary files.

7.1 to read the file

  TextFile class contains static methods that can be read as a simple string of text files, and we can create a TextFile objects, it uses an ArrayList to hold a number of lines of the file, the benefits can use an ArrayList when we manipulate the file contents of all functions .

public class TextFile extends ArrayList<String>{
    // 将文件读取到一行字符串中
    public static String read(String fileName){
        StringBuilder sb = new StringBuilder();
        try{
            BufferedReader in = new BufferedReader(new FileReader(new File(fileName).getAbsoluteFile()));
            try{
                String s;;
                while((s = in.readLine()) != null){
                    sb.append(s).append("\n");
                }
            }finally{
                in.close();
            }
        }catch (IOException e){
            throw new RuntimeException(e);
        }
        return sb.toString();
    }

    // 单次调用将一个字符串写入一个文件
    public static void write(String fileName,String text){
        try{
            PrintWriter out = new PrintWriter(new File(fileName).getAbsoluteFile());
            try{
                out.print(text);
            }finally{
                out.close();
            }
        }catch(IOException e){
            throw new RuntimeException(e);
        }
    }

    // 读取文件,并通过正则表达式将其分离,保存在List中
    public TextFile(String fileName,String splitter){
        super(Arrays.asList(read(fileName).split(splitter)));
        // 因为split()方法有时会在返回的数组第一个位置产生一个空字符串
        if(get(0).equals(""))
            remove(0);
    }

    // 常规的分行读取
    public TextFile(String fileName){
        this(fileName,"\n");
    }

    // 将该TextFile中的内容分行写入指定文件中
    public void write(String fileName){
        try{
            PrintWriter out = new PrintWriter(new File(fileName).getAbsoluteFile());
            try{
                for(String item : this){
                    out.println(item);
                }
            }finally{
                out.close();
            }
        }catch(IOException e){
            throw new RuntimeException(e);
        }
    }

    // 简单验证一下
    public static void main(String[] args){
        String file = read("TextFile.java");
        write("test.txt",file);
        TextFile text = new TextFile("test.txt");
        text.write("test2.txt");
        TreeSet<String> words = new TreeSet<String>(new TextFile("TextFile.java","\\W+"));
        System.out.println(words.headSet("a"));
    }
}

  这里利用静态的read()方法将文件读取到一个字符串中,再用静态的write()方法将其写入到文件中。然后将新写入的文件作为构造参数构造一个TestFile对象,利用其List的特性,将其内容写入文件test2中。这个类的作用是帮我们读取文件,可以通过静态的read方法读取到一个字符串中,也可以通过构造器读取文件到一个TextFile对象中。

7.2 读取二进制文件

public class BinaryFile{
    public static byte[] read(File bFile)throws IOException{
        BufferedInputStream bf = new BufferedInputStream(new FileInputStream());
        try{
            byte[] data = new byte[bf.available()];
            br.read(data);
            return data;
        }finally{
            bf.close();
        }
    }

    public static byte[] read(String bFile)throws IOException{
        return read(new File(bFile).getAbsoluteFile());
    }
}

8. 总结

  本文没有总结什么新的知识点,只是总结了一些Java I/O的常见用法比如缓冲输入文件、从内存输入、基本的文件输出、存储和恢复数据、随机读写文件等,并且搜集了两个工具类用来帮助我们读写文件读取二进制文件,以提高些代码的效率。

 

Guess you like

Origin www.cnblogs.com/volcano-liu/p/10991248.html