JAVA基础(三十七)IO流

【分类】

按操作数据分为两种:字节流和字符流

字节流的两个顶层父类:

1.inputstream  2.OutputStream


字符流的两个顶层父类:

1.Reader 2.Writer


这些体系的子类都以父类名作为后缀。

而且子类名的前缀就是该对象的功能


记住:如果操作文字数据,建议优先考虑字符流。

而且要将数据从内存写到硬盘上。要使用字符流中的输出流Writer


按流向分为:输入流和输出流

输入流和输出流相对于内存设备而言

将外设中的数据读取到内存中:输入流
将内存的数据写入到外设中:输出流

【字符流的由来】
字符流:

其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的码表。获取对应的文字。

再对这个文字进行操作。简单说:字节流+编码表

由来:

以前其实没有字符流,是后面才有的。

这就要从编码表说起了,为了能让计算机能识别美国的生活中的文字,就产生了用二进制和它文字
的对应关系表,ASCII码表,而二进制转换成十进制就是数字,例如:97对应a,这张
码表记录了美国所有的文字和数字的对应关系。可是,其他国家也需要去做这样的事情
,所以就得让其他国家的文字和二进制对应起来,这样就产生了很多码表,中国有中国
的码表,日本有日本的码表等等,但是多张码表不利于数据的互通,所以Unicode(国际标准码表)
就产生了,java中内置的就是Unicode。Unicode会将各个国家的编码重新对应。因为相同的数字在不同的编码表中
表示的文字不一样,例如: 一个中文在GBK中有对应得数字,但是这个数字在其他编码里面表示的就是其他的国家对应的文字了,
这样在Unicode中就会造成冲突,所以,Unicode会将各个国家的编码重新对应。所以我们读数据的时候,
就需要指定码表。所以就将用于读取字节数据的字节流和编码表结合,封装成了字符流,这样字符流就产生了。

【例子】

//需求:将一些字符存储到硬盘中

如果文件不存在,则会自动创建,如果文件存在,则会覆盖

private static final String LINE_SEPARATOR=System.getProperty("line.separator");


FileWriter fw=null;


try{
//第二个参数为是否续写

// fw=new FileWriter("demo.txt");

fw=new FileWriter("demo.txt",true);

//调用Writer对象中的write(String)方法,写入数据。
//其实数据写入到临时存储缓冲区中。
fw.write("abcd");

//换行

fw.write("abcd"+LINE_SEPARATOR+"HHAHH");

//进行刷新,将数据直接写到目的地中
fw.flush();
//关闭流,释放资源
fw.close();

}catch(IOException e){

  System.out.println(e.toString());

}finally {//要是创建fw的时候被try catch了fw就是null了 所以需要判空
   if (fw != null)
     try {
     fw.close();
         } catch (IOException e) {
    // code....
         throw new RuntimeException("关闭失败");
                }
   }

【例2】
读写,一次读一个字符

//1,创建读取字符数据的流对象。
        /*
         * 在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的。 
         * 
         * 用一个读取流关联一个已存在文件。 
         */
        FileReader fr = new FileReader("demo.txt");
        
        int ch = 0;
        
        while((ch=fr.read())!=-1){
            System.out.println((char)ch);
        }
        
        /*
        //用Reader中的read方法读取字符。
        int ch = fr.read();
        System.out.println((char)ch);
        int ch1 = fr.read();
        System.out.println(ch1);
        int ch2 = fr.read();
        System.out.println(ch2);
        */
        
        fr.close();


一次读一个数组:


            FileReader fr = new FileReader("demo.txt");
        
        /*
         * 使用read(char[])读取文本文件数据。
         *  
         * 先创建字符数组。
         */
        char[] buf = new char[1024];
        
        int len = 0;
        
        while((len=fr.read(buf))!=-1){
            System.out.println(new String(buf,0,len));
        }
        
        /*
        int num = fr.read(buf);//将读取到的字符存储到数组中。num 返回的是数组的长度
        System.out.println(num+":"+new String(buf,0,num));
        */
        
        
        
        
        fr.close();


