黑马程序员——Java基础(八)之异常处理、递归、IO流

时间:2021-04-03 00:46:44

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

程序出现了不正常的情况称为异常,Throwable类是Java中所有错误或异常的超类,异常的分类如下:

程序的异常:Throwable

严重问题:Error(这种问题一般是很严重的问题,更改代码无法解决。)

普通问题:Exception

编译期异常:非RuntimeException(无法编译,所以此问题必须处理。)

运行期异常:RuntimeException(出现这个问题是因为代码不够严谨,是需要修改代码的。)

       Java中的异常分为两大类:编译时异常和运行时异常,所有的RuntimeException类及其子类的实例被称为运行时异常,其它的被称为编译时异常。当程序出现异常时,jvm会自动做出处理,把异常的情况输出在控制台,并终止程序的运行。但是此处理方法不够好,需要我们自己处理,处理方式如下:

A: try ... catch ... finally;

基本格式:

try {

可能出现问题的代码;

} catch (异常名 变量) {

针对问题的处理;

} finally {

释放资源;

}

执行过程:

一旦在try里发现问题,jvm会生成一个异常对象,然后抛出,和catch里的异常匹配,匹配成功,则执行catch中的处理,最后结束此try...catch语句,继续执行后面的语句。

注意事项:

try里面的代码越少越好;

catch里面必须有针对内容处理的内容;

catch后的异常名能明确的尽量要明确,明确不了的,可以写其父类异常名;

出现多个异常时,需写多个catch,异常名出现上下级关系时,级别大的必须在后面。

被finally修饰的语句一定会被执行,但是如果再finally之前jvm退出了,就不能执行了。

Jdk7针对异常处理的新特性:

try{

可能出现问题的代码;

} catch (异常名1 | 异常名2 | ... 变量) {

针对问题的处理;

}

注意事项:

此方法针对catch中多个异常的处理方式是一致的;

多个异常的关系必须是平级关系。

B: throws;

在定义功能方法时,需要把出现的问题暴露出来让调用者去处理,就通过throws将异常抛出,所以throws的作用是在方法上声明异常。

格式:

throws 异常类名

注意:

throws的位置在方法的括号后面;

尽量不要在main方法上抛出;

编译期异常抛出后,调用者必须处理,运行期异常抛出后,调用者可以不用处理。

throw的作用:

在功能方法内部出现某种异常,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

throw和throws的区别:

throws:

用在方法声明后面,跟的是异常类名;

可以跟多个异常类名,用逗号隔开;

表示抛出异常,由该方法的调用者来处理;

throws表示出现异常的一种可能性,并不一定会发生这些异常。

throw:

用在方法体内,跟的是异常对象名;

只能抛出一个异常对象名;

表示抛出异常,由方法体内的语句处理;

throw表示抛出了异常,执行throw则一定抛出了某种异常。

异常处理时的原则:

如果该功能内部可以将问题处理,就用try处理,如果处理不了,就使用throws抛出,交由调用者处理。


Throwable类(Java.lang包)

概述:Java中所有错误或异常的超类,它有如下一些成员方法;

public String getMessage();

返回此异常消息的详细消息。

public String toString();

返回此异常的简短描述。

public void printStackTrace();

获取异常类名和信息,以及此异常出现在程序中的位置。

public void printStackTrace(PrintStream s);

将此异常信息输出到指定的输出流。

final,finally和finalize的区别:

final:最终的意思,可以修饰类、成员变量和成员方法,

修饰类,类不能被继承,

修饰变量,变量是常量,

修饰方法,方法不能被重写,

finally:是异常处理的一部分,用于释放资源,

finalize:是Object类的一个方法,用于垃圾回收。

自定义异常类

在Java开发中,有时候需要根据一些实际情况,自定义异常类,一个类必须继承自Exception或者RuntimeException才能是异常类。

