java IO流详解(下)
来源:互联网 发布:淘宝登陆异常 编辑:程序博客网 时间:2024/05/16 10:50
java IO流(上)
接着上一篇文章的内容,我们在说完了InputStream、OutputStream和Reader、Writer之后,来看一些有趣的类,最后我们来看一些具体应用的实例,去体会在实际项目中怎么组织这些类来让它们发挥作用。
(一)ZIP文档,ZipInputStream类
ZIP文档以压缩格式存储一个或多个文件,每个ZIP文档都有一个头,包含诸如每个文件名字和所使用的压缩方法等信息。在java中,我们通常使用ZipInputStream来读入ZIP文档。
在ZipInputStream对象中我们可能有一个或多个项(文件),你可能需要浏览文档中每个单独的项,所以java使用叫做ZipEntry的类来表示在ZIP中的一个个项。下面我们通过一个略长的例子来学习一下操作ZIP的所有方法和它们的用法。
package Stream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.PrintWriter;import java.util.Scanner;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;import java.util.zip.ZipOutputStream;/** * * @author QuinnNorris * * 使用java中的ZipInputStream和ZipOutputStream类操作ZIP文件 */public class ZIPStream { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("根目录是:" + System.getProperty("user.dir")); String fileName = "example.zip"; try (FileOutputStream fos = new FileOutputStream(fileName); ZipOutputStream zos = new ZipOutputStream(fos);) { for (int i = 0; i < 10; i++) { zos.putNextEntry(new ZipEntry("No." + i + ".txt")); // zos.write(("这是第" + i + "个txt文件").getBytes()); PrintWriter pw = new PrintWriter(zos); pw.print("这是第" + i + "个txt文件"); pw.flush(); zos.closeEntry(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block System.err.println("没有在根目录:" + System.getProperty("user.dir") + "下找到:" + fileName); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block System.err.println("将文件加入压缩包时发生未知错误。"); e.printStackTrace(); } try (FileInputStream fis = new FileInputStream(fileName); ZipInputStream zis = new ZipInputStream(fis);) { while (zis.getNextEntry() != null) { /* * byte[] b = new byte[1024]; zis.read(b); * System.out.println(new String(b)); */ Scanner sn = new Scanner(zis); if (sn.hasNextLine()) System.out.println(sn.nextLine()); zis.closeEntry(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
- 在一开始,我们通过System.getProperty(“user.dir”)先输出这个.java文件所在的位置,为我们之后的工作带来方便。
- 之后我们使用了带资源的try块(jdk1.7后可用),带资源的try块会为你自动调用close方法,省去了很多不必要的麻烦。
- 通过FileOutputStream与ZipOutputStream的套用,我们构建出了可以进行操作的输出流。
- 我们打算在这个zip文件中写入10个txt文件,for循环做标记。
- 调用putNextEntry方法,这个方法将参数中的ZipEntry对象作为一个新的条目加入ZIP文件中。
- ZipEntry对象的构造器传入String作为这个条目的名字,不要忘记后缀。
- 被注释掉的write方法是ZipOutputStream自带的写出方法,参数是byte[],如果要使用write一般都需要类型转换。
- 我们不使用原生的write方法,创建PrintWriter对象,使用print方法写入内容,调用flush方法将内容填充进去。
- 调用closeEntry方法表示这个条目已经操作结束。
- 期间会出现两个异常,这里我们选择catch来捕获,如果你想throws也没有问题。
- 下面的try块同样带资源, 根据需要,我们将文件和zip关联起来,使用FileInputStream,ZipInputStream这两个类。
- 调用getNextEntry方法,如果需要操作ZipEntry对象,为它赋个名字,这里我们不需要。
- 被注释的方法是原生read方法。
- 我们通过Scanner类来获取zis对象中的内容,将每行输出到控制台。
- 调用closeEntry方法走向下一个条目。
通过以上的步骤完成了创建zip文件和在控制台显示其中每个txt文件的内容。
(二)序列化对象流、ObjectOutputStream类
当你要存储数据时,使用固定长度的数组或者是集合类库中的列表是个不错的选择。但是如果你想要同时存储不同类型的数据呢?或许可以使用类似Object[]的数组来存储,但是这里要强势推荐一个对象序列化的通用机制来存放任何对象。我们通过这个方法将任何对象写出到流中,并在之后将其读回。而且这种序列化的方法有很多优点,最著名的优点就是通过序列化我们可以得到一个对象的clone,如果你在很多项目中都见过这个接口——Serializable。说明对象克隆使用的正是这种方法。
package Stream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/** * * @author QuinnNorris * * 序列化对象流会深拷贝复制对象 */public class ObjectStream { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String fileName = "example.txt"; try (FileOutputStream fos = new FileOutputStream(fileName); ObjectOutputStream oos = new ObjectOutputStream(fos); FileInputStream fis = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(fis)) { Student s1 = new Student(19, "XiaoZhang", null); Student s2 = new Student(20, "XiaoWang", s1); oos.writeObject(s2); Student getS2 = (Student) ois.readObject(); getS2.getFriend().setAge(5); // 将getS2的Student类型的friend属性的age值改为5. if (19 == s2.getFriend().getAge()) // 如果序列化不是深拷贝,那么getS2和s2指向的应该是同一个s1,这个if判断不会正确 System.out.println("序列化是深拷贝"); // 结果确实输出了:“序列化是深拷贝”,证明getS2和s2只想的对象已经不同,经过了深拷贝 } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
(三)IO流典型使用方式
这一段主要来自于thinking in java,但我们采用了try-catch方法,原书中为了方便直接使用throws来回避异常的问题,主要是各种常用的IO流使用手段。
1.缓冲输入文件
如果想打开一个文件用于字符输入,可以使用String或File对象作为文件名。为了提高速度,我们想要为这个文件进行缓冲,我们将产生的引用传递给BufferedReader构造器。通过这个类的readLine()方法,这就是我们最终对象和进行读取的接口。
package Stream;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;/** * * @author QuinnNorris * * 缓冲输入文件 */public class Stream1 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try (FileReader fir = new FileReader("example.txt"); // 直接接受一个File文件或String,和FileInputStream用法一样。 BufferedReader br = new BufferedReader(fir) // 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 // 构造器接受一个Reader对象,类似包装器 ) { String nextLine = null; while ((nextLine = br.readLine()) != null) { System.out.println(nextLine); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
2.基本的文件输出
FileWriter对象可以向文件写入数据。首先创建一个与指定文件连接的FileWriter。实际上,我们会通过用BufferedWriter将其包装起来用以缓冲输出。为了提供格式化的方法我们还可以使用PrintWriter方法。
package Stream;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;/** * * @author QuinnNorris * * 基本文件输出 */public class Stream2 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try (FileWriter fw = new FileWriter(new File("example.txt")); BufferedWriter bw = new BufferedWriter(fw); PrintWriter pw = new PrintWriter(bw)) { for (int i = 0; i < 10; i++) pw.print("这是第" + i + "行文字。" + System.getProperty("line.separator")); pw.flush(); // 在当前目录下多出个txt文件,有十行内容。 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
3.存储和恢复数据
如果我们使用DataOutputStream写入数据,java保证我们可以使用DataInputStream准确的读取数据——无论读和写数据的平台多么不同,这一点是非常有价值的。
package Stream;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;/** * * @author QuinnNorris * * 存储和恢复数据 */public class Stream3 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String fileName = "example.txt"; try (FileOutputStream fos = new FileOutputStream(fileName); BufferedOutputStream bos = new BufferedOutputStream(fos); DataOutputStream dos = new DataOutputStream(bos);) { dos.writeDouble(3.14); dos.writeUTF("圆周率"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try (FileInputStream fis = new FileInputStream(fileName); BufferedInputStream bis = new BufferedInputStream(fis); DataInputStream dis = new DataInputStream(bis)) { System.out.println(dis.readDouble()); System.out.println(dis.readUTF()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
- java IO流详解(下)
- java中的IO详解(下)
- java中的IO详解(下)
- Java 文件 IO 详解(下)
- java io (java输入输出流)详解
- JAVA IO流详解
- Java IO流详解
- JAVA IO流 详解
- Java IO流详解
- Java IO流详解
- Java IO流详解
- JAVA IO流详解
- Java IO流详解
- java io流详解
- JAVA IO流详解
- Java IO流详解
- java IO流详解
- java io流详解
- 用shell脚本监控进程是否存在 不存在则启动的实例
- Erlang 保护式
- ATS来了,网页HTTP访问怎么办?
- ios 属性readwrite,readonly,assign,retain,copy,nonatomic
- Java5新特性之静态导入、可变参数、增强for循环、自动拆装箱
- java IO流详解(下)
- Android广告图片轮播控件
- 使用SimpleAdapter创建ListView
- Executor框架
- 剑指offer--替换空格
- PyCharm 重构(refactor)快捷键
- shell中$0,$?,$!等的特殊用法
- jQuery选择器之id选择器
- 第一章:开篇