您的位置:首页 > 编程语言 > Java开发

黑马程序员_文件IO流部分疑点和JDK1.7版本后新try-catch处理学习笔记

2014-03-14 20:09 375 查看
------- android培训java培训、期待与您交流! ----------

前言

IO流,应该算是JAVA程序,与外部沟通的桥梁吧。

这边整理一下自己在IO流学习中,经常容易忘掉的知识点。

说明:

1)本文中的代码,为了体现主干流程思想,暂时上抛所有异常。

2)JDK1.7版本以后,可以参考新try-catch的处理方法,处理IO流的关闭。

1、在文件后添加内容
实现方法:在新建文件流的时候,第二个参数置为true。eg:
private static void appendFile() throws IOException {
//打开文件流
FileWriter fw1 = new FileWriter("D:\\1.txt");
//写入文件
fw1.write("HelloWorld1");
//关闭文件流
fw1.close();

//再次打开文件流
FileWriter fw2 = new FileWriter("D:\\1.txt",true);
//写入文件
fw2.write("HelloWorld2");
//关闭文件流
fw2.close();
}


2、LineNumberReader类
通过LineNumberReader类读取行数、指定读取的起始行数,eg:
private static void lineNumber() throws FileNotFoundException, IOException {
LineNumberReader lnr = new LineNumberReader(new FileReader("D:\\ClassLoaderTest.java"));
//指定读取的起始行数
lnr.setLineNumber(2);
String line = null;
while(null!=(line=lnr.readLine()))
//获取行数,并打印行内容
System.out.println(lnr.getLineNumber() + ":" + line);
lnr.close();
}


3、打印流PrintWriter和PrintStream(Writer/OutputStream)

该流提供了打印方法,可以将各中数据类型的数据都原样打印。eg:
private static void PrintWriterTest() {
//新建打印流
PrintWriter pr = new PrintWriter(System.out);
//打印数据
pr.println("hello");
//打印基本数据
pr.println(1.111);

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
//打印对象
pr.println(list);
//关闭打印流
pr.close();
}


4、合并流
用于合并读取多个输入流,eg:
private static void sequenceInputStreamTest() throws FileNotFoundException,
IOException {
//用一个Vector存储多个输入流
Vector<FileInputStream> vector = new Vector<FileInputStream>();
vector.add(new FileInputStream("D:\\1.txt"));
vector.add(new FileInputStream("D:\\2.txt"));
vector.add(new FileInputStream("D:\\3.txt"));

//定义一个序列流
SequenceInputStream sis = new SequenceInputStream(vector.elements());

//定义一个输出流
FileOutputStream fos = new FileOutputStream("D:\\4.txt");

//依此读取 三个输入流 到 一个输出流 中
int len=0;
byte[] buf = new byte[1024];
while((len=sis.read(buf))>0) {
fos.write(buf, 0, len);
}

//关闭输出流
fos.close();

//关闭输入流
sis.close();
}


5、对象序列化ObjectInputStream和ObjectOutputStream
被操作的对象,需要实现Serializable接口(标记接口),eg:
1)可序列化的类:
import java.io.Serializable;
public class Person implements Serializable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2)序列化对象:
private static void objectOutputStreamTest() throws IOException,
FileNotFoundException {
//定义对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\object.txt"));
//定义待序列化的对象
Person person = new Person();
person.setName("cby");
//序列化对象到文件中
oos.writeObject(person);
//关闭输出流
oos.close();
}
3)反序列化对象
private static void objectInputStreamTest() throws IOException,
FileNotFoundException, ClassNotFoundException {
//定义对象输入流
ObjectInputStream oos = new ObjectInputStream(new FileInputStream("D:\\object.txt"));
//从文件中反序列化对象
Person person = (Person)oos.readObject();
//获取对象中的属性值
System.out.println(person.getName());
//关闭输入流
oos.close();
}

4)序列化的文件



注意:
1)、静态属性是不能被序列化的
2)、如果有非静态成员不详序列化,应该用transient修饰。

6、管道流PipedInputStream和PipedOutputStream
输入输出可以直接进行连接。
应该用于多线程,单线程易导致死锁。
在写之前,读是阻塞式方法。
开发的时候,参考API文档就可以了。

7、RandomAccessFile
随机访问文件(灰常强大),有些书上说,这个类可以用作断点续传。
主要是因为,这个类读取文件时,是可以指定开始读取位置的。
开发的时候,参考API文档就可以了。

8、数据流:DataOutputStream和DataInputStream
专门用于操作数据的流。
开发的时候,参考API文档就可以了。

9、数组操作对象:ByteArrayInputStream和ByteArrayOutputStream
没有访问资源,不需要关闭。
即使关闭以后,对象依然可以正常访问。
开发的时候,参考API文档就可以了。

10、转换流操作编码表
//定义文本转换输出流(向文件输出UTF-8编码的中文字符)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\utf.txt"),"UTF-8");
//写入信息
osw.write("你好");
//关闭流
osw.close();


11、JDK1.7之后,新try-catch对IO流的关闭
当你同时访问多个文件资源时,多个IO流的释放往往是一件让人头疼的事。

我们可以看一下以下的代码:

public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
fr  = new FileReader("D:\\ClassLoaderTest.java");
fw = new FileWriter("D:\\ClassLoaderTest1.java");
char[] cbuf = new char[1024];
int len = 0;
while((len=fr.read(cbuf)) > 0)
fw.write(cbuf, 0, len);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if(null!=fr) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=fw) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
代码的功能很简单,其实就是将一个文本文件拷贝到另外一个文本文件中。
但为了较为安全的释放IO流访问的资源。
我们花费了将近一半的篇幅,来写释放资源的代码。
看括号的层次,就挺让人觉得烦躁的。

所以,在JDK1.7中,我们可以用如下方法来实现:

public static void main(String[] args) {
try
(
FileReader fr = new FileReader("D:\\ClassLoaderTest.java");
FileWriter fw = new FileWriter("D:\\ClassLoaderTest1.java");
)
{
char[] cbuf = new char[1024];
int len = 0;
while((len=fr.read(cbuf)) > 0)
fw.write(cbuf, 0, len);
}
catch (IOException e)
{
e.printStackTrace();
}
}
显然,以上这段代码,相对于第一段代码而言,清晰很多。
两段代码的区别在于:
1、将资源的创建放到了try后面的小括号中。

2、省去了资源释放的代码。

在try中的代码运行结束后,不需要手动的close()资源。

JAVA会自动去释放这些资源。

这应该算是JDK1.7之后一个较好的改进吧。

------- android培训java培训、期待与您交流! ----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: