您的位置:首页 > 职场人生

黑马程序员_IO流_3

2013-10-10 22:38 330 查看
   ----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
1、字节流是由字节组成的,字节流是由字符组成的。
2、输入流就是能连续从其中读取数据的对象,输出流刚刚相反,就是能连续写入数据到其中的对象。
由上面2点可以知道JAVA的IO流中有4大基类,分别为InputStream,OutputStream,Reader,Writer。他们都是抽象类。由这4个类派生出来的子类名称都是以父类名作为类名的后缀,以类的功能来作为类的前缀。
 
Writer子类必须实现的方法有 write(char[], int, int)、flush() 和 close()。这3个方法也是最常用的方法。write()方法是将char[]数组中从第二个参数一直写到第三个参数。因为写入的参数会保存在流中,所以要调用flush()方法讲数据刷新到目的中。(一个字节构成不了要的数据)。因为Writer类要调用系统资源,所以要调用close()方法来关闭资源。FileWriter是个操作文件的Writer类。可以用来演示.

public static void main(String[] args) throws IOException {

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

fw.write("lailongwei");

fw.flush();

fw.close();

Runtime.getRuntime().exec("notepad.exe FileWriterDemo.txt");

}


FileWriter的构造函数中可以传入是否续写的参数。True表示续写。
 
Reader子类必须实现的方法只有 read(char[], int, int) 和 close()。read()方法读取一个字符。返回int类型,读到末尾返回-1。read(char[]),字符数组,用于存储读到的字符。返回读到的字符个数。FileReader是个操作文件的Reader类,和FileWriter对应。可以用来演示.

public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("FileWriterDemo.txt");
char[] temp = new char[16];
int len;
while ((len = fr.read(temp)) > 0) {
System.out.print(new String(temp, 0, len));
}
fr.close();
}


 

因为write()方法和read()方法每个细小的操作都要去调用系统底层的方法所以效率低。这个时候就出现了缓存区。缓存区的出现是为了提高数据的读写效率,分别为BufferReader和BufferWriter。他们是修饰类。修饰类要被修饰对象作为构造函数的参数。BufferReader中有readLine()特有方法。BufferWriter有newLine()这个特有方法。分别修改上面的两端代码如下:

public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("FileWriterDemo.txt");
//fw.write("lailongwei");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("lailongwei");
bw.newLine();
bw.flush();
fw.close();
bw.close();
Runtime.getRuntime().exec("notepad.exe FileWriterDemo.txt");
}

public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("FileWriterDemo.txt");
BufferedReader br = new BufferedReader(fr);
//		char[] temp = new char[16];
String line;
while ((line = br.readLine()) != null) {
System.out.print(line);
}
fr.close();
br.close();

}


 

缓存类的close()就会调用被修饰对象的close()方法。newLine()方法的好处是,不同系统换行的表示方式可能不同。readLine()方法原理:无论是读一行还是读多个字符,其实最终都是在硬盘上一个一个的读取,所以最终都是使用的还是read()方法一次一个的读取。
 
上面的演示都没有对异常进行处理。IO流中的IO异常处理方式:在try外部建立应用,然后在try中赋值,finally里面进行close()。close要用try语句块,因为也会跑出异常。在关闭之前要判断流是否为空,为空就不必关闭,不然会抛出异常。示例如下:

public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("FileWriterDemo.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.print(line);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//		char[] temp = new char[16];
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}


 

 
InputStream字节输入流,需要定义 InputStream 子类的应用程序必须总是提供返回下一个输入字节的方法(read()这个方法返回一个int类型。低八位表示读取到的byte类型,返回-1表示已经读到了末尾)。InputStream的available()方法返回可以读取的字节数。FileInputStream是它的操作文件的子类。
OutputStream字节输出流,需要定义 OutputStream 子类的应用程序必须始终提供至少一种可写入一个输出字节的方法(write()方法,就是read()方法的反操作)。FileOutputStream是它的操作文件的子类。OutputStream的flush并不会进行任何操作。因为他就是写入字节。
因为FileInputStream和FileOutputStream的效率都不高,所以要提高效率,BufferFileInputStream和BufferOutputStream来修饰,提高效率。下面通过键盘录入来演示

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferInDemo {

public static void main(String[] args) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("QQ.jpg"));
bos = new BufferedOutputStream(new FileOutputStream("Q_Q.jpg"));
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1){
bos.write(bytes, 0, len);
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
bis.close();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("复制成功");
}

}


 

InputStreamReader是字节流通向字符流的桥梁。而OutputStreamWriter是字符流通向字节流的桥梁。这两个桥梁的构造函数中可以选择需要解码或者编码的编码表。在存储时,如果需要加入指定的编码表。而指定的编码表只有转换流可以指定。所以要在转换流中填入指定的编码。下面通过键盘录入来演示:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class InputStreamReaderDemo {

public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line;
while (true) {
line = br.readLine();
if (line.equals("over")) {
break;
}
else {
bw.write(line.toUpperCase());
bw.flush();
}
}
} catch (Exception e) {
// TODO: handle exception
}
finally{
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


RandomAccessFile这个类的实例支持对随机访问文件的读取和写入。它不是IO体系中的之类,不过在IO包中。内部封装了一个数组,而且通过指针对数组元素进行操作。可以通过getFilePointer获取指针位置。同时可以通过seek方法来改变指针的位置,其实,完成读写的原理就是内封装了字节输入流和输出流,通过构造函数可以看出该类是否能进行写入(如果模式为只读r,就不会创建文件,如果为rw就会在需要的时候创建)。seek()调整指针的位置。skipBytes()是跳过多少个字节,不能往回跳。通过文件切割来演示:

 

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class SplitFiltDemo {

public static void main(String[] args) {
File file = new File("D:\\网络图片\\mypicture.jpg");
for (int i = 0; i < 4; i++) {
new Thread(new Split(file, i)).start();
}
System.out.println("没问题");
}

}

class Split implements Runnable{
private File file;
private int num;
public Split(File file,int num){
this.file = file;
this.num = num;
}
@Override
public void run() {
RandomAccessFile raf = null;
RandomAccessFile raFile = null;
try {
raf = new RandomAccessFile("切个" + num + ".split", "rw");
raFile = new RandomAccessFile(file, "r");
byte[] temp = new byte[1024];
int len = 0;
raFile.seek(file.length() / 4 * num);
while ((len = raFile.read(temp)) != -1 && raFile.getFilePointer() <= (file.length() / 4 * (num + 1))) {
raf.write(temp, 0, len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
raf.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
raFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}


              ObjectOutputStream是讲对象输出,不过这个对象必须要实现Serializable接口,这个借口中并没有具体的方法,是个标记接口.接口中有个序列号.对象的系列话指的是将堆内存中的对象保存在可以持续保存的地方。可以通过ObjectInputStream方法来重构对象。注意,静态成员不会被系列化,如果想让非静态成员也不参与系列化,这个成员就要用transient来修饰。

    
----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima
 
                                   


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java io流