zoukankan      html  css  js  c++  java
  • IO流—内存流、管道流、随机流

    转载于https://www.cnblogs.com/wulianjie/p/12231539.html

    1.内存操作流

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

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

    使用场景:

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

    ByteArrayOutputStream类的定义:

    public class ByteArrayOutputStream extends OutputStream

    主要方法:

    ByteArrayInputStream类的定义:

    public class ByteArrayInputStream extends InputStream

     

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

    复制代码
    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】
    ").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());
            }
        }
    
    }
    复制代码

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

    最后还有一个博文对于io中用到的两种设计模式进行的分析

    https://www.cnblogs.com/wxgblogs/p/5649933.html

  • 相关阅读:
    看懂SqlServer查询计划
    jQuery 插件autocomplete自动完成应用(自动补全)(asp.net后台)
    MVC Html.AntiForgeryToken() 防止CSRF攻击
    iOS开发UI篇—transframe属性(形变)
    iOS开发UI基础—手写控件,frame,center和bounds属性
    iOS开发UI篇—Button基础
    iOS开发UI篇—UITableviewcell的性能优化和缓存机制
    iOS开发UI篇—UITableview控件基本使用
    iOS开发UI篇—UITableview控件简单介绍
    iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)
  • 原文地址:https://www.cnblogs.com/jiazhutao/p/12403455.html
Copyright © 2011-2022 走看看