流(IO)
四个基本流:
InputStream(输入字节流)、OutputStream(输出字节流)、writer(输出字符流)、reader(输入字符流)-四个基本流都是抽象类不能实例化,固只能用其子类;
注意:流结束后一定要关流(close())和将引用设为null;以便被GC回收。
流的一般异常处理:
1. 流对象要外置定义内置初始化
2. 判断流对象是否初始化成功---判断流对象是否为空
3. 关流操作无论成功与否,都需要将流对象值为null
// 流对象需要外置定义内置初始化 FileWriter writer = null; try { writer = new FileWriter("E:\b.txt"); writer.write("bbb"); } catch (IOException e) { e.printStackTrace(); } finally { //需要判断流对象是否为空,以防对象初始化失败出现空指针异常 if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } finally { writer = null; } } }
字符流:
FileWriter(String name):传入文件路径,创建新文件。
// 需要准备一个流对象---布尔值表示是否向文件中追加内容 FileWriter writer = new FileWriter("E:\a.txt",true); // 利用write方法向文件中写入数据 // 数据不是直接写到文件中而是写到了缓冲区中 // 当缓冲区没有满的时候,数据不会写到文件中 // 程序一旦结束,数据死在了缓冲区中 writer.write("aaa "); // 冲刷缓冲区 // writer.flush(); // 关闭流 //流在关闭之前会自动冲刷一次缓冲区以防有数据死在缓冲区中 //流在关闭之后并没有被销毁,只是不能再次使用 writer.close(); System.out.println(writer); writer = null;
FileReader(String name):传入文件路径,读取文件
1 //创建一个输入流对象 2 FileReader reader = new FileReader("D:\a.txt"); 3 //定义一个变量来记录读取的数据 4 int len = -1; 5 while((len = raeder.read()) != -1){ 6 System.out.println((char)len); 7 } 8 9 //需要一个数组来作为盛放读出的数据容器 10 char[] char = new char[1024]; 11 //定义一个变量来记录读出的数据保存在数组的数 12 int len = -1; 13 //将数据读取到char数组中。读到末尾返回的是-1则表示读完了 14 while((len = rader.read(char))!=-1){ 15 //将char数组中的数据拿出来拼接成一个字符串并打印 16 System.out.println(new String(char,0,len)); 17 } 18 reader.close(); 19 reader = null;
两个缓冲流:BuffReader、BufferedWriter---->主要的作用提供缓冲区
BuffReader:从字符输入流中来获取数据;Reader对象来指名数据的具体来源.(需要传入字符流);
1 //BufferedReader需要一个字符输入流对象---字符输入流指名数据的具体来源,BufferedReader从流中来获取数据,然后提供一个缓冲区 2 BufferedReader br = new BufferedReader(new FileReader("D:\a.txt")); 3 4 //来定义一个变量来记录每一行的数据 5 String line = null; 6 7 //读取文件 8 while((line = br.readLine()) != null){ 9 System.out.println(line); 10 } 11 12 br.close();
BufferWriter:主要是提供了newLine这个方法。方便开发时换行在不同的平台实现相同的换行效果。只有BufferWriter这个对象才有newLine方法。
字节流: InputStream:输入字节流【如文件不存在时会自动创建,若文件存在则会被新创建的文件所覆盖】
|--FileInputStream(子类)
1 FileInputStream fis = new FileInputStream("D:\a.txt"); 2 int len = -1; 3 byte[] by = new byte[1024*1024]; 4 while((len = fis.raeder(by))!=-1){ //将数据读取到字节数组内。 5 System.out.println(by,0,len); 6 }
OutputStream:输出字节流【如文件不存在时会自动创建,若文件存在则会被新创建的文件所覆盖】
|--FileOutputStream(子类)
1 //准备了一个输出流来向文件中写入数据 2 FileOutputStream fos = new FileOutputStream("E:\c.txt"); 3 4 //创建一个Scanner对象 5 Scanner s = new Scanner(System.in); 6 String str = s.nextLine(); 7 s.close(); 8 9 //写出数据---字节流没有缓冲区 10 fos.write(str.getBytes()); 11 12 //关流 13 fos.close();
转换流:
OutputStreamWriter:将字节输出流转换成字符输出流。
1 //创建了一个流对象---没有指定编码的时候,采用的是系统平台码 2 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\d.txt"),"utf-8"); 3 4 //写出数据 5 osw.write("达内大数据~~~"); 6 7 //关流 8 osw.close();
InputStreamReader:将字节输入流转换成字符输入流
1 //创建一个输入流对象 2 InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\d.txt"), "utf-8"); 3 4 //创建一个缓冲流 5 BufferedReader br = new BufferedReader(isr); 6 7 //记录每行的数据 8 String line = null; 9 10 //读取数据 11 while((line = br.readLine()) != null){ 12 System.out.println(line); 13 } 14 15 //关流 16 br.close();
系统流:
System.out 标准输出流
System.in 标准输入流
System.err 标准错误流
打印流:
PrinteWriter:是一个输出流
1 // 创建打印流对象 2 PrintWriter pw = new PrintWriter("D:\a.txt"); 3 4 // 写出数据 5 // pw.write("aaa"); 6 7 // 打印数据 8 pw.print("aaaa"); 9 pw.println(1.234); 10 // 打印对象的时候,默认调用了这个对象的toString方法 11 pw.println(new A()); 12 13 pw.println("bbbb"); 14 15 // System.out.println(); 16 17 // 关流 18 pw.close();
合并流:
关键字:SequenceInputStream
1 //创建三个流对象指向三个文件 2 FileInputStream f1 = new FileInputStream("E:\a.txt"); 3 FileInputStream f2 = new FileInputStream("E:\b.txt"); 4 FileInputStream f3 = new FileInputStream("E:\c.txt"); 5 6 //创建 一个向量对象 7 //Vector是List的一个实现类,是最早期的列表,在List之前产生的 8 Vector<InputStream> vector = new Vector<InputStream>(); 9 10 //将流添加到集合中 11 vector.add(f1); 12 vector.add(f2); 13 vector.add(f3); 14 15 //利用集合产生枚举对象 16 Enumeration<InputStream> e = vector.elements(); 17 18 //创建合并流对象 19 SequenceInputStream sis = new SequenceInputStream(e); 20 21 //读取数据 22 BufferedReader br = new BufferedReader(new InputStreamReader(sis)); 23 24 //记录每一行的数据 25 String line = null; 26 27 //读取数据 28 while((line = br.readLine()) != null){ 29 System.out.println(line); 30 } 31 32 //关流 33 br.close();
序列化和反序列化:
ObjectOutputStream:是个输出流。----序列化
1 //实例化一个对象(对象中自己的基本信息) 2 Person p = new Person; 3 4 //创建一个序列化流 5 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\test.txt")); 6 7 //序列化对象;writerObject 写入的是一个对象。 8 oos.writerObject(p); 9 10 //关流 11 oos.close();
ObjectInputStream:是个输入流。 ---反序列化
1 //创建反序列化流 2 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\test.txt")); 3 4 //反序列化对象;从 ObjectInputStream 读取对象。 返回是个Object 5 Person person = (Person)ois.readObject; 6 7 //关流 8 ois.close(); 9 10 //测试;输出Person对象中需要的基本信息 11 System.ou.println(person.name+","+person.age);
Properties:
Properties本质上是一个映射,继承了Hashtable类。---可持久的映射。---将映射保存到 properties文件中。
Properties中键值对的类型都是String。
properties文件中不能直接存储中文,一旦输入中文会将中文转化成对应的编码
HashMap---默认的初始大小是16,加载因子是0.75f---扩容,扩容一倍---是一个异步式线程不安全的映射---允许一个键为null,允许值为null
Hashtable---默认的初始大小是11,加载因子是0.75f;每次不是一倍---是一个同步式线程安全的映射---不允许键值为空
ConcurrentHashMap---是一个异步式线程安全的映射
下面的代码是序列化Properties:
1 //创建properties对象 2 Properties prop = new Properties(); 3 4 //添加键值对---键值的类型只能是String类型 5 prop.put("name", "wade"); 6 prop.setProperty("age", "15"); 7 prop.setProperty("gender", "Male"); 8 9 //将prop对象序列化到硬盘上 10 //第一个参数需要的是一个流对象 11 //第二个参数需要一个字符串---注释 12 prop.store(new FileWriter("person.properties"), "This is a person .");
下面的代码是反序列化Properties:
1 //创建一个properties对象 2 Properties p = new Properties(); 3 4 //需要将对象反序列化回来 5 p.load(new FileInputStream("person.properties")); 6 7 //根据键来获取值 8 System.out.println(p.get("name")); 9 10 //给了一个默认值,如果这个键不存在或者没有对应的值,那么返回默认值;反之返回对应值 11 System.out.println(p.getProperty("hobby","打篮球!!!"));