【例3】复制文本文件

既然是文本那就选择字符流

private void copyFile() throw IOException{
   //读取一个已有的文本文件,使用字符流来读取
   FileReader fr=new FileReader("copytext1.txt");
   //创建一个目的,用于存储读到的数据
   FileWriter fw=new FileWriter("copytext2.txt");
    //一次读写一个字符
   int ch=0;    
   while((ch=fr.read())!=-1){
        w.write(ch);
    }
   fw.close();
   fr.close();
  
}

一次读写一个数组

private void copyFile2(){

    FileReader fr=null;
    FileWriter fw=null;
    try{
     //创建一个临时容器,用于缓存读取到的字符
    char[]buf=new char[1024];
    //定义一个变量记录读取到的字符数,(其实就是往数组里装的字符个数)

        int len=0;
        while((len=fr.read(buf))!=-1){
        fw.write(buf,0,len);
              }
    }catch(Exception e){
    }finally{
    if(fw!=null)
        try{
        fw.close();
        }catch(IOException e){

            }

    
    if(fr!=null)
        try{
     fr.close();
    }catch(IOEception e){
        

    }

          
        
    }

}


我们做程序的有两部分优化,第一部分就是设计优化,第二部分就是性能优化

设计优化就是对代码进行重构,让代码实现更强的扩展性,灵活性,以及复用性,
所以我们会用很多的设计模式来实现设计优化。提高性能优化的一个重要手段之一
就是缓冲。

【字符流缓冲区】

缓冲区的出现提高了对数据的读写效率。
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用
在流的基础上对流的功能进行了增强


【字符流缓冲区写入例子】

FileWriter fw= new FileWriter("test.txt");

BufferedWriter bufw=new BufferedWriter(fw);

bufw.write("abdcef");

//bufw.newLine();//行分隔符

bufw.flush();

bufw.close();

【字符流缓冲区读例子】
缓冲区读的方法有读一个字符,数组,行(这个是字符特有的读取方式)

FileReader fr=new FileReader("buf.txt");
BufferedReader bufr =new BufferedReader(fr);
String line=null;
while((line=bufr.readLine())!=null){

    System.out.println(line);

}


【字符流缓冲区复制文件】

FileReader fr =new FileReader("buf.txt");
BufferedReader bufr=new BufferedReader(fr);

FileWriter fw=new FileWriter("copy.txt");
BufferedWriter bufw=new BufferedWriter(fw);

String line=null;

while((line=bufr.readLine())!=null){

  bufw.write(line);

  bufw.newLine();

  bufw.flush();


}
bufr.close();
bufw.close();


自定义缓冲区


package cn.itcast.p4.io.charstream.mybuffer;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

/**
 * 自定义的读取缓冲区。其实就是模拟一个BufferedReader.
 * 
 * 分析:
 * 缓冲区中无非就是封装了一个数组,
 * 并对外提供了更多的方法对数组进行访问。
 * 其实这些方法最终操作的都是数组的角标。
 * 
 * 缓冲的原理:
 * 其实就是从源中获取一批数据装进缓冲区中。
 * 在从缓冲区中不断的取出一个一个数据。
 * 
 * 在此次取完后,在从源中继续取一批数据进缓冲区。
 * 当源中的数据取光时,用-1作为结束标记。 
 * 
 * 
 * @author Administrator
 *
 */
public class MyBufferedReader extends Reader {

    private Reader r;
    
    //定义一个数组作为缓冲区。
    private char[] buf = new char[1024];
    
    //定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。    
    private int pos = 0;    
    
    
    //定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。
    private int count = 0;
    
    
    MyBufferedReader(Reader r){
        this.r = r;
    }
    
