java基础复习 IO

发布时间:2016-12-10 18:47:10 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"java基础复习 IO",主要涉及到java基础复习 IO方面的内容,对于java基础复习 IO感兴趣的同学可以参考一下。

IO IO中的流对象 InputStream OutputStream 字节流   BufferedInputStream BufferedOutputStream 字节缓冲区   ByteArrayInputStream ByteArrayOutputStream 操作字节数组   DataInputStream DataOutputStream     FileInputStream FileOutputStream 操作图片、音视频等文件   FilterInputStream FilterOutputStream     ObjectInputStream ObjectOutputStream 操作对象   PipedInputStream PipedOutputStream           Reader Writer 字符流   BufferedReader BufferedWriter 字符流缓冲区   CharArrayReader CharArrayWriter 操作字符数组   StringReader StringWriter 操作字符串   FileReader FileWriter 操作文本文件的   InputStreamReader OutputStreamWriter 转换流   PipedReader PipedWriter     FilterReader FilterWriter           LineNumberInputStream     LineNumberReader           PrintStream 字节打印流   PrintWriter 字符打印流         PushbackInputStream     PushbackReader           SequenceInputStream     StringBufferInputStream 操作字符串的字节流         Console     File 用于封装文件   FileDescriptor     FilePermission     ObjectInputStream.GetField     ObjectOutputStream.PutField     ObjectStreamClass     ObjectStreamField     RandomAccessFile     SerializablePermission     StreamTokenizer                  目的 源      内存 文件 控制台 Sokcet 内存         文件         Socket             IO大纲   字符流 FileWriterFileReader: 1FileWriter 2文件的续写, 3文本文件的读取方式1, 4文本文件的读取方式2, 5拷贝文本文件          bufferedWriterbufferedReader: 2、通过缓冲区复制文本文件, 3、readLine()方法的原理, 4、MyBufferedReader          装饰设计模式: 1、装饰设计模式,2、装饰和继承的区别,3、自定义装饰类               LineNumberReader: 1、LineNumberReader, 2、MyLineNumberReader   字节流        FileInputStreamFileOutputStream: 1字节流File读写操作, 2拷贝图片        BufferedInputStreamBufferedOutputStream: 字节流缓冲区, 自定义字节流的缓冲区 read和write的特点, 读取键盘录入     转换流   流的常规操作        流的常规操作规律-1,流的常规操作规律-2 其他操作        改变标准输入输出设备,异常的日志信息,系统信息   流操作文件:File对象        创建,删除,判断,获取,文件列表-1,文件列表-2,列出目录下所有内容--递归,列出目录下所有内容--带层次,删除带内容的目录,创建java文件列表   Properties        存取,存取配置文件,练习 其他流对象        PrintWriter, 合并流, 切割流, 对象的序列化, 管道流, RandomAccessFile, 操作基本数据类型的流对DataStream, ByteArrayStream   转换流的字符编码 字符编码 联通 练习 第一章 字符流 第一节 FileWriter 1、FileWriter     FileWriter的继承结构是:lang.object>io.Writer> io.OutputStreamWriter     构造方法摘要 FileWriter(File file)           根据给定的 File 对象构造一个 FileWriter 对象。   FileWriter(File file, boolean append)           根据给定的 File 对象构造一个 FileWriter 对象。   FileWriter(FileDescriptor fd)           构造与某个文件描述符相关联的 FileWriter 对象。   FileWriter(String fileName)           根据给定的文件名构造一个 FileWriter 对象。   FileWriter(String fileName, boolean append)           根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。     从类 java.io.OutputStreamWriter 继承的方法 close, flush, getEncoding, write, write, write 从类 java.io.Writer 继承的方法 append, append, append, write, write   使用FileWriter对象,写入数据的步骤:1 导包,2 创建一个FileWriter对象。需要注意的是:该对象一被初始化就必须要有要操作的对象,如果该目录下已有指定的要操作的同名文件,原有文件将被覆盖。3 使用write方法向目标文件中写入数据fw.write("abc");4 刷新fw.flush() ;5 fw.write("def") ;会写在abc后面;6 fw.flush();关闭流资源,关闭前会刷新fw.close();   2文件的续写, API中FileWriter有构造函数FileWriter(String fileName,boolean append) 。可用于在文件的原有数据上加入数据,而不去覆盖原文件。如果参数append为 true,则将数据写入文件末尾处,而不是写入文件开始处。   3文本文件的读取方式1,读取单个字符就操作        Reader不用刷新,使用Reader的read方法读取的是字符。可以一次读取单个字符然后操作,或是将读取到的字符缓存入字符数组然后操作,不能直接读字符串。Reader使用的是默认的字符编码,使用System.getPorperties()可以得到系统信息。read()返回类型是int 可以根据需要将其强转成(char)。        特点:此方法会自动往下读,读到流的末尾返回-1,并且一直阻塞        使用read()方法读取一次读取单个字符。示例代码        FileReaderfr = new FileReader(c:\\demo.txt);        intch = 0 ; while((ch =fr.read())!=-1){        //对读取的字符进行操作 }   4文本文件的读取方式2, 读取单个字符,将其存入指定大小的字符数组,待将数组装满,再对结果操作        read(char[]cbuf) 返回的是读到的字符个数,数据类型是int 。使用此方法可以将数据缓冲入cbuf中。 通常为了方便,要将得到的cbuf转换为String类型。方法是new String(cbuf,0,num) ,其中num是read的返回值,这样就将字节数组cbuf中的0~num个字节转成了一个字符串,num是读到的字符个数,即cbuf中的有效字符个数,避免了无效字符的产生。 特点:读到末尾返回-1一直阻塞        示例代码        FileReaderfr = new FileReader(c:\\demo.txt);        //定义一个指定大小的字符数组,用以缓存read读到的字符        byte[]cbuf = new byte[1024] ; int num = 0 ; while((num =fr.read(cbuf))!=-1){        //对读取的字符进行操作 } 5拷贝文本文件   第二节 bufferedWriter bufferedReader 1、BufferedWriter BufferedReader        字符流缓冲区1、缓冲区的出现提高了对数据的读写效率,在创建缓冲区钱,要操作的流对象必须存在。2、对应类:BufferedWriter和BufferedReader3、缓冲区使用时要结合流4、在流的基础上对流的功能进行了增强5、出现了新的方法。 BufferedWriterBufferedReader是Writer和Reader的子类。继承了它们的读写方法,同时有自己更加功能更实用的方法。 BufferedWriter的void write(int c) ,写入单个字符,write(char[] cbuf, int off,int len) 写入字符数组的某一部分,write(Strings, int off, int len) 写入字符串的某一部分,newLine()写入一个行分隔符,这个方法在各种平台通用。有自己的刷新的关闭方法。 BufferedReader的readLine()方法可以一次读取一行,但不包含终止符,如果读到流的末尾返回null。他的结束标记是回车符,返回类型是String。   2、通过缓冲区复制文本文件, readLine方法读取的数据不包含行终止符,所以读取一行后,要加入换行符; 并且写入后一定要刷新,如果不刷新,数据将保留在缓冲区中,刷新后数据才被写进目标; 缓冲区提高了FileWriter的效率,但真正和文件相关联并对文件进行操作的是FileWriter缓冲区的关闭,实际上关闭的是调用底层资源的流对象。   3、readLine()方法的原理,        无论是读一行,获者读取多个字符。都必须在硬盘上一个一个字符读取,所以最终使用的还是一次读取一个的read方法,。readLine方法内部封装了一个数组,使用read方法读取一个字符后,并没有将这个字符返回给下一步的操作者,而是将其存储在数组中,直到读到换行符的\r时,再调用一次read方法读取一个字符,如果这个字符是\n,就将数组中的数据一次性返回给下一步的操作者。   4、MyBufferedReader        MyBufferedReader{ private Reader r ;        MyBufferedReader(Readerr){            this.r= r ; } public String myReadLine(){ StringBuilder sb = new StringBuilder(); int ch; while((ch = read() )!=-1) {//使用传入的功能 if(ch == ’\r’)        coutinue; if(ch == ‘\n’){        returnsb.toString();       } else sb.append((char)ch); //添加前要转换为char, } return null ;    } }   第三节 装饰设计模式 1、装饰设计模式, 当想要对已有的对象的功能进行增强时,可以定义一个类,将想要增强的类传入,并基于已有的功能,提供新的更强大的功能。这种方法我们称之为装饰设计模式。增强类称之为装饰类。 装饰类基于被装饰类,并且通常装饰类和被装饰类属于同一个体系。   2、装饰和继承的区别 装饰设计模式的由来 是专门用于读取文本数据的类,它有一些子类。在使用MyReader子类读文本时,发现效率低,想到了缓冲技术,由MyReader的子类衍生出了一些用于缓冲的子类。 下面是它的继承体系。               MyReader                      |--MyTextReader                             |--MyBufferTextReader                      |--MyMediaReader                             |--MyBufferMediaReader                      |--MyDataReader                             |--MyBufferDataReader        如果MyReader的每个直接子类都需要增强,这样产生的继承体系,臃肿复杂,这个时候就需要对现有的体系进行优化。思路是可以定义一个类,将需要缓冲的MyReader的直接子类作为参数传入。        MyReader直接子类原来的功能是读,定义的装饰类增强了读取的功能,所以装饰类的功能也是读取,因此也应该是MyReader体系中的一员,所以它应该继承MyReader。                      classMyBufferedReaer() extends MyReader                      {                             privateReader r ;                             MyBufferedReaer(MyReaderr)                             {                                    this.r= r ;                             }                             //增强功能                      } 这样,原来的体系就变得简单起来,MyReader直接子类和装饰类的关系由继承变成了组合               MyReader                      |--MyTextReader                      |--MyMediaReader                       |--MyDataReader                      |--MyBufferBufferReader   装饰类对原有对象的功能进行了增强,它具备的功能和原有对象的功能都可以达到同样的目的。但是装饰类的功能使用起来更加方便。 所以装饰类和被装饰类通常都是属于同一个体系.   3、自定义装饰类        在定义装饰类时,定义的增强功能因为原有功能而有可能产生异常时,不能捕捉,而应该抛出,让调用者处理。 第四节 LineNumberReader: 1、LineNumberReader        LineNumberReader是BufferedReader子类,是可以跟踪行号的缓冲字符输入流。 此类定义了方法setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。并且有readLine()方法。 2、MyLineNumberReader import java.io.*; class MyLineNumberReader extends BufferedReader {        private int lineNumber ;        MyLineNumberReader(Readerr)        {               super(r) ;        }        public StringmyReadLine() throws IOException        {               //每调用一次myReadLine() lineNumber自增1 ; lineNumber++ ;               returnsuper.readLine();        }        //特有方法        public void setLineNumber(int lineNumber)        {               this.lineNumber =lineNumber ;        }        public int getLineNumber()        {               returnlineNumber;        } } 第二章 字节流 第一节 FileInputStreamFileOutputStream: 字节流的read方法读取的是字节,可以读取单个字符,或是将读取的字符存入字节数组。available()方法返回字符的个数( \r 和\n分别是一个字节)。可以使用这个方法定义一个大小等于源的缓冲区。 1字节流File读写操作        字节流write方法不用刷新。        一次读一个字节 FileInputStreamfis = new FileInputStream(“c:\\demo.txt”);        FileOutputStreamfos = new FileOutputStream(c:\\demo_1.txt) ; int len = 0 ; while((len= fis.read())!=-1){ fos.write(len);        } 读入字节数组中,然后写入目标 FileInputStreamfis = new FileInputStream(“c:\\demo.txt”);        FileOutputStreamfos = new FileOutputStream(c:\\demo_1.txt) ; byte[] b = newbyte[1024]; int num = 0 ; while((num= fis.read(b))!=-1){ fos.write(b,0,num);        }        available()方法的使用 FileInputStreamfis = new FileInputStream(“c:\\demo.txt”);        FileOutputStreamfos = new FileOutputStream(c:\\demo_1.txt) ; byte[] b = newbyte[fis.available()]; fis.read(b); fos.write(b); 2拷贝图片        第二节BufferedInputStream BufferedOutputStream: 1字节流缓冲区   2自定义字节流的缓冲区 read和write的特点   读取字节时,如果读到连续八个1,连续的八个1对应的是整数-1,程序会错误地以为是结束标记,会停止读取,导致目标文件不完整,复制失败。 为什么返回的是int而不是byte 11111111 ——>提升为一个int类型,那不还是-1吗?是-1的原因是,在八个1前面补了1,那么在八个1前面补0,就可以避免这种-1,即可以保留原字节数据不变,由可以避免-1的出现 所以用int接收byte,将其类型提升。然后使用&255的方式,在原数据前补0 ,避免了读到连续八个一,等于-1,和结束标记相等 的情况。如下图 byte:-1 ——> int:-1 ; 00000000 00000000 00000000 11111111 255, 11111111 11111111 11111111 11111111 -1   取最后4位:&15() 取最后8位&255 import java.io.*; class MyBufferedInputStream  {        private InputStream in ;        private byte[] buf = newbyte[1024*1024];        private int pos = 0 ,count = 0;             MyBufferedInputStream(InputStreamin)        {               this.in = in ;        }        //一次读一个字节,从缓冲区(字节数组)获取        public int myRead() throws Exception        {               //通过in对象读取硬盘上数据,并存储buf中               if(count == 0 )               {                      count = in.read(buf);                      if(count<0)                             return -1;                      pos = 0 ;                      byte b = buf[pos];                                           count -- ;                      pos++ ;                      return b&255/*255的十六进制表现形式*/ ;               }               else if(count>0)               {                      byte b = buf[pos];                      count -- ;                      pos++ ;                      return b&255;               }               return -1 ;        }        public voidmyClose()throws Exception        {               in.close();        }        public static voidcopyMp3()throws Exception        {               MyBufferedInputStreambis =                      newMyBufferedInputStream(new FileInputStream("c:\\王麟 - 当爱情离开的时候.mp3"));               BufferedOutputStreambos =                      newBufferedOutputStream(new FileOutputStream("c:\\王麟 - 当爱情离开的时候_copy.mp3"));                             //byte[] buf =new byte[1024*1024];               //int len = 0 ;               int by = 0 ;               while((by =bis.myRead())!=-1)               {                      bos.write(by);               }               bis.myClose();               bos.close();        }               public static voidmain(String[] args) throws Exception        {               long start =System.currentTimeMillis();               System.out.println(start);               copyMp3();               long end =System.currentTimeMillis();               System.out.println(end);               System.out.println("用时"+(end-start)+"毫秒");                      } } 3读取键盘录取        使用字节流进行键盘录入               InputStream in = System.in;               StringBuildersb = new StringBuilder();               while(true)               {                      Strings = null ;                      intch = in.read();                      if(ch== '\r')                             continue;                      if(ch== '\n')                      {                             s= sb.toString();                                                         if("over".equals(s))                                    break;                             System.out.println(s.toUpperCase());                             sb.delete(0,sb.length());                      }                                 else                      {                             sb.append((char)ch);                      }               }            第三章 转换流       InputStreamReader OutputStreamWriter 第四章 流的常规操作 OutputStreamWriter可以指定编码表 怎么选择流对象? 1明确源和目的        源:输入流 InputStream Reader        目的:输出流 OutputStream Writer 2操作的数据是否是存文本        是:用字符流        否:字节流 3当体系明确后,再明确使用哪个具体的对象        源:内存,硬盘,键盘        目的:内存,硬盘,控制台 第五章 其他操作 第一节 改变标准输入输出设备        static void setIn(InputStream in)           重新分配“标准”输入流。 static void setOut(PrintStream out)           重新分配“标准”输出流。        第二节 异常的日志信息        异常的日志信息,以下是异常日志信息的建立方式。但真正开发时,不用这样的方法,在网络上有一个专门建立java日志信息的工具包log4j。 import java.io.*; import java.util.*; import java.text.*; class  ExceptionInfo {        public static voidmain(String[] args)        {               try               {                      int[] arr= new int [2] ;                      System.out.println(arr[3]);               }               catch (Exceptione)               {                                        try                      {                             Dated = new Date();                             SimpleDateFormatsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                             Strings = sdf.format(d);                                                         PrintStreamps = new PrintStream("c:\\ExceptionInfo.txt");                             ps.println(s);                               System.setOut(ps);                                    }                      catch(IOException e2)                      {                                 thrownew RuntimeException("创建异常日志文件失败");                      }                      e.printStackTrace(System.out);               }        } } 第三节 系统信息 System类中的static Properties getProperties() 方法可以得到系统信息。Properties类可以 和流相结合 import java.util.*; import java.io.*; class  GetProperties {        publicstatic void main(String[] args) throws IOException        {               Propertiesprop  = System.getProperties();               System.setOut(newPrintStream("systeminfo.txt"));               prop.list(System.out);        } }   第五章 流操作文件:File对象        创建, 删除, 判断, 获取, 文件列表-1, 文件列表-2, 列出目录下所有内容--递归, 列出目录下所有内容--带层次, importjava.io.*; 递归的英文是单词recursion 在列出目录的过程中,因为目录中还有目录,只要使用同一个列出目录功能的函数即可完成。在列出过中出现的还是目录的话,还可以再次调用本功能,也就是函数自身调用自身。这种表现形式,或者编程手法称为递归。 递归要限定循环条件,如if等。要不然会死循环;而且要注意递归次数,避免内存溢出。 下面是使用递归的思想列出一个目录下的所有文件和目录 class  RecursionDemo {        public static void main(String[] args)        {               File f = newFile("F:\\1115java\\javawork");                     showDir(f);               //showDirlist(f);        }               public static void showDir(File f)        {               int x = 0;               so.p("          "+f);               File[] files = f.listFiles();                    for(File f2 : files ){                      x++ ;                      //如果是目录,调用showDir方法.                      if(f2.isDirectory())                      {                             showDir(f2);                      }                      //如果不是目录,打印。                      else                             so.p("file"+x+":"+f2);               }        }        //插入层级目录        public static String getLevel(int level)        {               StringBuilder sb = newStringBuilder();               sb.append("|————");               for(int x = 0; x<level ;x++ )               {                      sb.intsert(0,"   ");               }        }          public static void showDirlist(File f)        {               int x = 0;               String[] strs = f.list();                         for(String str : strs ){                      x++ ;                                  so.p("strs"+x+" :"+str);               }        } } 删除带内容的目录, 创建java文件列表 第六章 Properties        Properties的继承结构 java.lang.Object> java.util.Dictionary<K,V> >   java.util.Hashtable<Object,Object>  >java.util.Properties   存取 存取配置文件 练习 第七章 其他流对象 PrintWriter, 合并流 SequenceInputStream有构造函数SequenceInputStream(Enumeration<?extends InputStream> e) Vector集合可以得到Enumeration 1、所以我们可以将文件封装成读取流        FileInputStream(File file)FileInputStream(String name);//InputStream是抽象的 2、再将读取流封装成Vector集合        Vector<FileInputStream> v = newVector<FileInputStream>()        v.add(new FileInputStream(String name)) 3、再由Vector集合的elements()方法 得到Enumeration        Enumeration<FileInputStream> e =v.elements(); 切割流 为了达到切割文件的目的,可一讲一个输出流切成几个部分 思路 1将要操作的对象封装成流对象 2建立一个字节数组,这个字节数组的大小将成为切割后单个文件的大小标准。 3建立循环,循环一次,建立一个流,写入规定大小的数据,然后关闭流 import java.io.*; class  slitFile {        public static voidmain(String[] args) throws Exception        {               splitFile();               System.out.println("HelloWorld!");        }        public static voidsplitFile()throws Exception        {               //1将操作对象封装成流对像               FileInputStreamfis = new FileInputStream("c:\\1.jpg");               //2               byte[] b = newbyte[1024*10];               //3               int count = 1;               int len = 0;               while((len= fis.read(b))!=-1)               {                      FileOutputStream fos = newFileOutputStream("c:\\"+(count++)+".part");                      fos.write(b,0,len);                      fos.close();               }        } } 对象的序列化 管道流 RandomAccessFile, 操作基本数据类型的流对DataStream, ByteArrayStream 第八章 编码 转换流的字符编码 字符编码 联通 练习

上一篇:algorithm头文件里的函数
下一篇:OpenGL函数思考-glLoadIdentity

相关文章

相关评论