------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
黑马程序员Java I/O系统2
装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。
若处理的数据量较多,为避免每个字节的读写都对流进行,可以使用过滤流类的子类缓冲流。缓冲流建立一个内部缓冲区,输入输出数据先读写到缓冲区中进行操作,这样可以提高文件流的操作效率。缓冲字节流类是BufferedInputStream和BufferedOutputStream。BufferedInputStream类允许把任何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流。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止。
DataInputStream和DataOutputStream类提供进行基本数据类型如整数和浮点数的输入/输出,这两个类的对象必须和一个输入类或输出类联系起来,而不能直接用文件名或文件对象建立。使用数据文件流的一般步骤:
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();
}
}