黑马程序员Java I/O系统2

------- <a href="http://www.itheima.com" target="blank">android培训</a><a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

黑马程序员Java I/O系统2

装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。

若处理的数据量较多,为避免每个字节的读写都对流进行,可以使用过滤流类的子类缓冲流。缓冲流建立一个内部缓冲区,输入输出数据先读写到缓冲区中进行操作,这样可以提高文件流的操作效率。缓冲字节流类是BufferedInputStreamBufferedOutputStreamBufferedInputStream类允许把任何InputStream类“包装”成缓冲流并使它的性能提高。当创建缓冲输入流BufferedInputStream时,一个输入缓冲区数组被创建,来自流的数据填入缓冲区,一次可填入许多字节。

缓冲输出流BufferedOutputStream类提供和FileOutputStream类同样的写操作方法,但所有输出全部写入缓冲区中。当写满缓冲区或关闭输出流时,它再一次性输出到流,或者用flush()方法主动将缓冲区输出到流。它通过减小系统写数据的时间而提高性能。缓冲输出不提供额外的功能,只是为了提高性能。

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.IOException;

publicclass buffer {

    publicstaticvoid main(String[] args) throws IOException

    {

       //创建一个读取流对象和文件相关联。

       FileInputStream fr = new FileInputStream("buf.txt");

       //为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。

       BufferedInputStream bufr = new BufferedInputStream(fr);

       int line = 0;

       while((line=bufr.read())!= -1)

       {

           System.out.print(line);

       }

       bufr.close();

    }

}

 

import java.io.BufferedOutputStream;

import java.io.FileOutputStream;

import java.io.OutputStream;

publicclass BufferedOutputStreamTest {

    publicstaticvoid main(String[] args) throws Exception

    {

       OutputStream os = new FileOutputStream("1.txt");

       BufferedOutputStream bos = new BufferedOutputStream(os);

       bos.write("http://www.google.com".getBytes());

       bos.close();

       os.close();

    }

}

SequenceInputStream类允许连接多个InputStream流。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止。

DataInputStreamDataOutputStream类提供进行基本数据类型如整数和浮点数的输入/输出,这两个类的对象必须和一个输入类或输出类联系起来,而不能直接用文件名或文件对象建立。使用数据文件流的一般步骤:

1.       建立字节文件流对象

2.       基于字节文件流对象建立数据文件流对象

3.       用流对象的方法对基本类型的数据进行输入/输出

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

 

publicclass DataStream

{

    publicstaticvoid main(String[] args) throws Exception

    {

       DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(

              new FileOutputStream("data.txt")));

       byte b = 3;

       int i = 12;

       char ch = 'a';

       float f = 3.3f;

       dos.writeByte(b);

       dos.writeInt(i);

       dos.writeChar(ch);

       dos.writeFloat(f);

       dos.close();

       DataInputStream dis = new DataInputStream(new BufferedInputStream(

              new FileInputStream("data.txt")));    

       //读和写的顺序要保持一致

       System.out.println(dis.readByte());

       System.out.println(dis.readInt());

       System.out.println(dis.readChar());

       System.out.println(dis.readFloat());

      

       dis.close();

    }

}

 

 

管道流用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。传送输入流会提供要写入传送输出流的所有数据字节。数据由某个线程从PipedInputStream对象读取,由其他线程将其写入到相应的PipedOutputStream。数据由某个线程写入PipedOutputStream对象并由其他线程从连接的PipedInputStream读取。connect()方法将这两个流连接起来。

package seventh;

import java.io.*;

class Read implements Runnable

{

    private PipedInputStream in;

    Read(PipedInputStream in)

    {

       this.in = in;

    }

    publicvoid run()

    {

       try

       {

           byte[] buf = newbyte[1024];

 

           System.out.println("读取前。。没有数据阻塞");

           int len = in.read(buf);

           System.out.println("读到数据。。阻塞结束");

           String s= new String(buf,0,len);

 

        System.out.println(s);

           in.close();

       }

       catch (IOException e)

       {

           thrownew RuntimeException("管道读取流失败");

       }

    }

}

 

class Write implements Runnable

{

    private PipedOutputStream out;

    Write(PipedOutputStream out)

    {

       this.out = out;

    }

    publicvoid run()

