
本文共 12239 字,大约阅读时间需要 40 分钟。
一.缓冲流
作用:主要是为了增强基础流的功能而存在的,提高了流的工作效率【读写效率】
注意:如果使用记事本创建的文件,文件是utf-8或者unicode编码,文件的前面有一个BOM(Byte Order Mark)头,BOM作用指定文件使用的编码类型。GBK编码没有添加bom头。
utf-8:EF BB BF unicode 小端: FF FE 66 00 unicode 大端 :FE FF 00 661.1 BufferedInputStream类
字节输入缓冲流, BufferedInputStream本身不具备读写文件的能力,所以需要借助FileInputStream来读取文件的数据。
BufferedInputStream 缓冲输入字节流,缓冲输入字节流的出现主要是为了提高读取文件数据的效率。 其实BufferedInputStream类内部只不过维护了一个8kb的字节数组而已。 注意:凡是缓冲流都不具备读写文件的能力。代码案例:
package BufferedStream;import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.IOException;public class BufferedInputStreamTest { public static void main(String[] args) throws IOException { FileInputStream fis=new FileInputStream("aaa.txt"); BufferedInputStream bis=new BufferedInputStream(fis); //可以一步到位的写: BufferedInputStream bis=new BufferedInputStream(new FileInputStream("aaa.txt"));/* //没有使用缓冲区的 byte[] arr = new byte[1024]; int len = 0; while((len = input.read(arr)) != -1) { String string = new String(arr, 0, len); } */ 使用缓冲区读取 byte[] arr=new byte[1024]; int len=-1; while ((len=bis.read(arr))!=-1){ String string=new String(arr,0,len); System.out.print(string); } bis.close(); }}
1.2 BufferedOutputStream类
使用BufferedOutputStream输出信息和往OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。
代码案例:
package BufferedStream;import java.io.BufferedOutputStream;import java.io.FileOutputStream;import java.io.IOException;public class BufferedOutputStreamTest { public static void main(String[] args) throws IOException { FileOutputStream fos=new FileOutputStream("good.txt"); BufferedOutputStream bos=new BufferedOutputStream(fos); for (int i = 0; i <10 ; i++) { bos.write("好好学习天天向上".getBytes()); bos.flush(); } bos.close(); }}
1.3BufferedReader类
BufferedReader由Reader类扩展而来,提供通用的缓冲方式文本读取而且提供了很实用的readLine,读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
BufferedReader和BufferedWriter为默认带有缓冲的字符输出输入流,因为有缓冲区所以效率比没有缓冲区的高代码实现:
public class BufferedReaderDemo { public static void main(String[] args) throws IOException { //实例化缓冲字符流的对象 BufferedReader reader = new BufferedReader(new FileReader(“aaa.txt”)); //方式一:read循环读取 /* //读取 char[] arr = new char[8]; int len = 0; while((len = reader.read(arr)) != -1) { String string = new String(arr, 0, len); } */ /* 方式二:字符数组读取 int len=0; String str=null; char[] chars=new char[1024]; while ((len=br.read(chars))!=-1){ str=new String(chars,0,len);//将读到的字符装换成字符串 从0开始转换长度为len } System.out.print(str);*/ //方式三:readLine循环读取 String result = null; while((result = reader.readLine()) != null) { System.out.println(result); } reader.close(); }}
1.4BufferedWriter类
public class BufferedWriterDemo { public static void main(String[] args) throws IOException { // 实例化FIle对象 File file = new File("test33.txt"); //实例化缓冲字符输出流 BufferedWriter writer = new BufferedWriter(new FileWriter(file,true)); // 写 writer.write("今天天气还可以"); // 作用:主要就是为了换行 writer.newLine(); // 刷新 writer.flush(); //关闭 writer.close(); }}
2.内存流
输入和输出都是从文件中来的,当然,也可将输出输入的位置设置在内存上,这就需要ByteArrayInputStream和ByteArrayOutputStream
ByteArrayInputStream:将内容写入到内存中,是Inputstream的子类 ByteArrayOutputStream:将内存中数据输出,是OutputStream的子类 此时的操作应该以内存为操作点 案例:接下来一个字母大小写转换的程序让我们了解内存流public class ByteArrayInputStreamTest { public static void main(String[] args) throws IOException { String str="HELLO";//先声明一个要转换的字符串 ByteArrayInputStream bais= new ByteArrayInputStream(str.getBytes());//因为内存输入流构造只支持字节需要将字符串转成字节 ByteArrayOutputStream baos=new ByteArrayOutputStream();//这是无参的 int a=0;//定义一个变量 读取时候进行判断 while ((a=bais.read())!=-1){ baos.write(Character.toLowerCase((char)a));//将读出来的字节变成字符,再将字符转换成小写字母写出去 baos.flush();//刷新,将缓冲区中的数据刷新到内存,在这里可以不刷新 } bais.close(); baos.close(); String s = baos.toString();//将内存中的数据转成字符串在输出 System.out.println(s); }}
注意:内存操作流的操作对象,一定是以内存为主准,不要以硬盘为准。
三. 标准输入输出流
Java的标准输入/输出分别通过System.in和System.out实现,默认情况下分别代表是键盘和显示器
PrintStream类:PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。PrintWriter类:向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream中的所有 print方法。它不包含用于写入原始字节的方法
使用PrintStream的print方法打印数字出现的是数字,使用其write方法打印数字 会打印其对应的字符public class Demo2 { public static void main(String[] args) throws FileNotFoundException { /* PrintStream ps=new PrintStream("stifly.txt");//使用PrintStream的print方法打印数字出现的数字 //使用PrintStream的print方法打印数字出现的是数字,使用其write方法打印数字 会打印其对应的字符 ps.write(97);//a ps.println(); ps.println(97);//97 ps.println('a'); ps.println("java"); ps.print("中国");*/ PrintStream ps=new PrintStream("systemout.txt"); System.setOut(ps);//重定向到指定的ps对应的文件systemout.txt,打印的内容便会出现在systemout.txt System.out.println("好久不见"); ps.close(); }}
可以使用system.in来获取键盘输入对象并接收

接下来通过输入流来键盘输入字符串,然后通过标准输出流输出,输入为over时候结束
public class Demo { public static void main(String[] args) throws IOException { InputStream in=System.in;//获取标准输入流对象(注意这里输入的是字节) InputStreamReader isr=new InputStreamReader(in);//创建转换流对象 BufferedReader br=new BufferedReader(isr);//放入缓冲区 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); while (true){ String line = br.readLine(); System.out.println(line); if(line.equals("over")){ break; } } }}
四. 对象流(序列化与反序列化)
流中流动的数据是对象
将一个对象写入到本地文件(硬盘)中,被称为对象的序列化 将一个本地文件中的对象读取出来到内存中,被称为对象的反序列化 使用对象流 ObjectInputStream: 对象输入流(将对象从硬盘读出,到内存中 这是可以显示到控制台的,即反序列化) ObjectOutputStream:对象输出流(将内存中的对象读入到硬盘,即序列化)
注意:
序列化对象的类型必须实现Serializable接口。否则不能序列化。 如果向将多个对象序列化到本地,可以借助于集合,【思路:将多个对象添加到集合中,将集合的对象写入到本地文件中,再次读出来,获取到的仍然是集合对象,遍历集合】。 对象中那些字段可以不序列化: 1 transient 修饰的字段 2 静态的字段 在要序列化类中添加字段,保证序列化和反序列化是同一个类 private static final long serialVersionUID = 100L;
接下来创建一个学生类对象对其实现序列化和反序列化 必须实现Serializable接口
import java.io.Serializable;/* * 佛祖保佑,永无BUG! * 不能序列化:(1)transient修饰的成员(2)静态成员 * 序列化版本id:判断序列化和反序列化是否是同一个类. */public class Student implements Serializable { //序列化版本id 不加版本id的话 当序列化的对象属性和反序列化属性不一致时侯 系统会认为不是同 一个类 会报异常 比如序列化的时候没有email,反序列化的时候加了**email**属性 如果没有版本id来标记这是同一个类的话 就会报错认为不是同一个类 加了id之后序列化在反序列化就正常运行了 但是Email不会有只 private static final long serialVersionUID=1000L; private String name; private transient int age; //transient:瞬间的 加了次关键字的无法被序列化 private String address; public static String country="中国"; 静态的也无法序列化 //修改 private String email;//序列化时候加了 反序列的时候没有 测试版本ID的作用 public Student(String name, int age, String address) { this.name = name; this.age = age; this.address = address; } public Student() { } 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; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; }}
测试
* 使用ObjectOutputStream实现序列化 * 使用ObjectInputStreaam实现反序列化 * Serializable * Deserializable */public class Demo12 { public static void main(String[] args) throws Exception{ //writeObject(); readObject(); } public static void writeObject() throws Exception{ //1创建流 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("stu.bin")); //2序列化 Student shaobo=new Student("少泊", 16, "北京"); Student zhangsan=new Student("张三", 16, "北京"); Student lisi=new Student("李四", 16, "北京"); ArrayListlist=new ArrayList<>(); list.add(shaobo); list.add(zhangsan); list.add(lisi); oos.writeObject(list); //3关闭 oos.close(); System.out.println("序列化完毕"); }//反序列化 将硬盘文件中的数据读到内存控制台显示 public static void readObject() throws Exception{ //1创建流 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("stu.bin")); //2读取// Student stu1= (Student) ois.readObject();// Student stu2= (Student) ois.readObject();// Student stu3= (Student) ois.readObject(); ArrayList list = (ArrayList ) ois.readObject();//这里反序列化返回的是object类型需要转换成集合类型 在进行遍历 for (Student student : list) { System.out.println(student.toString()); } //3关闭 ois.close(); }}
五. RandomAccessFile类
RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。
* 使用RandomAccessFile读写文件 */public class Demo1 { public static void main(String[] args) throws Exception{ //write(); read(); } public static void write() throws Exception{ //1创建对象 RandomAccessFile raf=new RandomAccessFile("ran.txt", "rw"); //2写入 raf.writeUTF("张三"); raf.writeInt(20); raf.writeDouble(170.5); raf.writeBoolean(true); raf.writeUTF("李四"); raf.writeInt(22); raf.writeDouble(180.5); raf.writeBoolean(false); //3关闭 raf.close(); System.out.println("写入完毕"); } public static void read() throws Exception{ //1创建对象 RandomAccessFile raf=new RandomAccessFile("ran.txt", "r"); //设置跳过张三,设置读取指针的偏移量,从0开始// raf.seek(21);// raf.seek(21); //跳过21个字节,从当前位置 raf.skipBytes(21); //raf.skipBytes(21); //2读取 String name = raf.readUTF(); int age = raf.readInt(); double height = raf.readDouble(); boolean b = raf.readBoolean(); System.out.println(name+" "+age+" "+height+" "+b); //3关闭 raf.close(); }}
六. Properties类
是Map接口的一个实现类,并且是Hashtable的子类
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的 Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。
常用方法getProperty(String key) 用指定的键在此属性列表中搜索属性。setProperty(String key, String value) 调用 Hashtable 的方法 put。(相当于添加键值对,但是String类型)遍历可采用 stringPropertyNames() 方法,获取一个keyset的集合 再根据遍历key来获取值list(PrintStream out) 将属性列表输出到指定的输出流,将properties中的键值对输出到指定文件中)例如:list(new PrintStream("aaa.txt"));list(System.out); 将properties中的键值对元素输出到控制台load(InputStream inStream) 将指定文件中的属性加载出来
Properties集合中元素也是以键值对的形式存在的
Properties特点:
1 存储属性名和属性值 2 属性名和属性值都是字符串 3 和流有关系 4 没有泛型* 使用Properties集合保存数据 */public class Demo2 { public static void main(String[] args) throws Exception{ //创建集合 Properties properties=new Properties(); //1添加 properties.setProperty("name", "少泊"); properties.setProperty("age", "20"); properties.setProperty("address", "北京"); //2遍历 Setkeyset = properties.stringPropertyNames(); for (String key : keyset) { System.out.println(key+"===="+properties.getProperty(key)); } //3和流有关的方法 //3.1 list方法 System.out.println("-----------list---------"); properties.list(new PrintStream("prop.properties")); properties.list(System.out); //3.2load方法 System.out.println("-----------load-----------------"); Properties properties2=new Properties(); properties2.load(new FileReader("prop2.properties"));//将prop2.properties中的键值加载出来 properties2.list(System.out);//将加载出来的内容打印出来 //3.3store方法 properties2.store(new FileWriter("prop3.properties"), "信息"); //3.4System.getProperties(); System.out.println("---------System.getProperties();----------"); Properties sysprop = System.getProperties(); sysprop.setProperty("myname", "hello"); sysprop.list(System.out); }}
转载地址:https://blog.csdn.net/shunshizhen120412/article/details/98990359 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关于作者
