IO(八)

管道流

管道流的输入输出流可以直接连接,通过结合线程来使用。
Properties是IO与集合的结合,而管道流是IO与线程的结合

PipedInputStream:
构造函数:
PipedInputStream() 创建一个 PipedInputStream ,所以它还不是 connected 。 PipedInputStream(int pipeSize) 创建一个 PipedInputStream ,使其尚未 connected ,并使用指定的管道大小作为管道的缓冲区。
PipedInputStream(PipedOutputStream src) 创建一个 PipedInputStream ,使其连接到管道输出流 src 。
PipedInputStream(PipedOutputStream src, int pipeSize) 创建一个 PipedInputStream ,使其连接到管道输出流 src ,并为管道缓冲区使用指定的管道大小。

API:
void connect(PipedOutputStream src) 使此管道输入流连接到管道输出流 src 。连接方法,输入输出流都有,只要一个调用即可。

PipedOutputStream:
构造函数:
PipedOutputStream() 创建一个尚未连接到管道输入流的管道输出流。 PipedOutputStream(PipedInputStream snk) 创建连接到指定管道输入流的管道输出流。

RandomAccessFile

RandomAccessFile:随机访问文件,自身具备读写的方法。内部封装了一个byte数组,通过指针对数组的元素进行操作。
通过skipBytes(int x),seek(int x)来达到随机访问。
通过getFilePointer获取指针的位置。
(能完成读写的原理是,其内部封装了字节输入流和输出流

构造函数:
rw如果文件不存在,会创建文件,如果存在,不会覆盖。
r如果文件不存在,不会创建文件
RandomAccessFile(File file, String mode) 创建一个随机访问文件流从File参数指定的文件中读取,并可选地写入文件。
RandomAccessFile(String name, String mode) 创建随机访问文件流,以从中指定名称的文件读取,并可选择写入文件。

mode:
1 r:以只读方式打开指定文件。如果试图对该RandomAccessFile指定的文件执行写入方法则会抛出IOException
2 rw:以读取、写入方式打开指定文件。如果该文件不存在,则尝试创建文件
3 rws(了解):以读取、写入方式打开指定文件。相对于rw模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备,默认情形下(rw模式下),是使用buffer的,只有cache满的或者使用RandomAccessFile.close()关闭流的时候儿才真正的写到文件
4 rwd(了解):与rws类似,只是仅对文件的内容同步更新到磁盘,而不修改文件的元数据

API:
void write(int b) 将指定的字节写入此文件。
void writeInt(int v) 将 int写入文件为四个字节,高字节 int 。
void write(byte[] b) 从指定的字节数组写入 b.length个字节到该文件,从当前文件指针开始。
小例子演示:

public class Demo11 {
    public static void main(String[] args)  throws Exception{
        writeFile();
    }
    
    public static void writeFile() throws Exception{
        File file = new File("D:\\a.txt");
        if(file.exists())
            file.delete();
        RandomAccessFile raf = new RandomAccessFile("D:\\a.txt","rw");
        raf.write("张三".getBytes());
        raf.write(97);
        raf.close();
    }
}

发现a.txt有7个字节,内容是:张三a
其中raf.write("张三".getBytes());调用的是write(byte[] b) ,getBytes根据java本身的unicode编码转换为系统默认的utf-8编码后,为3个字节,所以张三两个字占了6个字节,而raf.write(97);调用的是write(int b),虽然int类型有4个字节,但是该方法只写入最低的8位,所以当int类型的值超过了8位时,进行写入操作就会丢失数据。此时就要使用writeInt方法。

比如,使用write方法得到的文件如下:

image.png

而此时使用writeInt再写一遍:

image.png

两次写操作,对于字符的编码都是一样的,采用Unicode码转换为utf-8的三位字节,而区别就是int类型写入了一个字节和四个字节。

=========================================
int readInt() 从该文件读取一个带符号的32位整数。
使用了writeInt之后,使用readInt来读取,非常方便。

这两个方法是这个类的精髓。
int skipBytes(int n) 尝试跳过 n字节的输入丢弃跳过的字节
void seek(long pos) 设置文件指针偏移,从该文件的开头测量,发生下一次读取或写入。
区别:
skipBytes只能往下跳,而seek可以随意调整文件指针的位置,更加灵活

小例子:
现有文本文件如下:


image.png

要求不读取李四和b,直接读取王五和后面的int。

public class Demo11 {
    public static void main(String[] args)  throws Exception{
        skipReadFile();
    }
    
    public static void skipReadFile() throws Exception{
        RandomAccessFile raf = new RandomAccessFile("D:\\A1.txt","r");
        raf.skipBytes(10);
        byte[] buf = new byte[6];
        raf.read(buf);
        System.out.println("名字:" + new String(buf));
        System.out.println("age:" + raf.readInt());
    }
}
image.png

小例子2:
不覆盖现有数据,在现有数据之后进行续写。

public static void seekWriteFile() throws Exception{
        RandomAccessFile raf = new RandomAccessFile("D:\\A1.txt","rw");
        raf.seek(10*2);
        raf.write("周七".getBytes());
        raf.writeInt(103);
}
image.png

RandomAccessFile应用:多线程共同写入数据而不会冲突。

DataStream

用于操作基本数据类型的流对象。

DataInputStream
构造函数:
DataInputStream(InputStream in) 创建使用指定的底层InputStream的DataInputStream。

API:
int readInt() 见 readInt方法 DataInput的一般合同。

String readUTF() 见 readUTF法 DataInput的一般合同。String readUTF() 见 readUTF法 DataInput的一般合同。

DataOutputStream
构造函数:
DataOutputStream(OutputStream out) 创建一个新的数据输出流,以将数据写入指定的底层输出流。

API:
void writeInt(int v) 将底层输出流写入 int作为四字节,高位字节。
有各种操作基本数据类型的方法。

void writeUTF(String str) 使用 modified UTF-8编码以机器无关的方式将字符串写入基础输出流。

小例子:

public class Demo12 {
    public static void main(String[] args)  throws IOException{
//      writeData();
        readData();
    }
    
    public static void readData() throws IOException{
        DataInputStream dataInput = new DataInputStream(new FileInputStream("D:\\dataOutput.txt"));
        System.out.println(dataInput.readInt());
    }
    
    public static void writeData() throws IOException{
        DataOutputStream dataOutput = new DataOutputStream(new FileOutputStream("D:\\dataOutput.txt"));
        dataOutput.writeInt(32);
        dataOutput.flush();
        dataOutput.close();
    }
}

你可能感兴趣的:(IO(八))