转载请注明出:http://blog.csdn.net/jeffleo/article/details/52266200

有必要多看几遍的

这里写图片描述
关于字符和字节,例如文本文件,XML这些都是用字符流来读取和写入。而如RAR,EXE文件,图片等非文本,则用字节流来读取和写入。

DataInputStream和DataOutputStream

数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。当我们们需要读写Java的数据类型,DataInputStream和DataOutputStream就能帮我们了,而且重要的是,这两个类能够帮我们准确地读取数据,无论读和取得平台是否相同!

public class TestDadaIs { 
    public static void main(String[] args) throws IOException { 
        String file = "F:" + File.separator + "io" + File.separator + "a.txt"; 
 
        DataOutputStream dos = new DataOutputStream( 
                new BufferedOutputStream(new FileOutputStream(file))); 
 
        dos.writeInt(10); 
        dos.writeDouble(10.00000); 
        dos.writeUTF("Hello"); 
        dos.writeBoolean(true); 
        dos.writeChar('c'); 
        dos.writeByte('a'); 
 
        dos.flush(); 
        dos.close(); 
 
 
        DataInputStream dis = new DataInputStream( 
                new BufferedInputStream(new FileInputStream(file))); 
        System.out.println(dis.readInt()); 
        System.out.println(dis.readDouble()); 
        System.out.println(dis.readUTF()); 
        System.out.println(dis.readBoolean()); 
        System.out.println(dis.readChar()); 
        System.out.println(dis.readByte()); 
    } 
} 

各API的用法和作用,名字已经写得一清二楚。注意的是writeUTF的格式是UTF-8。

RandomAccessFile

RandomAccessFile这个类的作用很大,用来访问那些保存数据记录的文件的,它能够实现随机访问文件。使用seek()方法能够在文件内部的任何位置进行移动,由此达到随机访问。(BufferedInputStream有一个mark( )方法,但由于实用性不足,一般不使用)

RandomAccessFile实现了DataOutput和DataInput接口,但是它与DataInputStream,DataOutputStream毫无关系,它直接继承自Object,是一个独立的类。
它的作用:
第一,能够支持任意位置读写;
第二,拥有读取基本类型和UTF-8的具体方法。

比较重要的方法:
seek():设置文件指针位置
skipBytes():设置跳过字节数
setLength():设置文件大小

基本用法:

public class TestRAF { 
    static String file = "E:\\test\\hello.txt"; 
    static void read() throws Exception{ 
        RandomAccessFile raf = new RandomAccessFile(file, "r");//只读 
        for(int i = 0; i < 5; i++){ 
            System.out.println("Key " + i + " : " + raf.readDouble()); 
        } 
        raf.close(); 
    } 
 
    public static void main(String[] args) throws Exception { 
        RandomAccessFile raf = new RandomAccessFile(file, "rw");//读写 
        for(int i = 0; i < 5; i++){ 
            raf.writeDouble(i * 1.1314);     
        } 
        raf.close(); 
 
        read(); 
        System.out.println(); 
 
        raf = new RandomAccessFile(file, "rw"); 
        raf.seek(3 * 8);//double是8个字节的 
        //raf.skipBytes(3 * 8);//double是8个字节的 
        raf.writeDouble(81.000);//更改第4个的值 
        raf.close(); 
 
        read(); 
    } 
}

结果为:

Key 0 : 0.0 
Key 1 : 1.1314 
Key 2 : 2.2628 
Key 3 : 3.3941999999999997 
Key 4 : 4.5256 
 
Key 0 : 0.0 
Key 1 : 1.1314 
Key 2 : 2.2628 
Key 3 : 81.0 
Key 4 : 4.5256

由于double是8个字节的,raf.seek(3 * 8)则把文件指针设置到第四个double的开头处。调用write方法,则重写了原来的double值。

seek()和skipBytes()的区别:

seek():是绝对定位,要给定离文件开头的字节数。假如seek(0)则表示在文件开头。
skipBytes():是相对定位,给定字节数,就能跳过字节数的距离。

两者相比,seek()对系统的花销更大。

发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java IO系列(二):文件读取写入详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。