BufferWriter的出现,增强了Writer体系中的功能,这种设计方式比原理更为灵活,避免了继承的臃肿。由此引出了java的又一种设计模式-装饰设计模式。 具体实例: Writer |--TextWriter |--MediaWriter 运用缓冲技术提高效率: Writer |--TextWriter |--BufferTextWriter |--MediaWriter |--BufferMediaWriter |--DataWriter |--BufferDataWriter 通过继承的方式提高了效率。但是对于扩展性是一个问题。而且所需的功能越多,子类就越多。一旦加入新类,就需要为它提供高效。 既然都需要缓冲,对数据写入效率进行提高 。可以将缓冲技术单独进行封装。哪个对象需要缓冲,就把哪个对象传递给缓冲对象即可。 classBuffer{ Buffer(TextWriterw){ } Buffer(MediaWriterw){ } } 体系就变成了这样: Writer |--TextWriter |--MediaWriter |--BufferWriter BufferWriter的出现,增强了Writer体系中的功能。 字符流的常用对象和装饰设计模式简单讨论完了。 字符流处理的数据都是文字,需要将指定的数据,查指定的编码表。而字节流处理的数据不一定都是文字数据,所以不需要指定查表,直接在操作文件数据的时候,就将具体的字节数据写入到目的地址。 下面通过一个示例演示。 示例:copyMp3 1. import java.io.BufferedInputStream; 2. import java.io.BufferedOutputStream; 3. import java.io.FileInputStream; 4. import java.io.FileOutputStream; 5. import java.io.FileReader; 6. import java.io.FileWriter; 7. import java.io.IOException; 8. 9. public class CopyMp3Test { 10. 11. public static void main(String[] args) throws IOException { 12. 13. long start = System.currentTimeMillis(); 14. copy_1(); 15. long end = System.currentTimeMillis(); 16. System.out.println("毫秒值:"+(end-start)); 17. } 18. //不用缓冲区。 19. public static void copy_4() throws IOException { 20. 21. FileInputStream fis = new FileInputStream("C:\\0.mp3"); 22. 23. FileOutputStream fos = new FileOutputStream("c:\\4.mp3"); 24. 25. int by = 0; 26. 27. while((by=fis.read())!=-1){ 28. fos.write(by); 29. } 30. 31. fos.close(); 32. fis.close(); 33. 34. } 35. //不建议。使用刚刚好的缓冲区。因为文件过大会溢出。 36. public static void copy_3() throws IOException { 37. 38. FileInputStream fis = new FileInputStream("C:\\0.mp3"); 39. FileOutputStream fos = new FileOutputStream("c:\\3.mp3"); 40. 41. byte[] buf = new byte[fis.available()]; 42. 43. fis.read(buf); 44. 45. fos.write(buf); 46. 47. fos.close(); 48. fis.close(); 49. 50. } 51. 52. //使用字节流已有的缓冲区。 53. public static void copy_2() throws IOException { 54. 55. 56. FileInputStream fis = new FileInputStream("C:\\0.mp3"); 57. FileOutputStream fos = new FileOutputStream("c:\\2.mp3"); 58. 59. BufferedInputStream bufis = new BufferedInputStream(fis); 60. BufferedOutputStream bufos = new BufferedOutputStream(fos); 61. 62. // //3,定义一个字节缓冲区。 63.// byte[] buf = new byte[1024]; 64. 65. int by = 0; 66. 67. while((by=bufis.read())!=-1){ 68. bufos.write(by); 69. } 70. 71. bufos.close(); 72. bufis.close(); 73. 74. 75. } 76. 77. //自定义数组缓冲区的方式。 78. public static void copy_1() throws IOException { 79. 80. //1,读取流对象,和mp3关联。 81. FileInputStream fis = new FileInputStream("C:\\0.mp3"); 82. //2,写入流对象,明确存储mp3数据的目的。 83. FileOutputStream fos = new FileOutputStream("c:\\1.mp3"); 84. 85. //3,定义一个字节缓冲区。 86. byte[] buf = new byte[1024*8]; 87. 88. int len = 0; 89. 90. while((len=fis.read(buf))!=-1){ 91. fos.write(buf,0,len); 92. } 93. 94. fos.close(); 95. fis.close(); 96. 97. } 98. 99. } 通过示例可以发现,字节流不需要flush(),但close()仍是必须的。 原因:字节流直接是字节数据在源地址和目的地址之间的存储,而字符流会将数据进行临时存储,根据编码表解析成二进制数据后才进行传输,在底层也使用了字节流。
|