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

-----------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 block
			e.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>




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值