下面是一个自定义异常类的使用,并使用try...catch做处理,

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">//自定义一个异常类
public class MyException extends Exception{
public MyException() {

}
public MyException(String Message) {
super(Message);
}
}</span></span></span></span></span></span></span></span></span>
<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">//判断输入年龄是否正确,年龄不正确就报错,并给出提示public class Student {public void chack(int age) throws MyException{if(age<0) {throw new MyException("请输入正确的年龄");}else {System.out.println("输入年龄成功");}}}</span></span></span></span></span></span></span></span></span>
<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">//测试类import java.util.Scanner;public class StudentDemo {public static void main(String[] args) {Student s = new Student();Scanner sc = new Scanner(System.in);int age = sc.nextInt();try {s.chack(age);} catch (MyException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}</span></span></span></span></span></span></span></span></span>

异常使用中的注意事项:

A:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子异常;

B:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是它的子集,子类不能抛出父类没有的异常;

C:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能使用try...catch方式,不能使用throws方式。


File类(java.lang包)

概述:文件和目录路径名的抽象表示形式。

构造方法:

public File(String pathname);

     根据一个路径创建File对象。

public File(String parent,String child);

     根据一个路径和一个子目录或子文件名创建File对象。

public File(File parent,String child);

     根据一个File对象和一个子目录或子文件名创建File对象。

成员方法

创建功能:

public boolean createNewFile();

     创建文件。(创建文件或者文件夹时,如果没有指定盘符,默认在项目路径下)

public boolean mkdir();

     创建文件夹。

public boolean mkdirs();

     创建多级文件夹。

删除功能:

public boolean delete();

     删除文件或文件夹。(删除文件夹时文件夹内必须为空;且此删除功能不走回收站)

修改功能:

public boolean renameTo(File dest);

     重命名文件。(调用方法时,如果两文件路径相同,就是重命名,反之,则为重命名加剪切)

判断功能:

public boolean isDirectory();

     判断是否是目录。

public boolean isFile();

     判断是否是文件。

public boolean exists();

     判断是否存在。

public boolean canRead();

     判断是否可读。

public boolean canWrite();

     判断是否可写。

public boolean isHidden();

     判断是否隐藏。

获取功能:

public String getAbsolutePath();

     获取绝对路径。

public String getPath();

     获取相对路径。

public String getName();

     获取名称。

public long length();

     获取长度。(字节数长度)

public long lastModified();

     获取最后一次的修改时间的毫秒值。

public String[] list();

     获取指定目录下的所有文件或文件夹的名称数组。

public File[] listFiles();

     获取指定目录下的所有文件或文件夹的File数组。

public String[] list(FilenameFilter filter);

     返回一个满足过滤器过滤要求的文件或目录的字符串数组。

public File[] listFiles(FilenameFilter filter);

     返回一个满足过滤器过滤要求的文件或目录的文件数组。


FilenameFilter接口(java.io包)

实现此接口的类实例可用于过滤器文件名。

成员方法:

boolean accept(File dir,String name);

     测试指定文件是否应该包含在某一文件列表中。其中dir表示文件所在的目录,name表示文件的名称。

此过滤器的使用:

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">//使用文件名称过滤器筛选以.umd结尾的文件。
public class FileDemo {
public static void main(String[] args) {
File file = new File("E:\\Ebook");
File[] fileArray = file.listFiles(new FilenameFilter() {

@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
boolean flag = new File(dir,name).isFile();
boolean flag2 = name.endsWith(".umd");
return flag&&flag2;
}
});
for(File f : fileArray) {
System.out.println(f.getName());
}
}
}</span></span></span></span></span></span></span></span>


递归

概述:方法定义中调用方法本身的现象。

递归使用中的注意事项:

A:递归一定要有出口,否则就是死递归;

B:递归的次数不能太多,否则就会内存溢出;

C:构造方法不能递归使用。

递归的使用:

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">//递归删除指定目录下带有文件的文件夹
public class FileDemo2 {
public static void main(String[] args) {
File srcFile = new File("E:\\Book");
deleteFile(srcFile);
}

private static void deleteFile(File srcFile) {
File[] fileArray = srcFile.listFiles();
if (fileArray != null) {
for (File file : fileArray) {
if (file.isDirectory()) {
deleteFile(file);
} else {
System.out.println(file.getName() + "---" + file.delete());
}
}
System.out.println(srcFile.getName() + "---" + srcFile.delete());
}
}
}</span></span></span></span></span></span></span>


IO流

Java对数据的操作时通过流的方式,用于操作流的对象都在IO包中,IO流是用来处理设备之间的数据传输的。

IO流分类:

按照数据流向:输入流(读入数据),输出流(写出数据);

按照数据类型:

字节流:

字节输入流(InputStream)

字节输出流(OutputStream

字符流

字符输入流(Reader)

字符输出流(Writer)

InputStream,OutputStream,Reader,Writer类都是抽象类,不能实例化,所以需要使用它们的具体子类。


FileOutputStream类(java.io包)

概述:是OutputStream的具体子类,将数据写入File的输出流。

构造方法:

public FileOutputStream(File file);

     创建一个指向File对象的字节输出流。

public FileOutputStream(Stiring name);

     创建一个指向指定name文件的字节输出流。

public FileOutputStream(File file, boolean append);

     如果第二个参数值为true,则为追加写入。

在创建字节输出流对象时,jvm做了以下几件事情:

A:调用系统功能去创建文件;

B:创建对象,并指向这个文件。

成员方法:

public void write(byte[] b);

     向文件中写入一个字节数组。

public void write(int b);

     写入一个字节。

public void write(byte[] b, int off, int len);

     写入字节数组的一部分。

public void close();

     关闭并释放与此流有关的所有系统资源,让流对象变成垃圾,使其被垃圾回收器回收。


FileInputStream类(java.io包)

概述:是InputStream的具体子类,用于读取File文件的输入字节流。

构造方法:

public FileInputStream(File file);

     创建一个字节输入流对象,指向指定的File文件。

public FileInputStream(String name);

     创建一个字节输入流对象,指向name表示的文件。

成员方法:

public int read();

     从此输入流中读取一个字节数据。(返回其实际读取的字节数据)

public int read(byte[] b);

     从此输入流中读取一个字节数组的数据。(此方法返回的是其实际读取的字节个数)


BufferedOutputStream类 (java.io包)

概述:具有缓冲功能的字节输出流。

构造方法:

public BufferedOutputStream(OutputStream out);

     创建一个字符缓冲输出流对象。

BufferedInputStream类(java.io包)

概述:具有缓冲功能的字节输入流。

构造方法:

public BufferedInputStream(InputStream in);

     创建一个字符缓冲输入流对象。

使用普通字节流和高效字节流复制文件

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//使用字节流复制图片的四种方法
public class StreamDemo {
public static void main(String[] args) {
File file = new File("E:\\烟花.jpg");

try {
copy1(file, "F:\\晚会1.jpg");
copy2(file, "F:\\晚会2.jpg");
copy3(file, "F:\\晚会3.jpg");
copy4(file, "F:\\晚会4.jpg");
} catch (IOException e) {
e.printStackTrace();
}
}

// 基本字节流一次读取一个字节
public static void copy1(File srcFile, String copyString) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(copyString);
int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
}
fos.close();
fis.close();
}

// 基本字节流一次读取一个字节数组。
public static void copy2(File srcFile, String copyString) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(copyString);
byte[] bys = new byte[1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
fos.close();
fis.close();
}

// 高效字节流一次读写一个字节
public static void copy3(File srcFile, String copyString) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(copyString));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}
bos.close();
bis.close();
}

// 高效字节流一次读写一个字节数组
public static void copy4(File srcFile, String copyString) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(copyString));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}</span></span></span></span></span>


转换流(字符流)

由于字节流操作中文不是特别方便,所以就使用转换流来专门操作文字,转换流即字符流,是由字节流和编码表的构成的。编码表是由字符及其对应的数值组成的一张表,简体中文Windows操作系统默认使用GBK编码表,Linux系统默认使用UTF-8编码表。

String类中使用到编码表的方法:

构造方法:

public String(byte[] bytes,String charsetName);

     使用指定的编码表解码字节数组,将其转换为字符串。

成员方法:

public byte[] getBytes(String charsetName);

     使用指定的编码表将字符串编码,转换为字节数组。

OutputStreamWriter类(java.io包)

概述:字符输出流,是Writer类的具体子类。

构造方法:

public OutputStreamWriter(OutputStream out);

     创建一个使用默认字符编码的字符输出流对象。

public OutputStreamWriter(OutputStream out,String charsetName);

     创建一个使用指定字符编码的字符输出流对象。

成员方法:(以下方法都是继承自其父类Writer中的)

public void write(int c);

     写一个字符。

public void write(String str);

     写入字符串。

public void write(String str,int off,int len);

     写入字符数组的一部分。

public void write(char[] cbuf);

     写一个字符数组。

public void write(char[] cbuf,int off,int len);

     写入字符数组的一部分。

public void flush();

     刷新该缓冲区。

InputStreamReader类(java.io包)

概述:字符输入流,是Reader类的子类。

构造方法:

public InputStreamReader(InputStream in);

     创建一个使用默认字符编码的字符输入流对象。

public InputStreamReader(InputStream in,String charsetName);

     创建一个使用指定字符编码的字符输入流对象。

FileWriter类(java.io包)

概述:是写入字符文件的便捷类,继承自OutputStreamWriter类,但该类的构造方法更简便。

构造方法:

public FileWriter(File file);

public FileWriter(String filename);

     根据给定的File对象或文件名称创建一个字符输出流对象。

FileReader类(java.io包)

概述:用来读取文件的便捷类,继承自InputStreamreader类,但该类的构造方法更简洁。

构造方法:

public FileReader(File file);

public FileReader(String filename);

     根据给定的File对象或文件名称创建一个字符输入流对象。

BufferedWriter类(java.io包)

概述:高效字符输出流,继承自writer类。

构造方法:

public BufferedWriter(Writer out);

成员方法:

public void newLine();

     写入一个行分割符。

BufferedReader类(java.io包)

概述:高效的字符输入流,继承自Reader类。

构造方法:

public BufferedReader(Reader in);

成员方法:

public String readLine();

     读取一个文本行。

使用三种字符流复制文本文件:

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

//使用字符流复制文本文件
public class StreamDemo2 {
public static void main(String[] args) {
try {
copy1("E:\\srcfile.txt", "F:\\copyfile1.txt");
copy2("E:\\srcfile.txt", "F:\\copyfile2.txt");
copy3("E:\\srcfile.txt", "F:\\copyfile3.txt");
copy4("E:\\srcfile.txt", "F:\\copyfile4.txt");
} catch (IOException e) {
e.printStackTrace();
}
}

// 使用字符流复制文本文件(一次一个字符)
public static void copy1(String srcname, String copyname)
throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream(
srcname));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
copyname));
int ch = 0;
while ((ch = isr.read()) != -1) {
osw.write(ch);
}
osw.close();
isr.close();
}

// 使用便捷字符流复制文本文件(一次一个字符数组)
public static void copy2(String srcname, String copyname)
throws IOException {
FileReader fr = new FileReader(srcname);
FileWriter fw = new FileWriter(copyname);
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
fw.flush();
}
fw.close();
fr.close();
}

// 使用高效字符流复制文本文件(一次一个字符数组)
public static void copy3(String srcname, String copyname)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcname));
BufferedWriter bw = new BufferedWriter(new FileWriter(copyname));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
bw.flush();
}
bw.close();
br.close();
}

// 使用高效字符流复制文本文件(一次一行)
public static void copy4(String srcname, String copyname)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcname));
BufferedWriter bw = new BufferedWriter(new FileWriter(copyname));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}</span></span></span></span></span>


LineNumberReader类(java.io包)

概述:可跟踪行号的缓冲字符输入流,该类有两个方法分别用来获取和设置行号。

public int getLineNumber();

     获得当前行号。

public void setLineNumber(int lineNumber);

     设置当前行号。


DataOutputStream/DataInputStream数据输入/输出流

可以读写基本数据类型的数据流,它们继承自Out/InputStream类的子类,构造方法如下:

DataOutputStream(OutputStream out);

DataInputStream(InputStream in);

以下方法是写入和读取基本数据类型的方法:

public final void writeByte(int v);