    {

       try

       {

           System.out.println("开始写入数据,等待6秒后。");

           Thread.sleep(6000);

           out.write("piped lai la".getBytes());

           out.close();

       }

       catch (Exception e)

       {

           thrownew RuntimeException("管道输出流失败");

       }

    }

}

 

publicclass  PipedStreamDemo

{

    publicstaticvoid main(String[] args) throws IOException

    {

       PipedInputStream in = new PipedInputStream();

       PipedOutputStream out = new PipedOutputStream();

       in.connect(out);

       Read r = new Read(in);

       Write w = new Write(out);

       new Thread(r).start();

       new Thread(w).start();

    }

}

创建了一个文件读取流对象,和指定名称的文件相关联。要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException,如下

FileReader fr = new FileReader("demo.txt");

创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。

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

readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。

获取键盘录入对象:InputStream in = System.in;

将字节流对象转成字符流对象,使用转换流InputStreamReader

InputStreamReader isr = new InputStreamReader(in);

流操作的基本规律:

通过三个明确来完成。

1,明确源和目的。

         源:输入流。InputStream  Reader

         目的:输出流。OutputStream  Writer

2,操作的数据是否是纯文本。

         是:字符流。

         不是:字节流。

3,当体系明确后,在明确要使用哪个具体的对象。

         通过设备来进行区分:

         源设备:内存,硬盘。键盘

         目的设备:内存,硬盘,控制台。

键盘的最常见写法:BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流:PrintStream

构造函数可以接收的参数类型:

1,file对象。File

2,字符串路径。String

3,字节输出流。OutputStream

字符打印流:PrintWriter

构造函数可以接收的参数类型:

1,file对象。File

2,字符串路径。String

3,字节输出流。OutputStream

4,字符输出流,Writer。

import java.io.*;

 

publicclass  PrintStreamDemo

{

    publicstaticvoid main(String[] args) throws IOException

    {

       BufferedReader bufr =

           new BufferedReader(new InputStreamReader(System.in));

       PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

       String line = null;

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

       {

           if("over".equals(line))

              break;

           out.println(line.toUpperCase());

       }

       out.close();

       bufr.close();

    }  

}

Properties是hashtable的子类。也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。在加载数据时,需要数据有固定格式:键=值。

那么map+io -->properties. 配置文件可以实现应用程序数据的共享。

在流操作规律讲解时:

源设备,

         键盘 System.in,硬盘 FileStream,内存 ArrayStream

目的设备:

         控制台 System.out,硬盘FileStream,内存 ArrayStream

编码:字符串变成字节数组。

解码:字节数组变成字符串。使用工具类Arrays

RandomAccessFile

该类不是算是IO体系中子类。

而是直接继承自Object。

但是它是IO包中成员。因为它具备读和写功能。

内部封装了一个数组,而且通过指针对数组的元素进行操作。

可以通过getFilePointer获取指针位置,

同时可以通过seek改变指针的位置。

其实完成读写的原理就是内部封装了字节输入流和输出流。

如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。

如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

import java.io.RandomAccessFile;

 

publicclass RandomAccessFile1

{

    publicstaticvoid main(String[] args) throws Exception

    {

       Person p = new Person(1, "hello", 5.42);

       RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");

       p.write(raf);

       Person p2 = new Person();

       raf.seek(0); // 让读的位置重回到文件开头

       p2.read(raf);

       System.out.println(p2.getId() + ", " + p2.getName() + ", "

              + p2.getHeight());

    }

}

class Person

{

    intid;

 

    String name;

 

    doubleheight;

 

    publicint getId()

    {

       returnid;

    }

 

    publicvoid setId(int id)

    {

       this.id = id;

    }

 

    public String getName()

    {

       returnname;

    }

 

    publicvoid setName(String name)

    {

       this.name = name;

    }

 

    publicdouble getHeight()

    {

       returnheight;

    }

 

    publicvoid setHeight(double height)

    {

       this.height = height;

    }

 

    public Person()

    {

 

    }

 

    public Person(int id, String name, double height)

    {

       this.id = id;

       this.name = name;

       this.height = height;

    }

    publicvoid write(RandomAccessFile raf) throws Exception

    {

       raf.writeInt(this.id);

       raf.writeUTF(this.name);

       raf.writeDouble(this.height);

    }

 

    publicvoid read(RandomAccessFile raf) throws Exception

    {

       this.id = raf.readInt();

       this.name = raf.readUTF();

       this.height = raf.readDouble();

    }

 

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值