java学习笔记之IO编程—内存流、管道流、随机流

1.内存操作流

之前学习的IO操作输入和输出都是从文件中来的,当然,也可以将输入和输出的位置设置在内存上,这就需要用到内存操作流,java提供两类内存操作流

  • 字节内存操作流:ByteArrayOutputStream:将内存中数据输出                      ByteArrayInputStream:将内容写入到内存中
  • 字符内存操作流:CharArrayWriter                                                                   CharArrayReader

使用场景:

假设现在需要实现IO操作,又不希望产生文件,则就可以以内存为终端进行处理,这个时候的流程
与文件IO不同,InputStream是往内存里写,OutputStream是读内存。

ByteArrayOutputStream类的定义:

public class ByteArrayOutputStream extends OutputStream

主要方法:

ByteArrayInputStream类的定义:

public class ByteArrayInputStream extends InputStream

 

扫描二维码关注公众号,回复: 8806635 查看本文章

代码实例:利用内存操作流实现一个小写字母转大写字母的操作

import java.io.*;

public class ByteArrayStreamDemo {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        String str = "i believe i can fly";
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        InputStream input = new ByteArrayInputStream(str.getBytes());
        int data = 0;
        while((data = input.read()) != -1) {
            output.write(Character.toUpperCase(data));
        }
        byte res[] = output.toByteArray();
        System.out.println(new String(res));
        input.close();
        output.close();
    }

}

2.管道流

管道流主要作用是实现两个线程之间的IO处理操作,java中提供两类管道流

  • 字节管道流:PipedInputStream(管道输入流)    PipedOutputStream(管道输出流)
  • 字符管道流:PipedReader                                     PipedWriter

如果想要进行管道输出,则必须把输出流连在输入流之上,在PipeOutputStream上有如下方法用于连接管道。

public void connect​(PipedInputStream src) throws IOException

在PipedReader上有如下方法用于连接管道。

public void connect​(PipedWriter snk)  throws IOException

PipedOutputStream类的定义:

public class PipedOutputStream extends OutputStream

构造方法:

public PipedOutputStream()

主要方法:

public void write​(int b) throws IOException//输出方法

PipedInputStream类的定义:

public class PipedInputStream extends InputStream

构造方法:

public PipedInputStream()

主要方法:

public int read() throws IOException//输入方法

代码实例:

import java.io.*;

public class PipedDemo {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        SendThread send = new SendThread();
        RecieveThread recieve = new RecieveThread();
        send.getOutput().connect(recieve.getInput());
        new Thread(send,"消息发送线程:").start();
        new Thread(recieve,"消息接收线程:").start();
    }

}
class SendThread implements Runnable{
    private PipedOutputStream output;//管道输出流
    
    public SendThread() {
        this.output = new PipedOutputStream();//实例化管道输出流
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=1;i<=10;i++) {
            try {
                this.output.write(("【第"+i+"次信息发送-" + Thread.currentThread().getName()+"i love you】\n").getBytes());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        try {
            this.output.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public PipedOutputStream getOutput() {
        return output;
    }
}
class RecieveThread implements Runnable{
    private PipedInputStream input;//管道输入流
    
    public RecieveThread() {
        this.input = new PipedInputStream();//实例化管道输入流
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        byte[] data = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            while((len=this.input.read(data))!= -1) {
                bos.write(data,0,len);
            }
            System.out.println("{"+Thread.currentThread().getName()+"接收消息}"+new String(bos.toByteArray()));
            bos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            this.input.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public PipedInputStream getInput() {
        return input;
    }
}

3.随机流(RandomAcceFile类)

    对于文件内容的处理操作主要是通过InputStream(Reader)OutputStream(Write)来实现,但是利用这些类
实现的内容读取只能够将数据部分部分读取进来,如果文件非常庞大(20G),此时存再按照传统的IO操作进行读取
和分析根本不可能完成,所以这种情况下RandomAccessFile类可以实现跳跃式的读取,可以只读取中间的部分内容
(前提:需要有一个完善的保存形式)

RandomAccessFile类的定义:

public class RandomAccessFile extends Object
implements DataOutput, DataInput, Closeable

构造方法:

public RandomAccessFile​(File file,String mode) throws FileNotFoundException

RandomAccessFile最大的特点实在数据的读取处理上,因为所有的数据时按照固定的长度进行的保存,所以读取的
时候就可以进行跳字节读取

主要方法:

public int skipBytes​(int n) throws IOException//向下跳
public void seek​(long pos) throws IOException//向回跳

     

代码实例:

/*
 * 实现文件的保存
 */
package IODemo;

import java.io.*;

public class RandomAccessFileDemo {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        File file = new File("D:"+File.separator+"mldn.txt");
        RandomAccessFile raf = new RandomAccessFile(file,"rw");
        String[] names = new String[] {"zhangsan","wangwu  ","lisi    "};//名字占8位
        int age[] = new int[] {30,20,16};//年龄占4位
        for(int x = 0 ; x < names.length ; x++) {
            raf.write(names[x].getBytes());
            raf.writeInt(age[x]);
        }
        raf.close();
    }

}
/*
 * 读取数据
 */
package IODemo;

import java.io.*;

public class RandomAccessFileDemo2 {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        File file = new File("D:"+File.separator+"mldn.txt");
        RandomAccessFile raf = new RandomAccessFile(file,"rw");
        {//读取lisi数据,跳过24位
            raf.skipBytes(24);
            byte[] data = new byte[8];
            int len = raf.read(data);
            System.out.println("姓名:"+new String(data,0,len).trim()+"年龄:"+raf.readInt());
        }
        {//读取wangwu数据,回跳12位
            raf.seek(12);
            byte[] data = new byte[8];
            int len = raf.read(data);
            System.out.println("姓名:"+new String(data,0,len).trim()+"年龄:"+raf.readInt());
        }
        {//读取zhangsan数据,回跳到顶点
            raf.seek(0);
            byte[] data = new byte[8];
            int len = raf.read(data);
            System.out.println("姓名:"+new String(data,0,len).trim()+"年龄:"+raf.readInt());
        }
    }

}

整体的使用之中由用户自行定义要读取的位置,而后按照指定的结构进行数据的读取

 

猜你喜欢

转载自www.cnblogs.com/wulianjie/p/12231539.html