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

黑马程序员——学习笔记09.Java_IO流

2014-01-04 13:10 387 查看
----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流!
----------------------

IO流概念

Java 中对文件的操作是以流的方式进行的。流是Java 内存中的一组有序数据序列。Java 将数据从源(文件、内存、键盘、网络)读入到内存中,源源不断形成了流,再将这些流还可以写到另外的目的地(文件、内存、控制台、网络)。 IO流是就是处理设备之间的数据传输。

流分类

1.流按流向分为:输入流和输出流,输入流和输出流相对于内存设备而言的。

将外围设备的数据读到内存中是输入的过程,将内存的数据写入到外围设备中是输出的过程。

2.流按操作数据类型分为两种:字节流和字符流。,字节流读取的最小单位是一个字节(1byte=8bit),而字符流一次可以读取一个字符(1个字节,2个字节或者3个字节)。

3.流按照功能的不同分为:分节点流和功能流。节点流能够直接操作数据,而功能流则间接操作数据,给节点流添加功能。

字节流

字节流是最基本的流,文件的操作、网络数据的传输等都依赖于字节流,操作单元是以字节为单位。而字符流常常用于读取文本类型的数据或字符串流的操作。

1.输入字节流——InputStream

常用方法:

int read()

从输入流读取下一个数据字节。返回0到255范围内的 int字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1

int read(byte[] b)

从输入流中读取一定数量的字节并将其存储在缓冲区数组 b中,以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少可以读取一个字节并将其存储在b中。

int read(byte[] b, int off, int len)

将输入流中最多len个数据字节读入字节数组。尝试读取多达len字节,但可能读取较少数量。以整数形式返回实际读取的字节数。如果由于已到达流末尾而不再有数据,则返回 -1 。

参数:

b - 读入数据的缓冲区。

off - 在其处写入数据的数组b的初始偏移量。

len - 要读取的最大字节数。

void close() 关闭此输入流并释放与该流关联的所有系统资源。

2.输出字节流——OutputStream

常用方法

void write(int b)

将指定的字节写入此输出流。write的常规协定是:向输出流写入一个字节。要写入的字节是参数b的八个低位。b的24 个高位将被忽略。

void write(byte[] b)

将 b.length个字节从指定的字节数组写入此输出流。write(b)的常规协定是:应该与调用 write(b, 0, b.length)的效果完全相同。

write(byte[] b, int off, int len)

将指定字节数组中从偏移量off开始的len个字节写入此输出流。write(b, off, len)的常规协定是:将数组b中的某些字节按顺序写入输出流;元素b[off]是此操作写入的第一个字节,b[off+len-1] 是此操作写入的最后一个字节。

参数:b - 数据。

off - 数据中的初始偏移量。

len - 要写入的字节数

void flush()

刷新此输出流并强制写出所有缓冲的输出字节。flush的常规协定是:如果此输出流的实现已经缓冲了以前写入的任何字节,则调用此方法指示应将这些字节立即写入它们预期的目标。

注意:

不管是输入还是输出流,使用完毕后要close(),如果是带有缓冲区的输出流,应在关闭前调用 flush()。应该尽可能使用缓冲区,来减少IO次数,以提高性能。能用字符流处理的不用字节流。

基本代码演示:文件的拷贝。