    /**
     * 该方法从缓冲区中一次取一个字符。 
     * @return
     * @throws IOException
     */
    public int myRead() throws IOException{
        
        if(count==0){
            count = r.read(buf);
            pos = 0;
        }
        if(count<0)
            return -1;
        
        char ch = buf[pos++];
        
        count--;
        
        return ch;
        
        /*
        //1,从源中获取一批数据到缓冲区中。需要先做判断,只有计数器为0时,才需要从源中获取数据。
        if(count==0){
            count = r.read(buf);
            
            if(count<0)
                return -1;
            
            //每次获取数据到缓冲区后,角标归零.
            pos = 0;
            char ch = buf[pos];
            
            pos++;
            count--;
            
            return ch;
            
        }else if(count>0){
            
            char ch = buf[pos];
            
            pos++;
            count--;
            
            return ch;
            
        }*/
        
    }
    
    public String myReadLine() throws IOException{
        
        StringBuilder sb = new StringBuilder();
        
        int ch = 0;
        while((ch = myRead())!=-1){
            
            if(ch=='\r')
                continue;
            if(ch=='\n')
                return sb.toString();
            //将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。
            sb.append((char)ch);
            
        }        
        
        if(sb.length()!=0)
            return sb.toString();
        return null;
    }

    public void myClose() throws IOException {
        
        r.close();
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        
        return 0;
    }

    @Override
    public void close() throws IOException {
    }
}


【LineNumberReader】

可以获取读取内容的行号

例:

   FileReader r=new FileReader("abc.txt");
   LineNumberReader lnr=new LineNumberReader(r)
   String line=null;
   lnr.setLineNumber(100);//从第100行开始读
   while((line=lnr.readLine())!=null){

    System.out.println(lnr.getLineNumer()+""+line);
}
   lnr.close();

   


【字节流】

字节输出流

FileOutputStream fos =new FileOutputStream("123.txt");

fos.write("123".getBytes());


fos.close();


字节读取流,这种方式效率太低千万不要使用

FileInputStream fis=new FileInputStream("123.txt");

int len=0

//一次读取一个

//len = fis.read();


while((len=fis.read())!=-1){
   System.out.println((char)ch);
}
fis.close();

一次读取一个数组

byte[] buf =new byte[1024];

int len=0;

while((len=fis.read(buf))!=-1){
  System.out.println(new String(buf,0,len));

}

【字节复制】


public void copy_1() throw IOException{
  FileInputStream fis =new FileInputStream("c:\\123.txt");

  FileOutputStream fos = new FileOutputStream("c:\\234.txt");
 

  int len=0;

  byte [] buf=new byte[1024];

  while((len=fis.read(buf))!=-1){

    fos.write(buf,0,len);

}

  fos.close();
  fis.close();  
}

【字节流缓冲区】


public void copy_2() throw IOException{
  FileInputStream fis =new FileInputStream("c:\\123.txt");

  BufferedInputStream bufis= new BufferedInputStream(fis);

  FileOutputStream fos = new FileOutputStream("c:\\234.txt");

  BufferedOutputStream bufos=new BufferedOutStream(fos);
 

  int len=0;


//  byte [] buf=new byte[1024];//使用缓冲区的话,这里就多余了

//  while((len=bufis.read(buf))!=-1){
//    bufos.write(buf,0,len);
//        bufos.flush();


  while((len=bufis.read())!=-1){
    bufos.write(buf,0,len);
        bufos.flush();


}

  bufos.close();
  bufis.close();  
}

【键盘录入】

InputStream in=System.in;
System.out.println(ch);

in.close();//这个一般不用,他会随着系统的消失而消失,它是唯一的,如果关了

InputStream in2= System.in;
in.read();
就会报异常

【读取键盘录入】

public static void readKey2() throws IOException {
        
        /*
         * 获取用户键盘录入的数据,
         * 并将数据变成大写显示在控制台上,
         * 如果用户输入的是over,结束键盘录入。
         * 
         * 思路:
         * 1,因为键盘录入只读取一个字节,要判断是否是over,需要将读取到的字节拼成字符串。
         * 2,那就需要一个容器。StringBuilder.
         * 3,在用户回车之前将录入的数据变成字符串判断即可。 
         * 
         */
        
        //1,创建容器。
        StringBuilder sb = new StringBuilder();
        
        //2,获取键盘读取流。        
        InputStream in = System.in;
        
        //3,定义变量记录读取到的字节,并循环获取。         
        int ch = 0;
        
        while((ch=in.read())!=-1){
            
//            在存储之前需要判断是否是换行标记 ,因为换行标记不存储。 
            if(ch=='\r')
                continue;
            if(ch=='\n'){
                String temp = sb.toString();
                if("over".equals(temp))
                    break;
                System.out.println(temp.toUpperCase());
                sb.delete(0, sb.length());
            }
            else
            //将读取到的字节存储到StringBuilder中。
            sb.append((char)ch);
            
//            System.out.println(ch);
        }
        
    }


【转换流】

字节流转成字符流inputstreamreader
InputStream in=System.in;
InputStreamReader isr=new InputStreamReader(in);//这里变成了字符流
BufferedReader bufr =new BufferedReader(isr);
String line = bufr.readline();//读取字符串数据

字符流转成字节流outputStreamWriter
OutputStream out=System.out;//字节流
OutputStreamWriter osw=new OutputStreamWriter();
BufferedWriter bw=new BufferedWriter(osw);


【IO流的规律总结】


字节流的两个顶层父类:

1.InputStream      2.OutputStream


字符流的两个顶层父类

1.Reader   2.Writer

字节流:

InputStream
OutputStream
FileInputStream
FileOutputStream
BuffereInputStream
BuffereOutputStream


字符流:
Writer
Reader
FileReader
FileWriter
BufferedReader
BufferedWriter


转换流
InputStreamReader
OutputStreamWriter

流的操作规律:
之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。

想要知道开发时用到哪些对象。只要通过四个明确即可。

1,明确源和目的(汇)
    源:InputStream  Reader
    目的:OutputStream  Writer

2,明确数据是否是纯文本数据。
    源:是纯文本:Reader
        否:InputStream
    目的:是纯文本 Writer
        否:OutputStream
    
    到这里,就可以明确需求中具体要使用哪个体系。
    
3,明确具体的设备。
    源设备:
        硬盘:File
        键盘:System.in
        内存:数组
        网络:Socket流
        
    目的设备:
        硬盘:File
        控制台:System.out
        内存:数组
        网络:Socket流

4,是否需要其他额外功能。
    1,是否需要高效(缓冲区);
        是,就加上buffer.
    2,转换。
    
例子:
================================================================================
需求1:复制一个文本文件。
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本?
        是!
        源:Reader
        目的:Writer
        
    3,明确具体设备。
        源:
            硬盘:File
        目的:
            硬盘:File
    
        FileReader fr = new FileReader("a.txt");
        FileWriter fw = new FileWriter("b.txt");
        
    4,需要额外功能吗?
        需要,需要高效。
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
==================================================================================================
需求2:读取键盘录入信息,并写入到一个文件中。
        
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本呢?
        是,
        源:Reader
        目的:Writer
    3,明确设备
        源:
            键盘。System.in
        目的:
            硬盘。File
            
        InputStream in = System.in;
        FileWriter fw = new FileWriter("b.txt");
        这样做可以完成,但是麻烦。将读取的字节数据转成字符串。再由字符流操作。
    4,需要额外功能吗?
        需要。转换。    将字节流转成字符流。因为名确的源是Reader,这样操作文本数据做便捷。
            所以要将已有的字节流转成字符流。使用字节-->字符 。InputStreamReader
        InputStreamReader isr = new InputStreamReader(System.in);
        FileWriter fw = new FileWriter("b.txt");
        
        还需要功能吗?
        需要:想高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
        
            
        
