IO流

来源:互联网 发布:万方数据库期刊查询 编辑:程序博客网 时间:2024/06/05 10:58

第7章 IO流

7.1 概述

1、java对数据的操作是通过流的方式,IO流就是用来处理设备之间的数据传输。

2、流的分类

        ⑴、按操作数据分:字节流和字符流

        ⑵、按流向分:输入流和输出流

3、字符流的由来:

计算机发展过程中,产生了Unicode码表,其中任何字符用2个字节表示,后来又升级为UTF-8,该码表是根据所要表示的字符的大小来决定字节数。在中国也有汉字GBK码表,但俩个码表中的字符所对应的编码可能会不一样,如果用UTF-8来解析GBK码表,会造成乱码。为了解决这问题,IO流技术基于字节流产生了字符流。它的好处在于字符流可以在内部融合编码表,即根据字节流来决定是用UTF-8,还是用GBK码表。

4、IO流常用基类

       字节流的抽象基类:InputStream,OutputStream

字符流的抽象基类:Reader,Writer

注:由这四个类派生出来的子类名称都是以其父类作为子类名的后缀。

7.2 字符流

7.2.1 FileWriter

1、FileWriter没有空参构造方法,因为必须要有文件,一创建就得有文件

2、需求:将一些文字存储到硬盘一个文件中

⑴、创建一个可以往文件中写入字符数据的字符输出流对象,即FileWriter, 而且该文件会被创建到指定目录下,即就必须明确该文件(用于存储数据的目的地)。如果该目录下有同名文件,则会被覆盖;如果没有,则会自动创建。

⑵、调用write方法,将字符串写入到流中

⑶、刷新流对象,将数据写入目的地中

⑷、关闭流资源,但是关闭之前,会刷新一次内部的缓冲中的数据,并将数据写入目的地中。和flush的区别在于flush刷新后,流可以继续使用,但close刷新后,流会被关闭。

publicclass FileWriterDemo {

privatestaticfinal StringLINE_SEPARATOR =System.

getProperty("line.separator");

   publicstaticvoid main(String[] args) {

      FileWriter fw = = new FileWriter("demo.txt");

          fw.write("abcde" + LINE_SEPARATOR +"hahaha");

          fw.flush();

          fw.close();// 关闭流,关闭资源。

      }

  }

}

3、IO异常处理方式   

publicclass ExceptionHandleDemo {

  publicstaticvoidmain(String[] args) {

      FileWriter fw = null;//如果不把它放外面,fw就变局部变量,会发生错误。

      try {

          // fw = newFileWriter("k:\\demo.txt");

          fw = new FileWriter("demo.txt");

          fw.write("abcde");

          fw.flush();

      } catch (IOException e) {

          System.out.print(e.toString());// FileNotFoundException

          // k:\demo.txt系统找不到指定的路径。

      } finally {

          if (fw !=null)

          // 当发生了FileNotFoundException时,就无法创建文件了,如果没有if (fw != null)就会发生NullPointerException

             try {

                 fw.close();//一定要执行

             } catch (IOException e) {

                 thrownewRuntimeException("关闭失败");

             }

      }

  }

}

4、文件的续写

publicclass FileContinueWriter {

    publicstaticvoidmain(String[] args) {

        FileWriter fw = null;

        try {

           // 如果构造方法中加入true,可以实现对文件进行续写;

           fw = new FileWriter("demo.txt",true);

           fw.write("hufei");

           fw.flush();

        } catch (IOException e) {

           e.printStackTrace();

        } finally {

           if (fw !=null)

               try {

                   fw.close();

               } catch (IOException e) {

                   e.printStackTrace();

               }

        }

    }

}

7.2.2 FileReader

1、读取流方式

、方式一

publicclass FileReaderDemo {

     //需求:读取一个文本文件。将读取到的字符打印到控制台

      publicstaticvoid main(String[] args) {

      // 创建一个文件读取字符数据的流对象,和指定名称的文件相关联。同时必须要明确被读取文件,如果不存在会发生FileNotFoundException异常

      FileReader fr = null;

      try {

          fr = new FileReader("buf.txt");

      } catch (FileNotFoundException e) {

          e.printStackTrace();

      }

      // 调用读取流对象的read方法,它一次读一个字符,而且会自动往下读

      // 用Reader中的read方法读取字符

      // int ch = fr.read();

      // System.out.println((char)ch);

      // int ch1 = fr.read();

      // System.out.println(ch1);

      // int ch2 = fr.read();

      // System.out.println(ch2);

      //-------以上代码太烂,下面的更简洁------------------------------

      int ch = 0;

      try {

          while ((ch = fr.read()) != -1) {//如果已达到文件末尾,返回-1

             System.out.print((char) ch);

          }

      } catch (IOException e) {

          e.printStackTrace();

      }

  }

}

      ⑵、方式二:通过字符数组进行读取

