IO字符源阶段总结
IO字符流阶段总结
IO: 用于设备上的数据处理。 IO的分类: 字符流,字节流。 在早期时,只有字节流,后期为了方便处理不同的文字出现了字符流。 因为编码的原因,而出现字符流。 所有IO体系中的对象通常都以自己所属的父类名作为子类名的后缀名。 IO体系顶层类: 四个抽象基类: 字节流: InputStream OutputStream。 字符流: Reader Writer。 使用了字符流中的子类对象。因为要操作的是硬盘的文件。 所以使用了FileReader,FileWriter. 需求: 在硬盘上建立一个文件,并往文件中写入内容。 1,建立字符写入流对象。 建立了流对象,调用了window资源,在指定位置创建了demo.txt文件。先建立了数据存储的目的。 但是因为传递参数的原因,有可能出现IO异常。 如果指定目录下已有该文件会出现覆盖操作。 如果需求是在原有文件中进行数据的续写。要在构造时,传入另一个参数true。new FileWriter("demo.txt",true); FileWriter fw = new FileWriter("demo.txt"); 2,调用流对象写入方法,将数据写入到流中。 fw.write("abcdec");//fw.write("abcd".toCharArray()); 3,对流中的数据进行刷新,将数据刷到目的当中。 fw.flush(); 可以进行频繁写入,并刷新。。。。 4,关闭资源,会刷新它先。 fw.close(); public void show() { FileWriter fw = null; try { fw = new FileWriter("c:/demo.txt"); fw.write("abced"); } catch(IOException e) { System.out.println(e.toString()); } finally { /* if(fw!=null) try { fw.close(); } catch(Exception e) { e.printStackTrace(); } */ closeAll(fw,null); } } 需求: 读取硬盘上的数据,并将其打印在控制台上。 //1,建立字符读取流对象。先用流对象与要读取的文件相关联。必须要保证该是存在的,否则会发生FileNotFoundException。 FileReader fr = new FileReader("demo.txt"); //2,定于一个临时容器,因为读到的都是字符数据,所以建立一个字符数组。 该数组的长度如何定义呢?以计算机的基本单位或者其整数倍作为长度 char[] arr = new char[1024]; //3,使用读取流对象的read(arr)方法,将读取到每一个字符数据存入到数组中。 该方法会读到的字符个数。其实就是往数组里面装的元素的个数。 int num = 0; while((num=fr.read(arr))!=-1) { System.out.println(new String(arr,0,num)); } //4,关闭资源。 fr.close(); 注意:读取流还有一个read()方法,该方法是没有参数的,一次读一个字符,并将读到的字符返回。 int ch = 0; while((ch=fr.read())!=-1) { System.out.println((char)ch); } 需求: copy文本文件 public void show() { FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("demo.txt"); fw = new FileWriter("copydemo.txt"); char[] arr = new char[1024]; int num = 0; while((num=fr.read(arr))!=-1) { fw.write(arr,0,num); } } catch(Exception e) { ystem.out.println(e.toString()); } finally { closeAll(fw,fr); } } public void closeAll(Writer w,Reader r) { if(w!=null) try { w.close(); } catch(Exception e) { e.printStackTrace(); } if(r!=null) try { r.close(); } catch(Exception e) { e.printStackTrace(); } } ----------------------------------------- 为了提高了对流的操作效率,出现了缓冲技术,提高了流的操作效率。 该缓冲技术也被封装成了对象。 对于字符流: BufferedWriter: newLine();跨平台的换行符。 BufferedReader readLine():一次获取一行数据。不包括回车符。 缓冲技术,是为了提高流的效率,所以缓冲对象在初始化的时必须要有流。 使用缓冲技术一定要使用flush(); 需求:通过缓冲技术对文本数据进行copy. public void show() { FileReader fr = new FileReader("demo.txt"); BufferedReader bufr = new BufferedReader(fr); FileWriter fw = new FileWriter("bufdemo.txt"); BufferedWriter bufw = new BufferedWriter(fw); String line = null; while((line=bufr.readLine())!=null) { bufw.write(line); bufw.newLine(); bufw.flush(); } bufw.close(); bufr.close(); //closeAll(bufw,bufr); } 缓冲技术的出现对流的读取和写入都进行了增强。 其实就是将一个数组封装在缓冲对象中。 这里就用到了一种设计模式:装饰设计模式。 该模式可以对类中的功能进行增强,优化了继承。 通过继承一样可以完成对类功能的增强,为了还要装饰呢? Writer |--FileWriter |--BufferFileWriter |--MediaWriter |--BufferMediaWriter |--DateWriter |--BufferDateWriter 为了增强子类的操作效率。想到了缓冲技术。通过继承的方法,在子类中建立带缓冲技术的功能。 但是在设计方式中,发现该体系变的比较臃肿,而且功能都在重复。 那么,进一步优化该设计。 可不可以将缓冲技术进行抽取,单独进行描述。 想要对这些子类进行增强时,只要将每一个子类作为参数传递给缓冲类的构造函数即可。 Writer |--FileWriter |--MediaWriter |--DateWriter |--Buffer class Buffer { Buffer(FileWriter w) {} Buffer(MediaWriter w) {} Buffer(DateWriter w) {} } 发现这样设计不具备扩展性。 因为传递的都是Writer的子类,只要建立父类引用即可,多态。 class Buffer extends Writer { Buffer(Writer w) {} } --------------------------------------- readLine():原理:其实还是用底层read方法,只不过将每一次读到的字符进行临时存储, 当读到回车符,将临时存储的数据一次性返回。 class MyBufferedReader { private Reader r; MyBufferedReader(Reader r) { this.r = r; } public String myReadLine()throws IOException { StringBuilder sb = new StringBuilder(); int ch = 0; while((ch=r.read())!=-1) { if(ch=='\r') continue; if(ch=='\n') return sb.toString(); else sb.append((char)ch); } if(sb.length()!=0) return sb.toString(); return null; } public void myClose()throws IOException { r.close(); } } ----- 带行号 class MyLineNumberReader extends MyBufferedReader { private int myNumber; MyLineNumberReader(Reader r) { super(r); } public void setMyNumber(int myNumber) { this.myNumber = myNumber; } public int getMyNumber() { return myNumber; } public String myReadLine()throws IOException { myNumber++; return super.myReadLine(); } }