===================================================
需求3:将一个文本文件数据显示在控制台上。
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本呢?
        是,
        源:Reader
        目的:Writer
    3,明确具体设备
        源:
            硬盘:File
        目的:
            控制台:System.out
            
        FileReader fr = new FileReader("a.txt");
        OutputStream out = System.out;//PrintStream
    4,需要额外功能吗?
        需要,转换。
        FileReader fr= new FileReader("a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        需要,高效。 
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        
================================================================

需求4:读取键盘录入数据,显示在控制台上。
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本呢?
        是,
        源:Reader
        目的:Writer
    3,明确设备。
        源:
            键盘:System.in
        目的:
            控制台:System.out
        
        InputStream in = System.in;
        OutputStream out = System.out;
        
    4,明确额外功能?
        需要转换,因为都是字节流,但是操作的却是文本数据。
        所以使用字符流操作起来更为便捷。
        InputStreamReader isr = new InputStreamReader(System.in);
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        
        为了将其高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        
============================================================


该使用哪个流?


看是否是纯文本

是: Reader  Writer
否:InputStream   OutputStream


看设备:

1.硬盘:File

2.键盘:system.in

3.内存:数组

4.网络:Socket流

java凡是涉及到String的一定会涉及编码表

如果没有指定,就会使用平台默认的编码格式


中文版windows的编码是gbk

只有FileInputStreamReader/FileOutputStreamWriter可以指定编码格式。

其他的都是使用默认的也就是平台的编码

【转换流的编码解码】

将一个中文字符串数据按照指定的编码表写入到一个文本中。

1、目的。OutputStream  Writer 

2、是否存文本.Writer

3、设备: 硬盘:File
 
FileWriter fr=new FileWriter("123.txt");
fr.writer("你好");

这里其实就是转换流指定了本机默认的编码表的体现。而且这个转换流的子类对象,可以方便操作文本文件。
简单说:操作文件的字节流+本机默认的编码表。这是按照默认码表来操作文件的边界类。

如果操作文本文件需要明确具体的编码,FileWriter就不行了,必须使用转换流

OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStreamWriter("12.txt"),"gbk");

osw.writer("你好");


需要高效

BufferedWriter bufw =new BufferedWriter(osw);


什么时候使用转换流呢?

1.源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁
2.一旦操作文本设计到具体的指定编码表时,必须使用转换流
【打印流】

1。字节流

        /*
         * PrintStream:
         * 1,提供了打印方法可以对多种数据类型值进行打印。并保持数据的表示形式。 
         * 2,它不抛IOException.
         * 
         * 构造函数,接收三种类型的值:
         * 1,字符串路径。
         * 2,File对象。
         * 3,字节输出流。
         */
        
        PrintStream out = new PrintStream("print.txt");
        
//        int by = read();
//        write(by);
        
//        out.write(610);//只写最低8位,
        
//        out.print(97);//将97先变成字符保持原样将数据打印到目的地。 
        
        out.close();


2。字符流

/**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        /*
         * PrintWriter:字符打印流。
         * 构造函数参数:
         * 1,字符串路径。
         * 2,File对象。
         * 3,字节输出流。
         * 4,字符输出流。
         * 
         */
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        
        PrintWriter out = new PrintWriter(new FileWriter("out.txt"),true);
        
        String line =  null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
            out.println(line.toUpperCase());
//            out.flush();
        }
        
        out.close();
        bufr.close();
    }

【序列流】

    
        /*
         * 需求:将1.txt 2.txt 3.txt文件中的数据合并到一个文件中。
         */
        //Vector已经不常用了,所以用Arraylist来代替。
//        Vector<FileInputStream> v = new Vector<FileInputStream>();        
//        v.add(new FileInputStream("1.txt"));
//        v.add(new FileInputStream("2.txt"));
//        v.add(new FileInputStream("3.txt"));
//        Enumeration<FileInputStream> en = v.elements();
        
        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
        for(int x=1; x<=3; x++){
            al.add(new FileInputStream(x+".txt"));
        }
        
        Enumeration<FileInputStream> en = Collections.enumeration(al);//代替了下面的代码,其实实现原理是一样的
        
        
        
        /*这个有点麻烦,所以用Collections工具类来代替
        final Iterator<FileInputStream> it = al.iterator();
        Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){

            @Override
            public boolean hasMoreElements() {
                
                return it.hasNext();
            }

            @Override
            public FileInputStream nextElement() {
                
                return it.next();
            }
            
        };*/
        
        SequenceInputStream sis = new SequenceInputStream(en);
        
        FileOutputStream fos = new FileOutputStream("1234.txt");
        
        byte[] buf = new byte[1024];
        
        int len = 0;
        
        while((len=sis.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        
        fos.close();
        sis.close();
        
    }


IO包中的其它流
【RandomAccessFile】

public class RandomAccessFileDemo {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {

        /*
         * RandomAccessFile
         * 一看这个类名字,纠结。不是io体系中的子类。
         * 
         * 特点:
         * 1,该对象即能读,又能写。
         * 2,该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素,
         * 3,可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
         * 4,其实该对象就是将字节输入流和输出流进行了封装。 
         * 5,该对象的源或者目的只能是文件。通过构造函数就可以看出。 
         * 
         * 
         */
        
//        writeFile();
//        readFile();
        randomWrite();
    }
    
    public static void randomWrite() throws IOException{
        RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
        
        //往指定位置写入数据。
        raf.seek(3*8);
        
        raf.write("哈哈".getBytes());
        raf.writeInt(108);
        
        raf.close();
    }
    
    
    public static void readFile() throws IOException {
        
        RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "r");
        
        //通过seek设置指针的位置。
        raf.seek(1*8);//随机的读取。只要指定指针的位置即可。 
        
        byte[] buf = new byte[4];
        raf.read(buf);
        
        String name = new String(buf);
        
        int age = raf.readInt();
        
        System.out.println("name="+name);
        System.out.println("age="+age);
        
        System.out.println("pos:"+raf.getFilePointer());
        
        raf.close();
        
        
    }

    //使用RandomAccessFile对象写入一些人员信息,比如姓名和年龄。
    public static void writeFile() throws IOException{
        /*
         * 如果文件不存在,则创建,如果文件存在,不创建
         * 
         */
        RandomAccessFile raf = new RandomAccessFile("ranacc.txt","rw");
        
        raf.write("张三".getBytes());
        raf.writeInt(97);
        raf.write("小强".getBytes());
        raf.writeInt(99);
//        
        raf.close();
    }

}


【管道流】
package cn.itcast.io.p4.piped;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipedStream {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {

        PipedInputStream input = new PipedInputStream();
        PipedOutputStream output = new PipedOutputStream();
        
        input.connect(output);
        
        new Thread(new Input(input)).start();
        new Thread(new Output(output)).start();
        
    }

}


class Input implements Runnable{
    
    private PipedInputStream in;
    Input(PipedInputStream in){
        this.in = in;
    }
    public void run(){
        
        try {
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            
            String s = new String(buf,0,len);
            
            System.out.println("s="+s);
            in.close();
        } catch (Exception e) {
            // TODO: handle exception
        }
        
    }
}

class Output implements Runnable{
    private PipedOutputStream out;
    Output(PipedOutputStream out){
        this.out = out;
    }
    public void run(){
        
        try {
            Thread.sleep(5000);
            out.write("hi,管道来了!".getBytes());
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

【基本数据的流】

public class DataSteamDemo {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        
//        writeData();
        readData();
        
    }

    public static void readData() throws IOException {
        
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        
        String str = dis.readUTF();
        
        System.out.println(str);
    }

    public static void writeData() throws IOException {
        
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
        
        dos.writeUTF("你好");
        
        dos.close();
        
        
    }

}

【操作字节数组】
ByteArrayInputStream
ByteArrayOutputStream


public class ByteArrayStreamDemo{

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        
            ByteArrayInputStream bis =new ByteArrayInputStream("abcdef".getbytes());
            
            ByteArrayOutputStream bos=new ByteArrayOutputStream();

            int ch = 0;

            while((ch=bis.read())!=-1){
             bos.write(ch);        

        }
         System.out.println(bos.toString());
    }

}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值