input Output

File class

The File class represents a file or folder, such as File file = new File("dog.gif");the file in the current folder dog.gif, or File file = new File("images");the images folder in the current folder. Common operations of the File class are:

File

When creating a File object, the string in the constructor File(String pathname)is the path of the file or folder, which can be a relative path or an absolute path. Like dog.gif, images\dog.gif is a relative path, like d:\images\dog.gif under Windows, /home/test/images/dog.gif under UNIX is an absolute path.

Because in Java, the escape character is represented, so the path separator \in the string literal is written , or can be written , is the path separator in UNIX, and can also be used in Windows systems. So in Windows system, the path d:\images\dog.gif is written as: - "d:\images\dog.gif" is correct - "d:/images/dog.gif" is correct Note that the following is wrong of - "d:\images\dog.gif"\\\//



example:

public class TestFileClass {
  public static void main(String[] args) {
    java.io.File file = new java.io.File("image/us.gif");
    System.out.println("Does it exist? " + file.exists());
    System.out.println("The file has " + file.length() + " bytes");
    System.out.println("Can it be read? " + file.canRead());
    System.out.println("Can it be written? " + file.canWrite());
    System.out.println("Is it a directory? " + file.isDirectory());
    System.out.println("Is it a file? " + file.isFile());
    System.out.println("Is it absolute? " + file.isAbsolute());
    System.out.println("Is it hidden? " + file.isHidden());
    System.out.println("Absolute path is " +
      file.getAbsolutePath());
    System.out.println("Last modified on " +
      new java.util.Date(file.lastModified()));
  }
}

Text input/output

FileThe class does not have methods for creating files and writing/reading data to files. Writing data to a file is also called output, and reading data from a file is also called input, which together are called file input and output IO.

PrintWriter class for output

You can use the java.io.PrintWriter class to create text files and write text to them.

First create the PrintWriter class object

PrintWriter output = new PrintWriter(filename);

Then you can call the print(), println(), printf() and other methods of the PrintWriter class to write data to the file.

PrintWriter

The following program writes two lines of text to the file scores.txt, each line of text consists of a string and an integer.

public class WriteData {
  public static void main(String[] args) throws java.io.IOException {
    java.io.File file = new java.io.File("scores.txt");
    if (file.exists()) {
      System.out.println("File already exists");
      System.exit(0);
    }

    // Create a file
    java.io.PrintWriter output = new java.io.PrintWriter(file);

    // Write formatted output to the file
    output.print("John T Smith ");
    output.println(90);
    output.print("Eric K Jones ");
    output.println(85);

    // Close the file
    output.close();
  }
}

try-with-resources to automatically close resources

In the above program, if it is commented out, what output.close()may happen is that the data is not written to the file. After writing the data, the close() method of the stream is called to finally write the data to the target. But sometimes programmers forget to call it. So starting from JDK 7 Java supports a new syntax to automatically call the close() method of an object. One syntax is called try-with-resources syntax.

try(声明和创建资源){
   处理资源
}

The class of such a resource variable must implement the AutoClosealbeinterface, which only declares a close() method. PrintWriter implements the AutoClosealbeinterface. When the resource processing code in the braces is completed, regardless of whether an exception is thrown, the resource object variable declared in the try braces will automatically call the close() method. So the above code can be written as

public class WriteDataWithAutoClose {
  public static void main(String[] args) throws Exception {
    java.io.File file = new java.io.File("scores.txt");
    if (file.exists()) {
      System.out.println("File already exists");
      System.exit(0);
    }

    try (
      // Create a file
      java.io.PrintWriter output = new java.io.PrintWriter(file);
    ) {
      // Write formatted output to the file
      output.print("John T Smith ");
      output.println(90);
      output.print("Eric K Jones ");
      output.println(85);
    }
  }
}

Use Scanner to read text

The java.util.Scanner class can be used to read text and values ​​from the console and files. The Scanner treats the input as a string "token" separated by a delimiter (whitespace by default).
To read from the keyboard, you can create a Scanner and associate it with System.in,
Scanner input = new Scanner(System.in);
to read from a file, you need to associate the Scanner with the file,
Scanner input = new Scanner(new File(filename));
or
Scanner input = new Scanner(filename);

Scanner

Assuming that scores.txt is

John T Smith 90
Eric K Jones 85

import java.util.Scanner; 

public class ReadData {
  public static void main(String[] args) throws Exception {
    // Create a File instance
    java.io.File file = new java.io.File("scores.txt");

    // Create a Scanner for the file
    Scanner input = new Scanner(file);

    // Read data from a file
    while (input.hasNext()) {
      String firstName = input.next();
      String mi = input.next();
      String lastName = input.next();
      int score = input.nextInt();
      System.out.println(
        firstName + " " + mi + " " + lastName + " " + score);
    }

    // Close the file
    input.close();
  }
}