publicclass FileReaderDemo {

  publicstaticvoidmain(String[] args) {

      FileReader fr = null;

      try {

          fr = new FileReader("demo.txt");

      } catch (FileNotFoundException e) {

          e.printStackTrace();

      }

      // 定义一个字符数组,用于存储读到字符,该read(char[])返回的是读到字符的个数。

      char[] buf =newchar[1024];

      int ch = 0;

      try {

          while ((ch = fr.read(buf)) != -1) {

             System.out.print(new String(buf));

//注意:不要println,当数据超过1024时,有可能会在不该换行的地方换行

          }

      } catch (IOException e1) {

          e1.printStackTrace();

      } finally {

          try {

             fr.close();

          } catch (IOException e) {

             e.printStackTrace();

          }

      }

  }

}

7.2.3字符缓冲区

缓冲区的出现提高了对数据的读写效率,所以在创建缓冲区之前,必须要先有流对象分类

1、BufferedWriter字符写入缓冲区

publicclass BufferWriterDemo {

    publicstaticvoidmain(String[] args)throws IOException {

        // 创建一个字符写入流对象

        FileWriter fw = new FileWriter("buffer.txt");

        //为了提高字符写入流效率,加入缓冲技术。只要将需要被提高效率的流对象作为参数传递给缓冲区的构造方法即可

        BufferedWriter bufw = new BufferedWriter(fw);

        for (int i = 0; i < 5; i++) {

           bufw.write("dfja" + i);

           bufw.newLine();

// 该方法在任何系统都有用,其换行的作用,其原理就是bufw.write("\r\n")

           bufw.flush();// 只要用到缓冲区就要记得刷新

        }

        bufw.close();

        // fw.close();不需要关闭,因为关闭缓冲区就是关闭缓冲区中的流对象

    }

}

2、BufferedReader 字符读取缓冲区

    该缓冲区提供一个一次读一行的方法readline,方便对文本的获取。当返回null时,表示读到文件末尾。

publicclass BufferReaderDemo {

   publicstaticvoid main(String[] args) throws IOException {

      //创建一个读取流对象和文件相关联

      FileReader fr = new FileReader("buf.txt");//为了提高效率。加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造方法

      BufferedReader bufr = new BufferedReader(fr);

      String line = null;//

       while((line=bufr.readLine())!=null){//一行一行的读入,返回包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null。readLine方法的原理:无论是读一行,或读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终使用的还是read方法一次读一个的方法。

          System.out.println(line);

      }

  }

}

3、MyBufferedReader

    明白了 bufferReader类中特有方法readline的原理后,可以自定义一个包含一个功能和readline一致的方法来模拟一下BufferReader 字符读取缓冲区。该缓冲区提供一个一次读一行的方法readline,方便对文本的获取。

publicclass MyBufferedReader {

    private FileReaderr;//BufferedReader是FileReader的增强

   MyBufferedReader(FileReader r){//因为BufferedReader是基于read方法的,而read方法是FileReader的,于是就应该把FileReader传进去

      this.r = r;

    }

   public String myReadLine()throws IOException{  

//定义一个临时容器,原BufferReader封装的是字符数组

          //为了演示方便,定义一个StringBuffer容器,因为最终还是要将数据变成字符串

           StringBuilder sb =new StringBuilder();

           int ch = 0;

           while ((ch =r.read())!= -1){

             if(ch=='\r')

                 continue;

             if(ch=='\n')

                 return sb.toString();

             sb.append((char)ch);

           }

           if(sb.length()!=0)//只有缓冲区中有数据,就将其读出来

               returnsb.toString();

           returnnull;//如果已到达流末尾,则返回 null

    }

         // 他们的存在只是在继承Reader类后,需要复写read和close俩个抽象方法

    publicint read(char[] cbuf, int off, int len)throwsIOException {

           return r.read(cbuf, off, len);

   }

    publicvoid myClose()throwsIOException {//谁调用谁处理

           r.close();// 缓冲区的存在是为了提高FileReader的效率,真正操作的是FileReader的方法,所以只要把它关了就OK了;

   }

}