public final void writeShort(int v);

public final void writeInt(int v);

public final void writeLong(long v);

public final void writeFloat(float v);

public final void writeDouble(double v);

public final void writeChar(int v);

public final void writeBoolean(boolean v);

public final byte readByte();

public final short readShort();

public final int readInt();

public final long readLong();

public final float readFloat();

public final double readDouble();

public final char readChar();

public final boolean readBoolean();


内存操作流

用于处理和存储临时信息,程序结束,数据就从内存中消失,它的close()方法无意义。内存操作流分为三种,

操作字节数组:ByteArrayInputStream/ByteArrayOutputStream

操作字符数组:CharArrayReader/CharArrayWriter

操作字符串:StringReader/StringWriter

以操作字节数组举例:

构造方法:

ByteArrayInputStream(byte[] buf);

ByteArrayOutputStream();

其中输出流有如下方法,用来创建一个byte数组,并且缓冲区的有效内容已复制到该数组中。

public byte[] toByteArray();


打印流

PrintStream字节打印流

PrintWriter字符打印流

打印流的特点:

a:只有写数据的,没有读数据的,只能操作目的地,不能操作数据源。

b:可以操作任意类型的数据。

c:启用自动刷新,该流就可以自动刷新(在调用println(),printf(),format()方法的时候)。

d:该流可以直接操作文本文件,也可以操作基本流。

其中字符打印流的构造方法:

public PrintWriter(File file);

public PrintWriter(OutputStream out,boolean autoFlush);

     创建一个带自动刷新功能的字符打印流。

public PrintWriter(String fileName);

public PrintWriter(Writer out,boolean autoFlush);

在Scanner类出现之前,通过字符缓冲流可以实现键盘录入数据,

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">//通过字符缓冲流包装标准输入流实现键盘录入数据
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入字符串");
String line = br.readLine();
System.out.println("你输入的字符串是" + line);
System.out.println("请输入整数");
String line2 = br.readLine();
int i = Integer.parseInt(line2);
System.out.println("你输入的整数是" + i);
}
}</span></span></span>


RandomAccessFile随机访问流(java.io包)

概述:随机访问流不属于流,是Object的子类,但它可对文件进行随机读取和写入,其随机读写是依赖指向文件的索引。

构造方法:

public RandomAccessFile(String name,String mode);

     创建一个随机访问流对象,第一个参数是文件路径,第二个参数是操作文件的模式,其中"rw"表示此对象即可以写数据,又可以读数据。

成员方法:

public final void writeXxx(xxx x);

     向文件中写入xxx类型的数据。

public final xxx readXxx();

     从文件中读取一个xxx类型的数据。

public long getFilePointer();

     返回此文件中当前的文件指针位置。(以字节为单位)

public void seek(long pos);

     设置此文件中指针的偏移量


SequenceInputStream类(合并流)

概述:继承自InputStream,可将多个文件合并写入一个新的文件。

构造方法:

public SequenceInputStream(InputStream s1,InputStream s2);

     创建一个合并流对象,该对象读取文件时,先读流s1,再读流s2。

public SequenceInputStream(Enumeration<? extends InputStream>e);

     创建一个能读取多个文件的合并流对象,该对象读取文件时,先将文件的输入流对象存放到vector集合中,再通过集合的elements()方法获得Enumeration对象。

将多个文档合并写入新文档:

<span style="font-size:14px;"><span style="font-size:14px;">import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

//将多个文档合并写入一个新文档
public class SequenceStreamDemo {
public static void main(String[] args) throws IOException{
InputStream is1 = new FileInputStream("E:\\a.txt");
InputStream is2 = new FileInputStream("E:\\b.txt");
InputStream is3 = new FileInputStream("E:\\c.txt");
Vector<InputStream> v = new Vector<InputStream>();
v.add(is1);
v.add(is2);
v.add(is3);
Enumeration<InputStream> e = v.elements();
SequenceInputStream sis = new SequenceInputStream(e);
OutputStream os = new FileOutputStream("F:\\copy.txt");
byte[] bys = new byte[1024];
int len = 0;
while((len = sis.read(bys)) != -1) {
os.write(bys,0,len);
}
os.close();
sis.close();
}
}</span></span>