The result of running the above code is

John T Smith 90
Eric K Jones 85

NextInt(), nextDouble() and other methods will ignore the separator when reading characters (the default is a blank character, that is, ' ', \t, \f, \r, or \n), and read consecutive non-separators. To the string until a certain separator is encountered, the encountered separator will not be read and left to the subsequent read method to process. Then nextInt() will parse the string into an integer value and return it. Other methods are similar. If it cannot be parsed correctly, an unchecked exception of java.util.InputMismatchException will be thrown. The next() method does not parse the read string and returns it directly.

The nexLine() method reads the string on a line including the delimiter until a newline is encountered. Newlines are also read, but not returned as part of the string, and subsequent next...() methods start reading from the next line.

Text input and output principles

In the process of writing to a file using PrintWriter, it can be regarded as passing through these steps:

  1. Converts a binary numerical value to a readable text format, i.e. a sequence of characters (array)
  2. Encodes each character in the character sequence as a sequence of bytes in the platform default encoding format
  3. Output the byte sequence (array) as-is to a file

What PrintWriter essentially completes is step 1, and steps 2 and 3 are accomplished with the help of other classes. The second step, encoding characters into byte sequences is implemented by the OutputStreamWriter class, and the third step, writing the byte sequence to a file is implemented by FileOutputStream.

The process of Scanner scanning the integer string in the file into the integer variable can be regarded as the reverse process of PrintWriter:

  1. Read the contents of a file into a byte sequence (array)
  2. Decode a sequence of bytes into a sequence of characters (array) in the platform default encoding format
  3. Scan a sequence (array) of characters, parse them from readable characters into binary numbers and store into variables

Scanner essentially completes step 3, and steps 1 and 2 are implemented with the help of other classes. The first step, reading the data in the file into a byte sequence is implemented by the file input class FileInputStream. Step 2, decoding the sequence of bytes into characters is implemented by the InputStreamReader class.

For example, to output the value of variable x in text form to the file value.txt,

PrintWriter pw = new PrintWriter("value.txt");
int x = 199;
pw.print(x);
  1. Convert the binary value of 199, that is, 00000000 00000000 00000000 1100 0111, these 4 bytes into a readable text format, that is, the character sequence '1', '9', '9'. (Characters in Java are stored in 2 bytes as Unicode values, '1' is 0x0031 and '9' is 0x0039.)
  2. Convert the characters '1' and '9' into byte sequences encoded in the platform's default encoding format. Assuming ASCII encoding, the encoding of the character '1' is 0x31 (1 byte), and the encoding of the character '9' is 0x39 (1 byte)
  3. Output the byte sequence (array) to the file as is, i.e. 0x31 0x39 0x39 to the file

Reading text files with Scanner is the reverse of this process.

text/binary connection

Note that the above figure corresponds to steps 2 and 3 of the PrintWriter working process. The main job of PrintWrite, process 1, is not shown in the figure.

In addition to ASCII (for the character set, the ASCII character set), the common encoding forms are UTF-8, UTF-16 and other encoding formats for the Unicode character set, which is a superset of the ASCII character set.

Binary input/output

It can be simply understood that the processing of text files is to process characters, mainly to encode characters, while the processing of binary files is to process bytes. Common classes that handle input and output in binary (byte) form are,

  • FileInputStream/FileOutputStream handles byte-level reading and writing of files.
  • DataInputStream/DataOutputStream converts values ​​or strings to and from byte sequences in memory.
  • BufferedInputStream/BufferedOutputStream open up a buffer of byte sequences, so that the read and write of the file is first read and written to the buffer, and when the buffer is full, multiple bytes are read and written to the file at one time, which speeds up the input and output of the file.

Binary I/O Classes

OutputStream is the base class for binary output

OutputStream

InputStream is the base class for binary input

InputStream

As you can see from the methods of these two classes, they deal with byte-level data. Basically all methods throw java.io.IOException or a checked exception of its subclasses.

binary input/output to file

The basic meaning of binary processing is to input/output the bytes in memory to the target as is. If you want to output to a file, you need to use FileInputStream/FileOutputStream. FileInputStream is used to read bytes from a file into memory, and FileOutputStream is used to write a sequence of bytes in memory to a file. FileInputStream/FileOutputStream do not add new methods on the basis of their parent class InputStream/OutputStream, of course, they override the related methods of parent class InputStream/OutputStream.

The constructor of FileInputStream is as follows,

  • public FileInputStream(String filename)
  • public FileInputStream(File file)

When creating a FileInputStream, if the file does not exist, a java.io.FileNotFoundException will be thrown.

The constructor of FileOutputStream is as follows,

  • public FileOutputStream(String filename)
  • public FileOutputStream(File file)
  • public FileOutputStream(String filename, boolean append)
  • public FileOutputStream(File file, boolean append)

