IO流 整理
来源:互联网 发布:开淘宝网店的流程2016 编辑:程序博客网 时间:2024/06/14 10:55
引入
io流是操作数据(主要是控制台,和内存中)、文件(硬盘中)的流对象。
引用的包是java.io.*
按流向分为:输入流和输出流。
按操作数据分为:字节流和字符流
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀
如:InputStream的子类FileInputStream。 Reader的子类FileReader。
字符流
简单的字符流。
- 读
//一个一个字符打印FileReader fr=new FileReader(“hello.txt”);int ch;while((ch=fr.read())!=-1){System.out.println((char)ch);}
//指定长度字符串打印FileReader fr=new FileReader(“hello.txt”);char[] chs=new char[1024];int length;//一次读了多少长度的字符串while(length=fr.read(chs));{//取对应读取长度的字符串长度。System.out.println(new String(chs,0,length));}
- 写
//没有该文件则创建,有该文件则覆盖FileWriter fw=new FileWriter(“hello.txt”);//没有该文件创建,有该文件则续写。//FileWriter fw=new FileWriter(“hello.txt”,true);fw.write(“dddgfwe”);fw.flush();fw.close();
在IO中最必要的就是有IO异常,需要对异常处理,或者抛出,下面是对异常完整处理的代码。
- 读加写 完整异常处理
FileDemo.java
import java.io.*;class FileDemo{ public static void main(String[] args) { //在try的外面声明对象,使该对象是存在的,如果try中抛出了异常,对象也能被finally被使用! FileReader fr=null; FileWriter fw=null; try{ //这里使用读文件和写文件,所以都会抛异常。 fr=new FileReader("FileReaderDemo.java"); fw=new FileWriter("copy.txt"); char[] ch=new char[1024]; int len=0; while((len=fr.read(ch))!=-1){ fw.write(ch,0,len); } fw.flush(); }catch (IOException e){ System.out.println(e); }finally{ try{ /*关流也存在异常。但是为了减少异常的出现,我们可以在关流之前对对象进行判空,如果是空那么那么无需关闭。当然需要分别判空*/ if (fr==null) { fr.close(); } if (fw==null) { fw.close(); } }catch (IOException e){ System.out.println(e); } } }}
tip.在windows中 换行是”/r/n”
能够对文件进行读写之后,我们希望能够提高速度,所以缓冲流就引入了。
- 读加写 缓冲流 异常处理
可以注意下缓冲流中对换行已经封装好了。
BufferedWriterDemo.java
import java.io.*;class BufferedWriterDemo{ public static void main(String[] args)throws IOException{ BufferedReaderAndWriter_Method(); }//写 public static void BufferedWriter_Method()throws IOException{ FileWriter fw=new FileWriter("xx.txt"); BufferedWriter bw=new BufferedWriter(fw); bw.write("sjhhs"); //封装好了换行,好处,可以跨操作系统使用。 bw.newLine(); bw.write("311"); bw.flush(); bw.close(); } public static void BufferedReader_Method()throws IOException{ FileReader fr=new FileReader("xx.txt"); BufferedReader br=new BufferedReader(fr); String aa=null; //封装了读一整行,而且是不带换行符号的(windows系统中的"\r\n") //返回类型直接是String类型,便于操作 while((aa=br.readLine())!=null){ System.out.println(aa); } br.close(); }//缓冲流读加写,并且异常处理 public static void BufferedReaderAndWriter_Method(){ BufferedReader br=null; BufferedWriter bw=null; try{ br=new BufferedReader(new FileReader("FileDemo.java")); bw=new BufferedWriter(new FileWriter("copy2.txt")); String line=null; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } }catch (IOException e){ System.out.println(e); }finally{ try{ if (bw!=null) { bw.close(); } if (br!=null){ br.close(); } }catch(IOException e){ System.out.println(e); } } }}
缓冲流的使用其实是一种装饰模式。文章的末尾会浅谈一番。
BufferedWriter中的newLine()封装的是打印换行的转译字符(所以在windows系统和linux系统都可以使用);
BufferedReader中的readLine()封装的是通过read()方法一个一个字符读取,总合一行的字符(直到字符为换行字符即“/r/n”),则返回一行的字符串,不包含转译字符。
我们可以自己试着书写一个缓冲输入流。
MyBufferedReaderDemo.java
import java.io.*;class MyBufferedReaderDemo{ public static void main(String[] args)throws IOException{ FileReader fr=new FileReader("xx.txt"); MyBufferedReader mbr=new MyBufferedReader(fr); String line=null; while((line=mbr.myRead())!=null){ System.out.println(line); } if (mbr!=null) { mbr.myClose(); } }}class MyBufferedReader{ private FileReader f; //构造函数值得注意一下 MyBufferedReader(FileReader f){ this.f=f; } public String myRead()throws IOException{ StringBuilder sb=new StringBuilder(); int ch = 0; while((ch=f.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{ f.close(); }}
字节流
同样看读写,以及使用缓存的例子
- 读
public static void method_1()throws IOException{ FileOutputStream fos=new FileOutputStream("ceshi.txt"); fos.write(("dasgxc").getBytes());//与字符流不同的是:这里没有刷缓存!//资源是需要关闭的,是占用资源的 fos.close(); }
在FileOutputStream中的write所写的是最小单位,不需要刷新,直接传输,没有任何转换。
FileWriter所使用的write方法经过封装,底层使用的是FileOutputStream,是将一个字符分解为一个个字节来传输的,所以它是需要刷新缓存。
写
//一个一个字节读取。 public static void method_2()throws IOException{ FileInputStream fis=new FileInputStream("ceshi.txt"); int b=0; while((b=fis.read())!=-1){ System.out.println((char)b); } }
//一串字节读取。 public static void method_3()throws IOException{ FileInputStream fis=new FileInputStream("ceshi.txt"); byte[] b=new byte[1024]; int len=-1; while((len=fis.read(b))!=-1){ System.out.println(new String(b,0,len)); } }
//设置一个与复制目标文件相同大小的字节数组,将这串字节数组一起打印,所以只需要一次,不用循环。//但是,当目标文件过大时,会使内存爆炸,如比内存还大,内存中就装不下这样的数组了。 public static void method_4()throws IOException{ FileInputStream fis=new FileInputStream("ceshi.txt"); //得到文件的大小 int size=fis.available(); byte[] b=new byte[size]; fis.read(b); System.out.println(new String(b)); }
字节流缓冲读写
public static void method_5()throws IOException{ BufferedInputStream bis=new BufferedInputStream(new FileInputStream("ceshi.txt")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("ceshi2.txt")); int by=0; while((by=bis.read())!=-1){ bos.write(by); } bis.close(); bos.close(); }
- 通过字节流复制一个mp3文件。
CopyMp3.java
import java.io.*;class CopyMp3{ public static void main(String[] args) throws IOException{ long start =System.currentTimeMillis(); // MyBufferedInputStream mbis=new MyBufferedInputStream(new FileInputStream("1.mp3")); BufferedInputStream mbis=new BufferedInputStream(new FileInputStream("1.mp3")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("2.mp3")); int i=0; while((i=mbis.myRead())!=-1){ bos.write(i); } bos.close(); mbis.myClose(); long end =System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); }}
自己写一个读mp3的字节流,当然是使用缓冲流提速的!
MyBufferedInputStream.java
import java.io.*;class MyBufferedInputStream{ private InputStream in; private int pos=0,count=0; private byte[] b=new byte[1024*1024]; MyBufferedInputStream(InputStream in){ this.in=in; } public int myRead()throws IOException{ if (count==0) { count=in.read(b); pos=0; if (count<0) { return -1; } // System.out.println("length:"+b.length+" count:"+count+" pos:"+pos); byte bt=b[pos]; count--; pos++; //注意这里并上了一个255。 return bt&255; } else if (count>0) { // System.out.println("length:"+b.length+" count:"+count+" pos:"+pos); byte bt=b[pos]; count--; pos++; return bt&255; } return -1; } public void myClose()throws IOException{ in.close(); }}
由于二进制转换为int的时候,为防止出现连续的八个1(1111 1111 即可以表示255也可以表示-1,而在判断条件是,read()==-1,表示读到了文件的末尾,出现冲突,可能会提前结束读的操作)。
所以转换时,存在着提升的现象,在每个8位二进制的数值前,补上三组八个0,使其区分于“-1”的二进制(32个1)表示。即
一个字节(8位)&0000 0000 0000 0000 0000 0000 1111 1111(255)。
修改CopyMp3.java
import java.io.*;class CopyMp3{ public static void main(String[] args) throws IOException{ long start =System.currentTimeMillis(); MyBufferedInputStream mbis=new MyBufferedInputStream(new FileInputStream("1.mp3")); //BufferedInputStream mbis=new BufferedInputStream(new FileInputStream("1.mp3")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("2.mp3")); int i=0; while((i=mbis.myRead())!=-1){ bos.write(i); } bos.close(); mbis.myClose(); long end =System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); }}
装饰设计模式
现在我们来浅谈一番 装饰设计模式
老师的定义:想要对已有的对象进行功能强化时,可以定义类,将已有对象传入,基于已有的功能,并提供加强的功能。那么称这个类为装饰类。
首先,这是装饰,所以他是服务的,而不是自己有的,那么它就没有空的构造函数,它只有有参的构造函数。
并且,前面提到的参数是所要装饰的对象,作为该装饰类的私有属性,通过构造函数来初始化。
提示:参数最好可以使用父类或者基类。使用一个基类,可以使它不同的子类作为入参,可以以多态的形式实现,而且降低了具体的子类和装饰类的耦合关系。
BufferedReader是Reader的装饰类。
而LineNumberReader也是Reader的装饰类,它同样是BufferReader的子类,所以部分代码在BufferedReader基础上面有拓展。
- IO流整理
- Java IO 流整理
- IO流分析整理
- java io流整理
- IO流知识点整理
- JAVA - IO流 - 整理
- java io 流整理
- IO流一点整理
- JAVA IO 流整理
- IO流知识点整理
- java io流整理
- java IO流整理
- IO流 整理
- Java IO流分析整理
- Java IO流分析整理
- Java IO流分析整理
- Java IO流分析整理
- 黑马程序员 IO流整理
- Function类型——ECMAScript
- 鸟哥的私房菜Linux 学习笔记之 Bash语法
- leetcode 119. Pascal's Triangle II
- quick 添加 GAF
- python设计模式之装饰器模式
- IO流 整理
- java 五子棋
- JUnit单元测试
- python设计模式之组合模式
- js 获取tr下的td下的 input值
- iOS开发证书管理
- 数据源
- PAT 乙级练习题1009. 说反话 (20)
- 关于QLabel无法显示的问题