ObjectOutputStream类(序列化流

概述:OutputStream的子类,把对象按照流一样的方式存入文本文件或在网络中传输。对应的还有烦序列化流:ObjectInputStream。

构造方法:

public ObjectOutputStream(OutputStream out);

成员方法:

public void writeXxx(xxx x);

     写入一个基本类型xxx的数据。

public void writeObject(object obj);

     将指定对象写入ObjectOutputStream。

对一个类进行序列化操作时,该类必须实现Serializable接口,才能被序列化,当没有实例化该接口时,会报异常NotSerializableException,并且当实现序列化接口后,还需在该类设置ID值,这样在对该类进行改动后,不影响序列化流对该类的读取操作。

transient关键字

当类中的某个成员变量不想被序列化是,可使用该关键字修饰。


Properties类(java.util包)

概述:属性集合类,该类继承自Hashtable,是一个可以和IO流相结合使用的集合类,能保存在流中或从流中加载。

区别于Hashtable的特殊成员方法:

public Object setProperty(Stirng key,String value);

     添加集合元素。

public String getProperty(String key);

     根据键获取值。

public Set<String> stringPropertyNames();

     获取所有键的集合。

该类和IO流结合使用时,可将数据从文件到集合之间相互读写,但文件中的数据必须是键值对形式。

public void load(Reader reader);

     把文件中的数据以字符流的形式读取到集合中。(文件中的数据必须是以键值对形式存储的)

public void store(Writer writer,String comments);

     把集合中的数据存储到文件。

Properties集合与IO流的结合使用,

<span style="font-size:14px;"><span style="font-size:14px;">import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;
import java.util.Set;

//使用属性集合类实现对文件的读写。
public class PropertiesDemo {
public static void main(String[] args) {
try {
myWrite();
myRead();
} catch (IOException e) {
e.printStackTrace();
}
}

//使用Properties集合将数据存储到文件中
public static void myWrite() throws IOException{
Properties p = new Properties();
p.setProperty("章子怡","北京人");
p.setProperty("刘德华","香港人");
p.setProperty("周杰伦","*人");
Writer w = new FileWriter("E:\\person.txt");
p.store(w,null);
}

//使用Properties集合从文件中读取数据并遍历
public static void myRead() throws IOException{
Properties p = new Properties();
Reader r = new FileReader("E:\\person.txt");
p.load(r);
Set<String> set = p.stringPropertyNames();
for(String key : set) {
String value = p.getProperty(key);
System.out.println(key+"=" + value);
}
}
}</span></span>


NIO包

概述:NIO就是新IO,是JDK4出现的,新IO和IO目的相同,但方式不同,它是采用内存映射文件的方式,将文件映射到内存中,然后像访问内存一样访问文件。

以下是JDK7出现的新IO;

Path接口(java.nio.file包):表示路径。

Paths类(java.nio.file包)

此类提供了一个静态方法能将URI转换为Path路径,

public static Path get(URI uri);

Files类(java.nio.file包)

此类提供了一些静态方法用来操作文件,

public static long copy(Path source,OutputStream out);

     复制文件。(第一个参数表示数据源的Path路径,第二个参数表示目的地的输出流)

public static Path write(Path path,Iterable<? extends CharSequence>lines,Charset cs,OpenOption... options);

     将一个Iterable类型集合以一种编码方式存储到指定Path路径的文件中。

NIO的使用:

<span style="font-size:14px;">import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;

//JDK7的NIO复制文件
public class NIODemo {
public static void main(String[] args) throws IOException{
//使用NIO复制文件,将E盘下的a.txt复制到F盘下的copy.txt
Files.copy(Paths.get("E:\\a.txt"), new FileOutputStream("F:\\copy.txt"));

//使用NIO将一个集合中的数据写入文件中
ArrayList<String> array = new ArrayList<String>();
array.add("Hello");
array.add("World");
Files.write(Paths.get("F:\\copy2.txt"), array, Charset.forName("GBK"));
}
}</span>