When a FileOutputStream is created, a new file is created if the file does not exist. If the file already exists, the first two constructors delete the contents of the file. The last two constructors can specify whether to append data to the file, rather than delete the contents of the file.

Almost all methods in the I/O class throw java.io.IOException. So we need to declare throw it, or catch it.

FilterInputStream/FilterOutputStream

Filter streams are a type of input and output streams, they are associated with file input and output streams, and their input and output operations will eventually be manipulated into files after their "filters". There are two subclasses of FiterInputStream/FilterOutputStream:

  • DataInputStream/DataOutputStream
  • BufferedInputStream/BufferedOutputStream

DataInputStream/DataOutputStream

DataOutputStream converts basic numeric types and string types to byte streams in their original form in memory and outputs them to a file. DataInputStream converts the byte stream in the file to a primitive numeric type or a String type.

DataOutputStream

DataInputStream

DataInputStream implements the DataInput interface to read values ​​and strings. DataOutputStream implements the DataOutput interface to write basic numbers and strings. It can be seen that they copy primitive numeric types in memory and in files without any modification. There are several ways to write characters in a string.

The writeChar(char c) and writeChars(Stirng s) methods write characters and characters in strings to a file. Character types are stored in memory as 2-byte Unicode values, so they are written in this 2-byte Unicode value. Sections are written to a file, or read from a file. writeChars(String s) does not write the number of characters in the character, so if you want to write the number of characters in the string, you can use the writeInt(int v) method to write the length of the string before calling writeChars(String s). .

writeUTF(String s) first writes 2-byte string length information to the output stream, and then writes the characters in the string s to the output stream in modified UTF-8 form. For example, writeUTF("ABCDEF") writes eight bytes to the file, which are 00 06 41 42 43 44 45 46 in hexadecimal. Compared with writeChars(String s), writeUTF(String s) records the length of string s. And if the characters in string s are mostly ASCII characters, writeUTF(String s) will save more space than writeChars(String s).

To create a DataInputStream/DataOutputStream object, use the following constructor:

  • public DataInputStream(InputStream instream)
  • public DataOutputStream(OutputStream outstream)

The following code creates an input stream that reads a stream of bytes from the in.dat file. The output stream writes the values ​​to the out.data file.

import java.io.*;

public class TestFileStream {
  public static void main(String[] args) throws IOException {
    try (
      // Create an output stream to the file
      FileOutputStream output = new FileOutputStream("temp.dat");
    ) {
      // Output values to the file
      byte byteArray[] = {1,2,3,4,5,6,7,8,9, 10};
      for (int i = 0; i < byteArray.length; i++)
        output.write(byteArray[i]);
    }

    try (
      // Create an input stream for the file
      FileInputStream input = new FileInputStream("temp.dat");
    ) {
      // Read values from the file
      int value;
      while ((value = input.read()) != -1)
        System.out.print(value + " ");
    }
  }
}

The file read and write operations when dealing with text files ultimately use these two classes. It's just that sometimes they are encapsulated into the PrintWriter and Scanner classes, and we don't need to manipulate them directly.

BufferedInputStream/BufferedOutputStream

BufferedInputStream/BufferedOutputStream is also a subclass of FilterInputStream/FilterOutputStream. Their function is very simple. They open up a buffer for reading/writing files in memory, so that you don't need to read/write directly from the file every time you call the function, because the file operation Relatively slow for memory operations. BufferedInputStream/BufferedOutputStream contains an array of bytes. When calling a method to read a byte stream from a file, first read many bytes from the file into an array of bytes at one time, and then read the function again to read words from the array of bytes. section until the byte array is read. Type of write operation.

Class Diagram

For example, we can add BufferedOutputStream object or BufferedInputStream object when creating DateOutputStream or DataInputStream.

DataInputStream/DataOutputStream

DataOutputStream converts basic numeric types and character types to byte streams in their original binary form in memory and outputs them to a file. DataInputStream converts the contents of the file and stores it in the original binary form into a variable of basic numeric type or character type.

DataOutputStream

DataInputStream

DataOutputStream implements the DataOutput interface to write basic numbers and characters. DataInputStream implements the DataInput interface to read values ​​and characters. It can be seen that they copy primitive numeric types in memory and in files without any modification.

The following takes DataOutputStream as an example to illustrate the methods in the class.

For example, writeInt(int x) outputs x directly to a file. For example, the integer 199 is 00000000 00000000 00000000 1100 0111 4 bytes in memory (0x000000C7 in hexadecimal), writeInt(199) writes these 4 bytes to the file.

There are several ways to work with characters and strings.

writeChar(char c) writes characters to the file, the character type is stored in memory as a 2-byte Unicode value, then they are written to the file in this 2-byte form. For example, the character '1' stored in memory is the Unicode code value of '1' 0x0031, and writeChar('1') stores these 2 bytes into the file.

