Java IO流技术
Java IO基本总结
Java的IO技术就是用来处理数据的。比如从文件中读取数据,或者将数据写到文件中。在网络中传输的都是二进制,即字节码,我们需要在传输之前,将我们程序中的数据转换成字节码才能进行传输。Java的IO包内就提供了完成这些工作的工具类。
总的来说:当需要以二进制的形式来处理文件时,即不涉及文本内容的操作时,我们可以选择InputStream和OutputStream来完成我们的工作。当需要完成处理字符串相关的工作时,就需要使用Reader和Writer来完成工作。当需要向文件或其它源写入或传输时,应该使用OutputStream和Writer,当需要从文件或其它源读取内容时,应该使用Reader和InputStream。
另外,BufferedReader和BufferedWriter,以及BufferedInputStream和BufferedOutputStream是利用了缓冲技术的IO操作,主要是可以提高文件读写的效率。
Java IO基本使用
以二进制读取文件
public static void test04(String filePath) { // 二进制形式读取文件内容 File f = new File(filePath); InputStream is = null; try { is = new FileInputStream(f); // 使用缓冲 BufferedInputStream bis = new BufferedInputStream(is); byte[] buffer = new byte[1024]; // 每次读1024 int len = -1; while ((len = bis.read(buffer)) != -1) { /** * 每次读取到的内容被保存到 buffer 字节数组 len返回读取到的字节的长度,当返回-1时表示:文件已经读取完毕 */ System.out.println(Arrays.toString(buffer)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(is!=null) { try { // 释放资源 is.close(); } catch (IOException e) { e.printStackTrace(); } } } }
二进制读取并保存
通过这种方法,可以实现一个简单的文件复制。
public static void test05(String src, String desc) { File f1 = new File(src); File f2 = new File(desc); byte[] buffer = new byte[1024]; int len = -1; /** * 使用 try-with-resource 将需要读写的文件放到 try 中进行声明,就不需要手动释放资源 * try 中声明的对象只能是 需要进行读写的对象,其它的不能放到这里进行声明 */ try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2)); ) { while ((len = bis.read(buffer)) != -1) { bos.write(buffer, 0, len); bos.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
处理文本文件
在处理文本文件时,应该清楚的了解自己应该使用什么字符集来处理文件。使用错误的字符集会导致乱码。
public static void test06(String filePath) { File f = new File(filePath); try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), "utf-8"));) { /** * 在 InputStreamReader实例化时,传入指定字符集 InputStreamReader是一个包装类,通过它,可以将字节转化为字符 * 很明显,它需要一个 InputStream 的子类。 */ String line = null; while((line=br.readLine())!=null) { System.out.println(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } }
将Java中的数据类型序列化
当需要对Java中的基本数据类型进行序列化时,就需要使用DateOutputStream和DataInputStream来进行操作了。
这次,我们把Java中的一些基本数据类型保存在 ByteArrayOutputStream中 进行保存,并 通过 ByteArrayInputStream 来读取。
public static void test07(Object... objects) { // 实现不定量参数的传递 ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); // 向ByteArrayOutputStream中写入数据 try { dos.writeLong((Long)objects[0]); /** * 将 ByteArrayOutputStream 中的内容 放到 ByteArrayInputStream 中进行读取 * ByteArrayInputStream 需要一个 字节数组 */ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); // 需要一个 DataInputStream 来 反序列化 DataInputStream dis = new DataInputStream(bais); /** * 开始读操作,应该按照一一对应的原则来进行读取 */ Long l = (Long)dis.readLong(); System.out.println(l); } catch (IOException e) { e.printStackTrace(); } }
将自定义的对象序列化和反序列化
这次将Java中自定义的对象 进行实例化,并保存到文件中,然后读取。要想实现自定义对象的序列化,必须实现 Serializable接口。
需要用到 ObjectOutputStream和ObjectInputStream。
// 类的定义 class School implements Serializable { private static final long serialVersionUID = 7278116284818149932L; private String name; private String area; private transient String secret; // 不会被序列化的字段 public String toString() { return this.name + "<" + this.area + ">"; } public School(String name, String area, String secret) { super(); this.name = name; this.area = area; this.secret = secret; } public School() { // 空构造器 } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } } // 类的实例化 及 保存和 读取 public static void test08(String filePath) { /** * 将实例化对象写入到 filePath指定的文件中 读取 desc中的内容,并打印到终端 */ School s1 = new School("燕山大学", "秦皇岛", "不会被序列化的字符串"); School s2 = new School("蠡县中学", "保定", "这是一个秘密信息"); File f = new File(filePath); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));) { /** * 实例化对象序列化 */ oos.writeObject(s1); oos.writeObject(s2); oos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } /** * 从文件中读取二进制文件,并反序列化 */ try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));) { School s3 = (School)ois.readObject(); School s4 = (School)ois.readObject(); System.out.println(s3); System.out.println(s4); /** * 尝试获取未通过序列化的属性 * 未序列化的属性为null或0 */ System.out.println("现获取未序列化的属性"); System.out.println(s3.getSecret()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
说明
本博客所有的文章都会随着本人的不断积累,而不断的更新。转载请注明出处。
原文地址:https://www.cnblogs.com/dbc0801/p/12066537.html