class MyBufferReaderDemo{

    publicstaticvoid main(String[] args)throws IOException{

       FileReader fr = newFileReader("buf.txt");

       MyBufferedReader myBuf = newMyBufferedReader(fr);

       String line = null;

        while((line = myBuf.myReadLine())!=null){

           System.out.println(line);

        }

       myBuf.myClose();

     }

}

7.2.4、DecoratorPattern:装饰模式

1、readLine方法的出现增强了read方法的功能,如何增强功能?将被增强的对象传给增强类。当想要对已有的对象进行功能增强时,可以定义类,将已有的对象传入,基于已有的功能,并提供加强功能,那么自定义的该类成为装饰类。

装饰类通常会通过构造方法接受被装饰的对象,比基于被装饰的对象的功能,提供更强的功能。

2、代码的体现

 publicclass BufferReaderDemo {

    publicstaticvoidmain(String[] args)throws IOException {

        FileReader fr = new FileReader("buf.txt");

        BufferedReader bufr = new BufferedReader(fr);

        String line = null;//

        while ((line = bufr.readLine()) !=null) {

           System.out.println(line);

        }

    }

}

3、装饰与继承的区别

①、装饰类的来源及表现形式

装饰优化前的体系

MyReader//专门用于读取数据的类

         !--MyTextReader 因为效率低

            !--MyBufferTextReader所以利用缓冲技术

         !--MyMediaReader

            !--MyBuffeMediaReader

         !--MyDataReader 后来又加入了读Data的类

            !—MyBufferDataReader 他也要增强

    在后期,数据越来越多,体系逐渐庞大,就会变得臃肿。但是它们的技术都一样,即缓冲技术。于是我们直接定义一个缓冲区,谁用谁进来,就对谁进行增强。

   class MyBufferReader{

         MyBufferReader(MyTextReader text){}

         MyBufferReader(MyMediaReader Media){}

     }

    上面这个类的扩展性很差,找到其参数的共同类型,通过多态的形式,可以提高扩展性

 class MyBufferReader extends MyReader{

      private MyReader r;

      MyBufferReader(MyReader r)

      {}

 }

通过装饰优化后的体系

 MyReader

     !--MyTextReader

     !--MyMediaReader

     !--MyDataReader

     !—MyBufferReader

②、装饰与继承的区别

     装饰模式比继承要灵活,避免了继承的臃肿,而且降低了类与类之间的关系。

注意:装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过是提供了更强的功能。所以装饰类与被装饰类通常是同属于一个体系中的

7.2.5 行号

1、常见方法

publicclass LineNumberReaderDemo {

    publicstaticvoidmain(String[] args)throws IOException {

        FileReader fr = new FileReader("ArrayListTest.java");

        LineNumberReader lnr = new LineNumberReader(fr);

        String line = null;

        lnr.setLineNumber(10);

        while ((line = lnr.readLine()) !=null) {

           System.out.println(lnr.getLineNumber() +":" + line);

        }

        lnr.close();

    }

}

2、自定义行号的方法

class MyLineNumberReader {

    privateintlineNumber;

    privateReaderr;

    MyLineNumberReader(Reader r) {

        this.r = r;

    }

    publicString myReadLine()throws IOException {

        lineNumber++;

        StringBuilder sb = new StringBuilder();//

        int ch = 0;

        while ((ch =r.read()) != -1) {

           if (ch =='\r')

               continue;

           if (ch =='\n')

               return sb.toString();

           sb.append((char) ch);

        }

        if (sb.length() != 0)//只有缓冲区中有数据,就将其读出来

           return sb.toString();

        returnnull;

    }

    publicint getLineNumber() {

        returnlineNumber;

    }

    publicvoid setLineNumber(int lineNumber) {

        this.lineNumber =lineNumber;

    }

}

publicclass MyLineNumberReaderDemo1 {

    publicstaticvoidmain(String[] args)throws IOException {

        FileReader fr = new FileReader("ArrayListTest.java");

        MyLineNumberReader mylnr = new MyLineNumberReader(fr);

        String line = null;

        mylnr.setLineNumber(10);

        while ((line = mylnr.myReadLine()) !=null) {

           System.out.println(mylnr.getLineNumber() +":" + line);

        }

    }

}

7.3 字节流

7.3.1 字节流的输入/出

基本操作与字符流类相同,但它不仅可以操作字符,还可以操作其他媒体文件。InputStream类是

字节输入流的抽象类,OutputStream类是字节输出流的抽象类,是所有字节流输入流的父类,下面是

InputStream类和OutputStream的具体层次结构

                             

publicclass FileIOStreamDemo {

    publicstaticvoidmain(String[] args)throws IOException {

        writeFile();

        readFile1();

        readFile2();

        readFile3();

    }

    privatestaticvoidreadFile3()throws IOException {

        FileInputStream fis = new FileInputStream("fos.txt");

        byte[] buf =newbyte[fis.available()];

        // available()是用来计算字节数,所以可以用来确定缓冲区大小,即可以定义一个刚刚好的缓冲区,不用再循环,但如果数据太多,不建议使用该方法。

        fis.read(buf);

        System.out.println(new String(buf));

        fis.close();

    }

    privatestaticvoidreadFile2()throws IOException {

        FileInputStream fis = new FileInputStream("fos.txt");

        byte[] buf =newbyte[1024];

        int ch = 0;

        while ((ch = fis.read(buf)) != -1) {

           System.out.println(new String(buf, 0, ch));

        }

        fis.close();

    }

    privatestaticvoidreadFile1()throws IOException {

        FileInputStream fis = new FileInputStream("fos.txt");

        int ch = 0;

        while ((ch = fis.read()) != -1) {

           System.out.println((char) ch);

        }

    }

    privatestaticvoidwriteFile()throws FileNotFoundException, IOException {

        FileOutputStream fos = new FileOutputStream("fos.txt");

        fos.write("abcfd".getBytes());//将字符串变成字节数组

  // fos.flush();为什么不需要刷新就能写入?字符流之所以需要,是因为有些字符需要查

编码表,如中文,所以现存在缓冲区(该缓冲区就是字节流的缓冲区)中,查完表后,利用刷新的技术将数据写入。而字节流不需要查表,所以不需要刷新。

        fos.close();

    }

}

7.3.2 字节流缓冲区

如果不和255进行“按位与”运算,结果是0个字节。为什么打印的0个字节呢?

因为map3文件是以字节存储,就会读取到11111111,即-1,而返回的类型是int,所以b会自动提升为

int型,当然它依然还是-1,所以程序就会停止读取。为什么要用int接收呢?为了避免碰到11111111的情况,所以将类型提升为int的同时,在除此8位以外,都补0.如此即保留了原数据没变化,又能保证不会出现11111111的情况。那么如何补0呢?只需返回值&255。

class MyBufferedInputStream {

    privateInputStreamin;

    privatebyte[]buf = newbyte[1024];

    privateintcount = 0,pos = 0;

    MyBufferedInputStream(InputStream in) {

        this.in = in;

    }

    // 一次对一个字节,从缓冲区获取

    publicint myRead()throws IOException {

        // 通过in对象读取硬盘上的数据,并存储在buf中

        if (count == 0) {

           pos = 0;

           count = in.read(buf);

           byte b =buf[pos];

           count--;

           pos++;

           return b & 255;

        } elseif (count > 0) {

           byte b =buf[pos];

           count--;

           pos++;

           return b & 255;

        }

        return -1;

    }

    publicvoid Myclose()throws IOException {

        in.close();

    }

}

7.3.3 用缓冲区技术拷贝Mp3

publicclass CopyMp3 {

    publicstaticvoidmain(String[] args)throws IOException {

        copyMp3_1();

        copyMp3_2();

        long start = System.currentTimeMillis();

        // 自定义缓冲区对象的方法

        copyMp3_3();

        long end = System.currentTimeMillis();

        System.out.println(end - start);//获取复制该文件的复制时间

    }

    privatestaticvoidcopyMp3_3()throws IOException {

       // MyBufferedInputStream就是上一节的那个

        MyBufferedInputStream  bufis = new MyBufferedInputStream(

new FileInputStream("D:\\北京北京.mp3"));

        BufferedOutputStream  bufos = new BufferedOutputStream(

                                   new FileOutputStream("D:\\北京北京copy3.mp3"));

        int len = 0;

        while ((len = bufis.myRead()) != -1) {

           bufos.write(len);

           // myRead()方法将数据提升,而write再讲最低的字节写出去,保证原数据不变

        }

        bufos.close();

        bufis.Myclose();

    }

    privatestaticvoidcopyMp3_2()throws IOException {

        BufferedInputStream bufis = new BufferedInputStream(

               new FileInputStream("D:\\北京北京.mp3"));

        BufferedOutputStream bufos = new BufferedOutputStream(

               new FileOutputStream("D:\\北京北京copy2.mp3"));

        int len = 0;

        while ((len = bufis.read()) != -1) {

           bufos.write(len);

        }

        bufos.close();

        bufis.close();

    }

    privatestaticvoid copyMp3_1()throws FileNotFoundException, IOException {

        FileInputStream fis = new FileInputStream("D:\\北京北京.mp3");

        FileOutputStream fos = new FileOutputStream("D:\\北京北京copy1.mp3");

        byte[] buf =newbyte[1024];

        int len = 0;

        while ((len = fis.read(buf)) != -1) {

           fos.write(buf, 0, len);

        }

        fos.close();

        fis.close();

    }

}

7.3.4 键盘录入

1、读取键盘录入:System.out:对应的是标准的输出设备

System.in:对应的是标准的输入设备

    2、需求:通过键盘录入一行数据后,就将该行数据进行打印 如果录入over,那么停止录入。

    3、停止录入的方式:自定义标记,或ctrl+c

publicclass ReadIn {

  publicstaticvoidmain(String[] args)throws IOException {

      InputStream in = System.in;

      StringBuilder sb = new StringBuilder();

      while (true) {

          int by = in.read();// read方法是阻塞式方法,如果没有读到数据就不会停

          if (by =='\r')

             continue;

          if (by =='\n') {

             String s = sb.toString();

             if ("over".equals(s))

                 break;

             System.out.print(s.toUpperCase());

             sb.delete(0, sb.length());

          }

          sb.append((char) by);

      }

  }

}

7.3.5 转换流

1、由来:通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。也就是rea- dLine方法。能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?readLine方法是Buffere -dReader类中的方法,而键盘录入的read方法是字节流InputStream的方法,那么能不能将字节流转成字符流在使用字符流缓冲区的readLine方法呢?

2、读取转换流:InputStreamReader 是字节流通向字符流的桥梁

、方式一

①获取键盘录入对象

             InputStream in =System.in;

           ② 将字节流对象转成字符流对象,使用的转换流是InputStreamReader

             InputStreamReaderisr = new InputStreamReader(in);

      ③为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader

             BufferedReaderbufr = new BufferedReader(isr);

        ⑵方式二:键盘录入最常见的写法

            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

3、写入转换流:OutputStreamWriter 是字符流通向字节流的桥梁

        OutputStreamout = System.out;

        OutputStreamWriterosw = new OutputStreamWriter(out);

        BufferedWriterbufw = new BufferedWriter(osw);

7.3.6 流操作规律

1、流操作通过三个明确来完成

       ⑴、明确源和目的

           源:输入流:InputStream、Reader

           目的:输出流:OutputStream、Writer

       ⑵、明确操作的数据是否是纯文本

           是:字符流

           不是:字节流

       ⑶、当体系明确后,在明确要使用哪个具体的对象

           源设备:内存(ArrayStream)、硬盘(FileStream)、键盘(System.in)

           目的设备:内存(ArrayStream)、控制台(System.out)、硬盘(FileStream)

    2、需求

       ⑴、将一个文本文件中的数据存储到另一个文件中,复制文件;

           ①、源:因为是输入流,所以要读取流,用InputStream或Reader

                  纯文本:是,所以选择Reader。这样体系就明确了

               接下来明确要使用该体系中的哪个对象。

                  明确设备:硬盘,

              Reader体系中可以操作文件的对象是FileReader    

               是否需要提供效率?需要,加入Reader体系中缓冲区BufferedReader 

                 FileReader fr = newFileReader("a.txt");

                 BufferedReader  bufr = new BufferedReader(fr);

          ②、目的:OutputStream或Writer

               是不是纯文本:是,所以选择Writer

               明确设备:硬盘 ,一个文件

               Writer体系中可以操作文件的对象是FileWriter

               是否需要提供效率?需要,加入Writer体系中缓冲区BufferedWriter            

                 FileWriter fw = newFileWriter("b.txt");

                 BufferedWriter  bufw = new BufferedWriter(fw);

