按照流向可以分为输入流和输出流;按照操作单元来分的话,可以分为字节流和字符流;按照流的角色来划分的话,可以划分为节点流和处理流;
直接从数据源或者目的地读写数据;
节点流的作用在于将一个已存在的文件,加载到程序中,从而进行操作,或者写出流到文件中;
// 1、建立一个流对象,将一个已经存在的文件加载进流 FileReader fr = new FileReader("hello.txt"); // 2、创建一个临时存放数据的数组 char [] buffer = new char[1024]; // 3、用数组盛放入进来的文件流 fr.read(buffer); // 4、关闭资源 fr.close();
代码:
FileReader fr = null; try{ // 这里需要注意的是,当在 main 方法中时,那么我们的当前路径就是当前的工程路径; // 如果是单元测试方法,那么当前路径就是相对于我们当前 model 的; fr = new FileReader("C:\\hello.txt"); char [] buffer = new char[1024]; int len; while ((len = fr.read()) != -1){ System.out.println(new String(buffer,0,len)); }catch(IOException e){ System.out.println("捕获异常:" + e.getMessage()); }finally{ if(fr != null){ try{ fr.close(); }catch(IOException e) System.out.println("捕获异常:" + e.getMessage()); } } }
定义文件路径时,可以使用"/"或者"\"。
在写入一个文件时,使用构造器 FileOutputStream(file),则会覆盖写文件;使用构造器 FileOutputStream(file,true),则会追加文件内容。
// 1、创建流对象,建立数据存放文件 FileWriter fw = new FileWriter("hello.txt"); // 2、调用流对象的写入方法,将文件写入流 fw.write("hello java,hello world"); // 3、关闭资源文件,并将流中的数据清空到文件中 // fw.flus(); fw.close();
代码:
FileWriter fw = null; try{ fw = new FileWriter("hello.txt"); fw.write("hello world"); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(fw != null){ fw.close(); } }catch(IOException e){ System.out.println(e.getMessage()); } }
不能直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能;
缓冲流要套接在相应的节点流之上,根据数据操作单位可以把缓冲流分为 BufferedInputStream
和 BufferedOutputStream
、BufferedReader
和BufferedWriter
。为了提高读写的速度,在使用这些流类的时候,会创建一个内部缓冲区数组,默认使用 8 k大小的缓冲区。缓冲流要套接在相应的节点流上。
图解:
代码:
BufferedReader br = null; bufferedWriter bw = null; try{ br = new BufferedReader(new FileReader("D:\\hello.txt")); bw = new BufferedWriter(new FileWriter("D:\\hi.txt")); String str = null; while((str = br.readLine()) != null){ bw.write(str); bw.newLine(); // 写入分隔符 } bw.flush(); // 刷新缓存区,将缓存区的内容一次性全部写入文件 }catch(IOException e){ System.out.println(e.getMessage()); }finally{ // 关闭资源 在这里关掉最外层的即可 try{ if(br != null){ br.close(); } }catch(IOException e){ System.out.println(e.getMessage()); } try{ if(bw != null){ bw.close(); } }catch(IOexception e){ System.out.println(e.getMessage()); } }
转换流,提供了在字节流和字符流之间的转换方法;
字节流中的数据都是字符时,转成字符流操作更高效,我们会经常使用转换流处理文件乱码问题。实现编码和解码功能;
// 构造器 // 输入 public InputStreamReader(InputStream is); public InputStreamReader(InputStream is,"gbk"); // 指定字符集 // 输出 public OutputStreamWirter(OutputStream os); public OutputStreamWirter(OutputStream os,"utf-8"); // 指定字符集
代码
// 文件输入输出流 FileInputStream fis = new FileInputStream("hello.txt"); FileOutputStream fos = new FileOutputStream("helloCopy.txt"); // 处理流-转换流 InputStreamReader isr = new InputStreamReader(fis,"gbk"); OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8"); // 处理流-缓冲流 BufferedReader br = new BufferedReader(isr); BufferedWriter bw = new BufferedWriter(osw); String str = null; while((str = br.readLine()) != null){ bw.write(str); bw.newLine(); bw.flush(); } // 关闭流操作 try{ if(br != null){ br.close(); } }catch(IOException e){ System.out.println(r.getMessage()); } try{ if(bw != null){ bw.close(); } }catch(IOException e){ System.out.println(e.getMessage()); }
System.in 和 System.out 分别代表了系统标准的输入和输出设备,System.in 的类型是 InputStream;System.out 的类型是 PrintStream,是OutputStream 的子类
ObjectInputStream 和 ObjectOutputStream ,分别用于反序列化读取和序列化保存基本数据类型或者对象。但是不能序列化 static 或 transient 修饰的成员变量
序列化:可以将任何实现了 Serializable 接口的对象转化为字节数据,使其在保存和传输时可被还原。(实现对象平台无关性)
序列化:写出
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.txt")); Person person = new Person("zhangsan",15); oos.write(p); oss.flush(); oss.close();
反序列化:读入
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.txt")); Person person = (Person) ois.readObject(); String str = person.toString(); System.out.println(str); ois.close();
InputStream 和 Reader 是所有输入流的基类
InputStream 的经典实现是 FileInputStream ,存在的方法有 int read( )
以及他的重载形式int read(byte [ ] b)
、int read(byte [ ] b,int off,int len )
等,用来读取字节(非文本文件);
Reader 的经典实现就是 FileReader,存在方法有int read( )
、int read(char [ ] c)
、int read( char [ ] c,int off,int len )
用来读取字符;
OutputStream 和 Writer 是相对应的字节输出流和字符输出流
先 flush( ) 刷新后,再关闭流;flush 操作会刷新输出流并强制写出所有缓冲的输出字节或字符
FileOutputStream,用于写出字节文件(非文本类型文件);
FileWriter,用于写出字符类型的文件(文本文件);