class Demo{
public static void main(String[] args) throws IOException {
  //找到源,如果不存在就抛出FileNotFoundException异常。
InputStream fis  = new FileInputStream("F:\\a.mp3");
  //找到目的,如果不存在就创建。
OutputStream fos = new FileOutputStream("E:\\b.mp3");
  //创建缓冲区,最小单元是字节。
byte[] buf = new byte[1024];
int len = 0;
  //如果文件中没有数据,就抛出IOException异常。
while((len=fis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
fis.close();
}
}

字符流

字符流的处理和字节流差不多,API 基本上完全一样,就是操作数据单元不同。字符流就是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。简单来说:字符流 = 字节流 + 编码表。字节流通常对操作文本文件较为常用。

1.字符输入流——Reader

2.字符输出流——Writer

基本代码演示:

class Demo{
public static void main(String[] args) throws IOException   {
Reader in = new FileReader("F:\\a.txt");
Writer out =  new FileWriter("E:\\b.txt");
  //最小处理单元是字符。
char [] buf = new char[1024];
int len = 0;
while((len=in.read(buf))!=-1){
out.write(buf,0,len);
}
  //关流。
in.close();
out.close();
}
}

注意:Reader中 void write(String s)方法写入的是字符串。

缓冲流

创建缓冲区,通过在在缓冲区内读取和写入数据,提高读写效率。

1.输入字节缓冲流:BufferedInputStream

2.输出字节缓冲流:BufferedOutputStream

基本代码演示:

class Demo{
public static void main(String[] args) throws IOException   {
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("F:\\a.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("E:\\b.mp3"));
int len = 0;
while((len = bufis.read())!=-1){
bufos.write(len);
}
bufos.close();
bufis.close();
}
}

3.输入字符缓冲流: BufferedReader

4.输出字节缓冲流:BufferedWriter

基本代码演示:

class Demo{
public static void main(String[] args) throws IOException   {
BufferedReader bufin = new BufferedReader(new FileReader("F:\\a.txt"));
BufferedWriter bufout = new BufferedWriter(new FileWriter("E:\\b.txt"));
String line = null;
while((line=bufin.readLine())!=null){
bufout.write(line);
  bufout.newLine();
}
bufout.close();
bufin.close();
}
}

注意:BufferedReader中String readLine()方法在读取纯文本文件时比较常方便,按行读取。BufferedWriter中void newLine()方法是写入一个行分隔符,行分隔符字符串由系统属性 line.separator 定义的,不同操作系统是不同的。

转换流

1.字节装换流:InputStreamReader

是字节流通向字符流的桥梁,它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,否则接受平台默认的字符集。

2.字符转换流:OutputStreamWriter

是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

练习1:要求键盘录入,打印到控制台上。

public class IOTest{
public static void main(String[] args) throws IOException   {
//接受键盘录入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//输出到控制台上
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine())!=null){
//如果输出over就终止运行程序。
if("over".equalsIgnoreCase(line))
break;
//将输入的内容按大写输出到控制台上
bufw.write(line.toUpperCase());
//写入分隔行符,就是换行
bufw.newLine();
//写入一行就输出一行
bufw.flush();
}
//关流。
bufw.close();
bufw.close();
}

练习2:按指定的编码表读取或写入文本文件。

public class IOTest{
public static void main(String[] args) throws IOException   {
InputStreamReader is = new InputStreamReader(new FileInputStream("F:\\a.txt"),"utf-8");
OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream("E:\\b.txt"),"utf-8");
int content = 0;
while((content = is.read())!=-1){
os.write(content);
}
os.close();
is.close();

}

其他功能流

1.序列流:SequenceInputStream (对多个流进行合并)。

表示其他输入流的逻辑串联,它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

2.打印流

PrintStream:字节打印流

它的构造函数可以接收三种数据类型的值。

(1)字符串路径。(2)File对象。(3)OutputStream。

PrintWriter:字符打印流

构造函数可以接收四种类型的值。

(1)字符串路径。(2)File对象。

对于上述类型的数据,可以指定编码表(如:“GBK”)参数,相当于字符转换流的功能。

(3)OutputStream。(4)Writer。

对于上述类型的数据,可以指定自动刷新参数boolean值。

注意:该自动刷新值为true时,只有三个方法可以用:println,printf,format.

3.对象流:ObjectInputStream和ObjectOutputStream

当创建对象时,程序运行时它就会存在,当程序停止时,对象也就消失了。但是如果希望对象在程序不运行的情况下仍能存在并保存其信息,将会非常有用,对象将被重建并且拥有与程序上次运行时拥有的信息相同。可以使用对象的序列化。

对象的序列化:将内存中的对象直接写入到文件设备中

对象的反序列化:将文件设备中持久化的数据转换为内存对象

基本的序列化由两个方法产生:

一个方法用于序列化对象并将它们写入一个流中。

ObjectOutputStream---writeObject(Object object)将对象写入流中

一个方法用于读取流并反序列化对象。

ObjectInputStream----readObject()读取并返回对象

注意:

(1)所有需要被序列化的类必须是实现java.io.Serializable标记接口。如果这个类的字段维护了一个对象的引用变量,那么引用变量对应的类也要实现标记接口或者将这个引用变量修饰成transient。

(2)可序列化类的所有子类型本身都是可序列化。

(3)序列化不适用于静态变量,因为静态变量并不属于对象的实例变量的一部分。

(4)如果被序列化的对象需要被不同的类版本所兼容,可以在类中自定义UID值定义格式:static final long serialVersionUID = 42L,该值用于判断被序列化的对象和类文件是否兼容。

IO流的异常捕获处理

public static void copyFile(String srcPath, String destPath) {

FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(srcPath);
fos = new FileOutputStream(destPath);

byte[] byt = new byte[1024 * 1024];
int len = 0;
while ((len = fis.read(byt)) != -1) {

fos.write(byt, 0, len);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {

try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}
}

}

----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流!
----------------------

详细请查看:http://edu.csdn.net
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: