16.IO流
字符流
package com.atguigu.java1; /* 一、流的分类 按照操作数据单位: 字节流(8bit)、 字符流(16bit) 按照流向: 输入流、输出流 流的角色: 节点流、 处理流 二、流的体系结构 抽象基类 节点流(或文件流) 缓冲流(处理流的一种) InputStream FileInputStream BufferedInputStream OutputStream FileOutputStream BufferedOutputStream Reader FileReader BufferedReader Writer FileWriter bufferedWriter */ import org.junit.Test; import java.io.*; public class FileReadWriteTest { public static void main(String[] args) { File file = new File("Hello.txt");//相对于工程下 System.out.println(file.getAbsolutePath());//D:\IntelliJ IDEA 2020\workspace\JavaSenior\Hello.txt } /* 将Day06下的hello.txt文件内容读入到程序中,并输出到控制台 1.read():返回读入的一个字符,如果达到文件末尾,返回-1 2.异常的处理,为了保证流资源一定可以执行关闭操作,一定要使用try-catch-finally处理 3.读入的文件,一定要存在,否则会报FileNotFountException */ @Test public void test1() { FileReader fr = null; try { //1.实例化File类的对象,指明要操作的文件 File file = new File("Hello.txt");//相较于当前module //2.提供具体的流 fr = new FileReader(file); //如果实例化出异常,fr未实例化,则fr为空,在fr.close操作会出现空指针异常 //3.数据的读入过程 //方式一: // int data = fr.read(); // while(data != -1){ // System.out.print((char) data);//h e l l o W o r d // data = fr.read(); // } int data1; while((data1 = fr.read()) != -1){ System.out.println((char)data1); } } catch (IOException e) { e.printStackTrace(); } finally { //4.流的关闭操作 if (fr != null){ try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* read():重载方法 read(char[] cbuf):返回每次读入cbuf数组中的字符个数.如果达到文件末尾返回-1 */ @Test public void test2() { FileReader fr = null; try { File file = new File("Hello.txt"); fr = new FileReader(file); char[] cbuf = new char[5]; int len; while ((len = fr.read(cbuf))!=-1){ //错误写法 第二次读取world存放在cbf中,在第三次读取123时,时123覆盖数组中的wor // for (int i = 0;i<cbuf.length;i++){ // System.out.print(cbuf[i]);//helloWorld123ld // } //正确的写法 // for (int i =0 ; i< len;i++){ // System.out.println(); // } //错误写法 // String str = new String(cbuf); // System.out.println(str);//hello world 123ld String str = new String(cbuf,0,len); System.out.println(str);//hello world 123 } } catch (IOException e) { e.printStackTrace(); } finally { if(fr != null){ try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 从内存中写出数据到硬盘的文件里 说明:1.输出操作 对应的file文件可以不存在,并不会报异常 2.File对应的硬盘中的文件如果不存在,可以在输出时,自动创建此文件, File对应的硬盘中的文件如果存在,①file使用的构造器是FileWriter(file,false)或者FileWriter(file),对原有文件的覆盖 ②file使用的构造器是FileWriter(file,true):则不会对原有文件覆盖,而是在原有文件基础上追加新内容 */ @Test public void test3() { FileWriter fw = null; try { //1.提供File类的对象,指明写到的文件 File file = new File("hello1.txt"); //2.提供FileWriter的对象,用于数据的写出 fw = new FileWriter(file,false); //3.写出的具体的操作 fw.write("I have a dream\n"); fw.write("you need to have a dream"); } catch (IOException e) { e.printStackTrace(); } finally { try { if(fw != null){ fw.close(); } } catch (IOException e) { e.printStackTrace(); } } //4.流关闭的操作 } /* 文件的复制:将读入的内容再写出去 */ @Test public void test4() { FileReader fr = null; FileWriter fw = null; try { //1.创建file的对象,指明读入和写出的文件 File srcFile = new File("hello.txt"); File destFile = new File("hello2.txt"); //2.创建输入流和输出流的对象 fr = new FileReader(srcFile); fw = new FileWriter(destFile); //3.数据的读入和写出操作 char[] cbuf = new char[5]; int len;//记录每次读入cbuf数组中的字符个数 while((len = fr.read(cbuf))!=-1){ //每次写出len个字符 fw.write(cbuf,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { //4.关闭流操作 try { fw.close(); } catch (IOException e) { e.printStackTrace(); } try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
字节流
package com.atguigu.java1; import org.junit.Test; import java.io.*; /* 测试FileInputStream 和 FileOutputStream的使用 1.对于文本文件(.txt,.java,.c,.cpp)使用字符流处理, 对于非文本文件(.jpg,.mp3,.avi,.doc,.ppt…)需要使用字节流处理 */ public class FileInputOutput { @Test public void test1() { FileInputStream fis = null; try { File file = new File("hello1.txt"); fis = new FileInputStream(file); byte[] buffer= new byte[5]; int len; while((len= fis.read(buffer))!=-1){ //方式一 // for(int i = 0;i<len ;i++){ // System.out.print(buffer[i]);//输出字符的字节数 // } //方式二: String str = new String(buffer,0,len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if(fis !=null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void test2() { FileInputStream fis = null; FileOutputStream fos = null; try { File scrFile = new File("timg-9.jpg"); File descFile = new File("timg.jpg"); fis = new FileInputStream(scrFile); fos = new FileOutputStream(descFile); byte[] buffer = new byte[5]; int len; while((len = fis.read(buffer))!=-1){ fos.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fis !=null){ fis.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fis !=null){ fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
缓冲流
package com.atguigu.java1; import org.junit.Test; import java.io.*; /* 处理流之一 :缓冲流 1.缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BudderedWriter 2.作用:提高流的读取、写入的速度 原因:内部提供了缓冲区 3.处理流就是套接在已有的流的基础上 */ public class BufferTest { @Test public void test(){ BufferedInputStream bis = null; BufferedOutputStream bos = null; try { //1.造文件 File scrFile = new File("timg.jpg"); File destFile = new File("timg3.jpg"); //2.1 造节点流 FileInputStream fis = new FileInputStream(scrFile); FileOutputStream fos = new FileOutputStream(destFile); //2.2造缓冲流 bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); //3.读取和写入的过程 byte[] buffer = new byte[10]; int len ; while ((len = bis.read(buffer))!=-1){ bos.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { //4.关闭流:要求 :先关闭外层的流 再管里面的流,在关闭外层的流时,内层的流也会自动关闭,则内层流的关闭可省略 if(bis != null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if(bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
其他流
package com.atguigu.java1; import org.junit.Test; import java.io.*; /* 处理流二:转换流的使用 1.转换流: 属于字符流 InputStreamReader:将一个字节的输入流转换成字符的输入流 OutputStreamWriter:将一个字符的输入流转换为字节的输出流 2.作用:提供字节流与字符流之间的转换 */ public class InputStreamReaderTest { @Test public void test1(){ InputStreamReader ips = null;//参数2 :指明字符集,取决于文件保存时的字符集 try { FileInputStream fis = new FileInputStream("Hello.txt"); ips = new InputStreamReader(fis,"UTF-8"); char[] cbuf = new char[1024]; int len; while((len = ips.read(cbuf))!=-1){ String s = new String(cbuf, 0,len); System.out.print(s); } } catch (IOException e) { e.printStackTrace(); } finally { try { ips.close(); } catch (IOException e) { e.printStackTrace(); } } } /* 对象流: ObjectInputStream 、ObjectOutputStream 作用:用于存储和读取基本数据类型数据或对象 序列化过程:将内存中的Java对象保存到磁盘中,或通过网络传输出去 使用ObjectOutputStream实现 反序列化:将磁盘文件中的对象还原为内存中的一个Java对象 自定义 序列化,序列化要求: 1.需要实现接口:Serializable 2.需要一个全局常量定义(序列版本号) public static final long serialVersionUID 3.除了当前类需要实现Serializable接口之外,还要保证其内部属性也是可序列化的(默认基本数据类型可序列化) 4.对象序列化机制:允许把内存中的Java对象转化成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络 将二进制流传输到另一个网络节点。当其他程序获取了二进制流,就可以恢复成原来的Java对象 补充:ObjectOutputStream和ObjectInputStream 不能序列化Static和transient修饰的成员变量 */ @Test public void test2(){ ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream("object.dat")); oos.writeObject(new String("我爱北京天安门")); oos.flush();//刷新操作 } catch (IOException e) { e.printStackTrace(); } finally { if (oos!=null){ try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void test3(){ ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream("object.dat")); Object o = ois.readObject(); String s = (String) o; } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } }
虽不能至,心向往之