概述:可以直接读写基本数据类型
数据输入流:DataInputStream 数据输出流:DataOutputStream
构造方法: DataInputStream(InputStream in) :使用指定的底层 InputStream 创建一个 DataInputStream DataOutputStream(OutputStream out) :创建一个新的数据输出流,将数据写入指定基础输出流
应用:
package org.org.westos.demo; import java.io.*; public class MyClass { public static void main(String[] args) throws IOException { //创建一个输出流,并自动创建文件 DataOutputStream out = new DataOutputStream(new FileOutputStream("a.txt")); //写基本数据类型 out.writeInt(100); out.writeBoolean(true); out.writeDouble(3.14); //创建一个输入流,并关联文件 DataInputStream in = new DataInputStream(new FileInputStream("a.txt")); //获取文件中的基本类型数据 //这里注意,获取顺序跟写入顺序类型必须一致 int i = in.readInt(); System.out.println(i); boolean b = in.readBoolean(); System.out.println(b); double v = in.readDouble(); System.out.println(v); out.close(); in.close(); } }读写基本数据类型是它的特有功能,当然,读写一个字节和读写字节数组也一样可以
概述:不操作文件,只操作内存中的数据
分类 (1)操作字节数组:ByteArrayOutputStream、ByteArrayInputStream,此流无需关闭 (2)操作字符数组:CharArrayWrite、CharArrayReader (3)操作字符串:StringWriter、StringReader
构造方法: (1)操作字节数组 ByteArrayOutputStream() :创建一个新的 byte 数组输出流 ByteArrayOutputStream(int size) :创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量(以字节为单位) ByteArrayInputStream(byte[] buf) :创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组 ByteArrayInputStream(byte[] buf, int offset, int length) :创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组
package org.org.westos.demo; import java.io.*; public class MyClass { public static void main(String[] args) throws IOException { //根据空参构造创建一个输出流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); //写入数据,参数要一个字节或一个字节数组,所以要调用getBytes方法 bos.write("你好".getBytes()); bos.write("世界".getBytes()); bos.write("hello".getBytes()); bos.write("java".getBytes()); //使用toByteArray方法取出这些数据 byte[] bytes = bos.toByteArray(); //创建一个输入流并将字节数组给它 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); //读取数据 //定义一个变量,记录每次读取的字节 int len = 0; //创建一个数组充当缓冲区 byte[] bytes1 = new byte[1024]; //创建一个文件,将读取到的数据放入文件中 FileOutputStream out = new FileOutputStream("b.txt"); while((len=bis.read(bytes1))!=-1){ out.write(bytes1,0,len); } out.close(); } }(2)操作字符数组 CharArrayWriter() :创建一个新的 CharArrayWriter CharArrayWriter(int initialSize) :创建一个具有指定初始大小的新 CharArrayWriter CharArrayReader(char[] buf) :根据指定的 char 数组创建一个 CharArrayReader CharArrayReader(char[] buf, int offset, int length) :根据指定的 char 数组创建一个 CharArrayReader
package org.org.westos.demo; import java.io.*; public class MyClass { public static void main(String[] args) throws IOException { //根据空参构造创建一个输出流 //底层维护的是字符数组 CharArrayWriter writer = new CharArrayWriter(); //写入数据 writer.write("aaa"); writer.write("bbb"); writer.write("ccc"); //将数据写入字符数组 char[] chars = writer.toCharArray(); //转换成字符串打印输出 String s = String.valueOf(chars); System.out.println(s); } }(3)操作字符串 StringWriter() :使用默认初始字符串缓冲区大小创建一个新字符串 writer StringWriter(int initialSize) :使用指定初始字符串缓冲区大小创建一个新字符串 writer StringReader(String s) :创建一个新字符串 reader
package org.org.westos.demo; import java.io.*; public class MyClass { public static void main(String[] args) throws IOException { //根据空参构造创建一个输出流 //底层维护的是StringBuffer StringWriter writer = new StringWriter(); writer.write("aaaaa"); writer.write("aaaaa"); writer.write("aaaaa"); writer.write("aaaaa"); String s = writer.toString(); System.out.println(s); } }后两种操作也可以使用输入流读取数据,跟操作字节数组是一样的,根据构造方法即可
概述:只能输出数据,不能读取数据
分类 字节打印流:PrintStream 字符打印流:PrintWriter
构造方法: (1)字节打印流: PrintStream(File file) :创建具有指定文件且不带自动行刷新的新打印流 PrintStream(OutputStream out) :创建新的打印流
package org.org.westos.demo; import java.io.*; public class MyClass { public static void main(String[] args) throws IOException { //封装文件 File file = new File("b.txt"); //创建字节打印流,输出数据进关联文件 PrintStream printStream = new PrintStream(file); printStream.println(100); printStream.println(200); printStream.println("aaa"); printStream.close(); //创建标准输出流,此流已打开并准备接受输出数据 // 通常,此流对应于显示器输出 PrintStream out = System.out; out.println(100); out.println(100); out.println(100); out.close(); } }
(2)字符打印流: PrintWriter(File file) :使用指定文件创建不具有自动行刷新的新 PrintWriter
package org.org.westos.demo; import java.io.*; public class MyClass { public static void main(String[] args) throws IOException { PrintWriter printWriter = new PrintWriter(new FileOutputStream("c.txt")); printWriter.println("abc"); printWriter.println("def"); printWriter.println("ghj"); //字符流必须刷新 printWriter.flush(); printWriter.close(); //根据构造方法启动自动刷新 //启用了自动刷新,只有在调用 println、printf 或 format 的其中一个方法时才执行 PrintWriter printWriter1 = new PrintWriter(new FileOutputStream("d.txt"),true); printWriter1.println("111"); printWriter1.println("222"); printWriter1.println("33"); //启动了自动刷新,无需手动刷新 printWriter1.close(); } }如果想多次输入,用while循环就行,然后给个条件break即可
随机访问流有指针,所以适合用于断点操作
概述: 序列化流就是把对象通过流的方式存储到文件中,此对象需重写Serializable接口 反序列化就是把文件中存储的对象以流的方式还原成对象
序列化:ObjectOutputStream 反序列化:ObjectInputStream
应用
package org.org.westos.demo; import java.io.Serializable; //一个类对象,要想序列化成功,就要实现Serializable这个标记接口 //标记接口就是该接口内部没有任何方法 public class Student implements Serializable { //这个类,实现了Serializable接口最后在生成一个serialVersionUID,建议自己给出 private static final long serialVersionUID=42L; private String name; //要想某个字段不被序列化,则用transient修饰 private transient int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } import java.io.*; class MyTest3 { public static void main(String[] args) throws IOException, ClassNotFoundException { write(); read(); } //编写方法,将对象保存到文件中 private static void write() throws IOException { Student student = new Student(); student.setName("张三"); student.setAge(23); ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream("a.txt")); objOut.writeObject(student); objOut.close(); } //编写方法,将文件中的对象读取出来 private static void read() throws IOException, ClassNotFoundException { ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("a.txt")); Object o = objIn.readObject(); //向下转型,获取对象 Student student = (Student) o; String name = student.getName(); int age = student.getAge(); System.out.println(name+"-"+age); } }年龄字段被序列化的情况 年龄字段被transient修饰,不被序列化的情况 另外,序列化流和反序列化流还用于深克隆
概述: 压缩流就是对文件或者文件夹的压缩 解压流就是把压缩文件还原成文件或文件夹
压缩流:zipOutputStream 解压流:ZipInputStream
方法 void putNextEntry(ZipEntry e):开始写入新的zip文件条目并将流定位到条目数据的开始处 ZipEntry getNextEntry():读取下一个zip文件条目并将流定位到该条目数据的开始处 String getName():返回条目名称 boolean isDirectory():如果为目录条目,则返回 true
应用(多级文件夹的压缩以及解压)
//多级文件夹的压缩 package org.org.westos.demo; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class MyClass2 { public static void main(String[] args) throws IOException { //封装多级文件夹 File srcFile = new File("D:\\java"); //封装目标压缩文件 ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream("D:\\java.zip")); //创建高效流包装压缩流 BufferedOutputStream bos = new BufferedOutputStream(zipOut); //调用压缩方法 yasuo(srcFile,srcFile.getName(),zipOut,bos); //释放资源 zipOut.close(); bos.close(); } private static void yasuo(File srcFile, String name, ZipOutputStream zipOut, BufferedOutputStream bos) throws IOException { //判断srcFile是文件还是文件夹 if(srcFile.isFile()){ //如果是文件,直接压缩 //封装压缩条目 zipOut.putNextEntry(new ZipEntry(name)); //创建高效输入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); //读写 int len = 0; byte[] bytes = new byte[1024]; while((len=bis.read())!=-1){ bos.write(bytes,0,len); bos.flush(); } bis.close(); }else{ //如果是文件夹,递归 File[] files = srcFile.listFiles(); for (File file : files) { //传路径的时候,最好不要带盘符号,把盘符号压缩进压缩包里,没有意义 yasuo(file,name+"\\"+file.getName(),zipOut,bos); } } } } //多级文件夹的解压 package org.org.westos.demo; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; //解压多级文件夹 public class MyTest { public static void main(String[] args) throws IOException { //封装压缩文件夹 ZipInputStream zipIn = new ZipInputStream(new FileInputStream("D:\\java.zip")); //创建高效流包装解压流 BufferedInputStream bis = new BufferedInputStream(zipIn); //获取下一个压缩条目 ZipEntry nextEntry=null; File file = null; //循环获取每一个压缩条目 while((nextEntry=zipIn.getNextEntry())!=null&&!nextEntry.isDirectory()){ //把压缩条目封装成文件 file = new File("D:\\", nextEntry.getName()); //如果一个压缩条目它的父目录不存在,就创建 if(!file.getParentFile().exists()){ new File(file.getParent()).mkdirs(); } //读写 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); int len = 0; byte[] bytes = new byte[1024]; while((len=bis.read())!=-1){ bos.write(bytes,0,len); bos.flush(); } bos.close(); } bis.close(); zipIn.close(); } }学会了多级文件夹的操作,对于文件和单级文件夹的操作也就会了
以上就是所学习的一些其他流 在学习每一个流时,还是要借助API文档,以获得更好的了解和使用 每个流针对不同的需求都会有一定程度上的方便,这也就是我们需要学习其他流的目的 虽然字节流可以完成任意类型的文件操作,但有时会不方便,实现会比较复杂,这时,这些其他流就派上用场了