writeChars(String s) writes the characters in the string to the file in sequence. It does not write the number of characters in the character, so if you want to write the number of characters in the string for reading to determine the number of characters in the string, you can use writeInt(int v before calling writeChars(String s) ) method to write the length of the string.

writeUTF(String s) first writes 2-byte string length information to the output stream, and then writes the characters in the string s to the output stream in modified UTF-8 form. For example, writeUTF("ABCDEF") writes eight bytes to the file, which are 00 06 41 42 43 44 45 46 in hexadecimal. Compared with writeChars(String s), writeUTF(String s) records the length of string s. And if the characters in string s are mostly ASCII characters, writeUTF(String s) will save more space than writeChars(String s).

DataInputStream/DataOutputStream

To create a DataInputStream/DataOutputStream object, use the following constructor:

  • public DataInputStream(InputStream instream)
  • public DataOutputStream(OutputStream outstream)

The following code creates an input stream that reads a stream of bytes from the in.dat file. The output stream writes the values ​​to the out.data file.

DataInputStream input =
    new DataInputStream(new FileInputStream("in.dat"));
DataOutputStream output =
    new DataOutputStream(new FileOutputStream("out.dat"));

example

import java.io.*;

public class TestDataStream {
  public static void main(String[] args) throws IOException {
    try ( // Create an output stream for file temp.dat
      DataOutputStream output =
        new DataOutputStream(new FileOutputStream("temp.dat"));
    ) {
      // Write student test scores to the file
      output.writeUTF("John");
      output.writeDouble(85.5);
      output.writeUTF("Jim");
      output.writeDouble(185.5);
      output.writeUTF("George");
      output.writeDouble(105.25);
    }

    try ( // Create an input stream for file temp.dat
      DataInputStream input =
        new DataInputStream(new FileInputStream("temp.dat"));
    ) {
      // Read student test scores from the file
      System.out.println(input.readUTF() + " " + input.readDouble());
      System.out.println(input.readUTF() + " " + input.readDouble());
      System.out.println(input.readUTF() + " " + input.readDouble());
    }
  }
}

BufferedInputStream/BufferedOutputStream

BufferedInputStream/BufferedOutputStream is also a subclass of FilterInputStream/FilterOutputStream. Their function is very simple. They open up buffers for reading/writing files in memory, so that you don't need to call the write/read function each time. Read/write directly from the file on the disk , because disk file operations are very slow compared to memory operations. It can be understood that BufferedInputStream/BufferedOutputStream contains an array of bytes. This array acts as a buffer. For example, BufferedOutputStream writes the contents of the array to the disk file at one time when the array is full, which is faster than calling the write function once to write the bytes to the disk file.

BufferedInputStream/BufferedOutputStream

BufferedInputStream/BufferedOutputStream have no new methods, their methods are inherited from InputStream/OutputStream, of course, they override these methods of the parent class.

We can add BufferedOutputStream object or BufferedInputStream object when creating DateOutputStream or DataInputStream.

DataOutputStream output = new DataOutputStream(
    new BufferedOutputStream(new FileOutputStream("temp.dat")));
DataInputStream input = new DataInputStream(
    new BufferedInputStream(new FileInputStream("temp.dat")));

For the read and write of a small amount of data, the effect of buffered stream is not obvious, but when the data to be read and written is large, the effect is more significant.

example

import java.io.*;

public class Copy {
  /** Main method
     @param args[0] for sourcefile 
     @param args[1] for target file
   */
  public static void main(String[] args) throws IOException { 
    // Check command-line parameter usage
    if (args.length != 2) { 
      System.out.println(
        "Usage: java Copy sourceFile targetfile");
      System.exit(1);
    }

    // Check if source file exists
    File sourceFile = new File(args[0]);
    if (!sourceFile.exists()) {
       System.out.println("Source file " + args[0] 
         + " does not exist");
       System.exit(2);
    }

    // Check if target file exists
    File targetFile = new File(args[1]);
    if (targetFile.exists()) {
      System.out.println("Target file " + args[1] 
        + " already exists");
      System.exit(3);
    }

    try (
      // Create an input stream
      BufferedInputStream input = 
        new BufferedInputStream(new FileInputStream(sourceFile));

      // Create an output stream
      BufferedOutputStream output = 
        new BufferedOutputStream(new FileOutputStream(targetFile));
    ) {
      // Continuously read a byte from input and write it to output
      int r, numberOfBytesCopied = 0;
      while ((r = input.read()) != -1) {
        output.write((byte)r);
        numberOfBytesCopied++;
      }

      // Display the file size
      System.out.println(numberOfBytesCopied + " bytes copied");
    }
  }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325324834&siteId=291194637