Java Input/Output

1. 简单的使用方式

java.util.Scanner (读)

Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();

java.io.PrintWriter  (写)

Writer writer = new PrintWriter("abc.txt");

   

Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式  (注意命名后缀)

2. 二进制IO

可序列化接口Serializable

可以写入输出流中的对象成为可序列化的,可序列化对象的类必须实现Serizlizable接口。

Serialzable接口是一种标记性接口,因为它没有方法,所以不需要在类中为实现Serializable接口增加额外的代码。实现这个接口可以启动Java的序列化机制,自动你完成存储对象和数组的过程。

关键字transient告诉Java虚拟机将对象写入对象流时忽略这些数据域。

序列化数组

只有数组中的元素都是可序列化的,这个数组才是可序列化的。一个完整的数组可以用writeObject方法存入文件,随后用readObject方法恢复。

示例:

 1 package com.artificerpi.demo;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.ObjectInputStream;
 7 import java.io.ObjectOutputStream;
 8 import java.io.Serializable;
 9 
10 public class Hello {
11     public static void main(String[] args) throws ClassNotFoundException, IOException {
12         int[] numbers = { 1, 2, 3, 4, 5 };
13         String[] strings = { "John", "Jim", "Jake" };
14         Programmer programmer = new Programmer("artificerpi", 17);
15         ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("array.dat", false)); // no
16                                                                                                         // append
17 
18         output.writeObject(numbers);
19         output.writeObject(strings);
20         output.writeObject(programmer);
21 
22         output.close();
23 
24         ObjectInputStream input = new ObjectInputStream(new FileInputStream("array.dat"));
25 
26         int[] nums = (int[]) input.readObject();
27         String[] strs = (String[]) input.readObject();
28         Programmer programmer2 = (Programmer) input.readObject();
29 
30         for (int a : nums) {
31             System.out.print(a);
32         }
33         System.out.println();
34 
35         for (String s : strs) {
36             System.out.print(s);
37         }
38 
39         System.out.println(programmer2.name + programmer2.age);
40 
41     }
42 }
43 
44 class Programmer implements Serializable {
45     String name;
46     transient int age;
47 
48     public Programmer(String name, int age) {
49         this.name = name;
50         this.age = age;
51     }
52 
53 }
View Code

随机访问文件RandomAccessFile

  RandomAccessFile类直接继承于Object类,它并不属于Streams结构的一部分。    

     public class RandomAccessFile implements DataOutput, DataInput, Closeable {

  RandomAccessFile类实现了DataInput和DataOutput接口,允许在文件内的随机位置上进行读写。

  当创建一个RandomAccessFile数据流时,可以指定两种模式(“r",只读或”rw",既允许读也允许写)。

RandomAccessFile raf = new RandomAccessFile("test.dat", "rw");

随机访问文件是由字节序列组成的。一个称为文件指针(file pointer)的特殊标记定位这些字节中的某个位置。文件的读写操作就是在文件指针所指的位置上进行的。打开文件时,文件指针置于文件的起始位置。在文件中进行读写数据后,文件指针就会向前移到下一个数据项。

 1 package com.artificerpi.demo;
 2 
 3 import java.io.IOException;
 4 import java.io.RandomAccessFile;
 5 
 6 public class Hello {
 7     public static void main(String[] args) throws IOException {
 8         RandomAccessFile raf = new RandomAccessFile("input.dat", "rw");
 9 
10         // Clear the file to destroy the old contents, if any
11         raf.setLength(0);
12 
13         // Write new integers to the file
14         for (int i = 0; i < 200; i++) {
15             raf.writeInt(i); // an integer accounts for 4 bytes
16         }
17 
18         System.out.println("Current file length is:" + raf.length());
19 
20         raf.seek(0);
21         System.out.println("The first number is " + raf.readInt());
22 
23         // Retrieve the tenth number
24         raf.seek(9 * 4);
25         System.out.println("The tenth number is: " + raf.readInt());
26 
27         raf.writeInt(555); // modify the eleventh number
28 
29         raf.seek(raf.length());
30         raf.writeInt(998);
31 
32         System.out.println("The new length is " + raf.length());
33 
34         raf.seek(10 * 4);
35         System.out.println("The eleventh number is " + raf.readInt());
36 
37         raf.close();
38     }
39 }
Current file length is:800
The first number is 0
The tenth number is: 9
The new length is 804
The eleventh number is 555

Closeable

Closeable is a source or destination of data that can be closed. The close method is invoked to release resources that the object is holding (such as open files).

void close()    Closes this stream and releases any system resources associated with it.

AutoColseable 继承了Closeable

Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the try-with-resources statement.

Flushable

 A Flushable is a destination of data that can be flushed. The flush method is invoked to write any buffered output to the underlying stream.

void flush() Flushes this stream by writing any buffered output to the underlying stream.

Writer.close() 实现一个writer一般在close流之前要flush(虽然很多实现类的flush没有什么操作). PrintWriter构造函数就有一个参数设定是否自动flush

一般而言,如果使用了Buffer,应谨慎处理流的关闭,弄清楚flush的必要性,否则不要省略。

/**
* Closes the stream, flushing it first. Once the stream has been closed,
* further write() or flush() invocations will cause an IOException to be
* thrown. Closing a previously closed stream has no effect.
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void close() throws IOException;

java.io.BufferedWriter close()方法就调用了flushBuffer(), 注意不是flush()

 @SuppressWarnings("try")
    public void close() throws IOException {
        synchronized (lock) {
            if (out == null) {
                return;
            }
            try (Writer w = out) {
                flushBuffer();
            } finally {
                out = null;
                cb = null;
            }
        }
    }

  

类似地,在实现一个压缩的Filter的时候,如果用到 ServletResponseWrapper 类, 在close流之前(finish数据传输之前)应该flush,否则reponse可能会显示为空(例如encoding 为chunked)。注意其flushBuffer的作用:

Forces any content in the buffer to be written to the client. A call to this method automatically commits the response, meaning the status code and headers will be written.

ServletResponse.flushBuffer() 

    public void flushBuffer() throws IOException;

Java 输入输出流性能优化

http://www.oracle.com/technetwork/articles/javase/perftuning-137844.html

更多代码

  JGet 一个简单的Java实现的多线程下载工具。

参考:

http://www.cnblogs.com/lanxuezaipiao/p/3371224.html

原文地址:https://www.cnblogs.com/7explore-share/p/5923420.html