⑵、需求:将键盘录入的数据保存到一个文件中,这个需求中有源和目的存在。那么分别分析

         ①、源:用InputStream或Reader

             是不是纯文本:是,所以选择Reader。这样体系就明确了

             设备:键盘对应的对象是System.in,选择Reader吗?System.in对应的不是字节流吗?

             为了操作键盘的文本数据方便,转换字符流按照字符串操作是最方便的。 所以既然明确了Reader,那么就将System.in转换Reader。用了Reader体系中的转换流InputStreamReader

         InputStreamReader isr = newInputStreamReader(System.in);

          需要提高效率吗?需要! BufferedReader

            BufferedReader  bufr = new BufferedReader(isr);

         ②、目的:OutputStream或Writer

              是不是纯文本:是,所以选择Writer

              明确设备:硬盘 ,一个文件

             Writer体系中可以操作文件的对象是FileWriter

                 FileWriter fw = newFileWriter("c.txt");

              是否需要提供效率?需要,加入Writer体系中缓冲区BufferedWriter            

                 BufferedWriter  bufw = new BufferedWriter(fw);       

    扩展一下,想要把录入的数据按照指定的编码表(UTF-8),将数据存储到文件中

    ①、 目的:OutputStream或Writer

         是不是纯文本:是,所以选择Writer

         明确设备:硬盘 ,一个文件

     Writer体系中可以操作文件的对象是FileWriter,但是FileWriter使用的是默认编码表,但存储时,需要加入指定的编码表,而指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。而该转换流对象要接收一个字节输出流,而且还可以操作的文件的字节输出流FileOutputStream。

    OutputStreamWriter osw =newOutputStreamWriter(newFileOutputStream("d.txt"),"UTF-8");  

     是否需要提供效率?需要,BufferedWriter            

     BufferedWriter  bufw = new BufferedWriter(osw);

     所以,记住,转换流什么时候使用?字符和字节之间的桥梁。通常,涉及到字符编码转换时,需要用到转换流。

3、代码示例

publicclass OperateReguler {

    publicstaticvoidmain(String[] args)throws IOException {

        // 键盘录入最常见的写法

        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

        OutputStream out = System.out;

        OutputStreamWriter osw = new OutputStreamWriter(out);

        BufferedWriter bufw = new BufferedWriter(osw);

        String line = null;

        while ((line = bufr.readLine()) !=null) {

           if ("over".equals(line))

               break;

           bufw.write(line.toUpperCase());

           bufw.newLine();

           bufw.flush();

        }

        bufw.close();

    }

}

7.3.7 异常日志及系统信息

1、异常日志

printStackTrace():将此 throwable及其追踪输出至标准错误流。

printStackTrace(PrintStream s):将此 throwable及其追踪输出到指定的输出流。

代码示例:

publicclass ExceptionInfo {

    /**

     * 如何将异常信息存放到一个文件中

     *log4j工具

     */

    publicstaticvoidmain(String[] args)throws IOException {

        try{

           int[] arr =newint[2];

           System.out.println(arr[3]);

        }catch(Exception e){

           try {

               //加入发生异常的时间

               Date d = new Date();

               //自定义时间格式

               SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

               String s =sdf.format(d);               

               PrintStream ps = new PrintStream("exeception.log");

               //ps.write(d.toString().getBytes());

               ps.println(s);

               System.setOut(ps);

           } catch (FileNotFoundException e1) {

               System.out.println("日志文件输出失败");

           }

           e.printStackTrace(System.out);                 

        }

    }

}

2、获取系信息

list(PrintStream out):将属性列表输出到指定的输出流

publicclass SystemDemo {

    publicstaticvoidmain(String[] args) {

        Properties prop = System.getProperties();

        try {

           Date d = new Date();

           SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

           String s = sdf.format(d);

           PrintStream ps =new PrintStream("System.txt");

           ps.println(s);

           prop.list(ps);

        } catch (FileNotFoundException e) {

           e.printStackTrace();

        }

    }

}

原创粉丝点击