黑马程序员—字节流+字符流缓冲区(装饰设计)+转换流+IO流操作规律+异常日志+系统信息列表输出

来源:互联网 发布:linux 重启后不能远程 编辑:程序博客网 时间:2024/06/07 13:50

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

1. 字符流缓冲区

字符缓冲区的原理

其实就是将数组进行封装。变成对象后,方便于对缓冲区的操作,提高效率。并提供了对文本便捷操作的方法。readLine( )&newLine( )

 

缓冲区的基本思想:就是对要处理的数据进行临时存储。譬如购物车以及篮子。

原理:为了提高字符写入流效率,减少频繁的操作,给读取流对象和写入流对象提供中转站,相对于来回跑的麻烦,利用缓冲区的容量,可以一边先存储,满了后再写入的方式,这样就提高了效率。

BufferedWriter的特有方法:newLine():跨平台的换行符。

BufferedReader的特有方法:readLine():一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null(返回的字符是不带回车符的)

在使用缓冲区对象时,要明确,缓冲的存在是为了提高流的操作效率而出现的,所以在建立缓冲区对象时,要先有流对象存在。其实缓冲内部就是在使用流对象的方法,只不过加入了数组对数据进行了临时存储,为了提高操作数据的效率

 

BufferedWriter实例:

/*

缓冲区的出现是为了提高流的操作效率而出现的。

 

所以在创建缓冲区之前,必须要先有流对象。

 

该缓冲区中提供了一个跨平台的换行符。

newLine();

 

*/

class  BufferedWriterDemo{public static void main(String[] args) throws IOException{//创建一个字符写入流对象。FileWriter fw = new FileWriter("buf.txt"); //为了提高字符写入流效率。加入了缓冲技术。//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。BufferedWriter bufw = new BufferedWriter(fw); //加循环(写一次刷一次)的原因是:防止意外断电后内存清空,导致数据没保存成功for(int x=1; x<5; x++){bufw.write("abcd"+x);bufw.newLine();//跨平台的换行符bufw.flush();} //记住,只要用到缓冲区,就要记得刷新。//bufw.flush(); //其实关闭缓冲区,就是在关闭缓冲区中的流对象。bufw.close();}}


 

BufferedReader实例:

/*

字符读取流缓冲区:

该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。

当返回null时,表示读到文件末尾。

 

readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。

*/

 

import java.io.*; class  BufferedReaderDemo{public static void main(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.print(line);} bufr.close();}}


 

通过缓冲区复制文本文件

/*

通过缓冲区复制一个.java文件。

 

*/

import java.io.*; class  CopyTextByBuf{public static void main(String[] args) {BufferedReader bufr = null;BufferedWriter bufw = null; try{bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt")); String line = null; while((line=bufr.readLine())!=null){bufw.write(line);bufw.newLine();//要加换行,因为readLine()没有返回换行符bufw.flush(); }}catch (IOException e){throw new RuntimeException("读写失败");}finally{try{if(bufr!=null)bufr.close();}catch (IOException e){throw new RuntimeException("读取关闭失败");}try{if(bufw!=null)bufw.close();}catch (IOException e){throw new RuntimeException("写入关闭失败");}}}}


 

 

其实缓冲区中的该方法,用的还是与缓冲区关联的流对象的read方法,只不过,每一次读到一个字符,先不进行具体操作,而是进行临时存储。当读到回车标记时,将临时容器中的数据一次性返回。----->StringBuilder调用了buff.read()将缓冲区中的数据存储到了该容器中。

缓冲区的read()和流对象的read()方法的区别?

流对象:从目的地一次读取一个字符

缓冲区:通过流对象的read([])将一批数据读取到缓冲数组,然后在数组中一次取一个字符,内存比硬盘操作要高效。

 

自定义缓冲区MyBufferedReader(装饰设计模式)

/*

明白了BufferedReader类中特有方法readLine的原理后,

可以自定义一个类中包含一个功能和readLine一致的方法。

来模拟一下BufferedReader

*/

import java.io.*;class MyBufferedReader extends Reader{private Reader r;MyBufferedReader(Reader r){this.r = r;} //可以一次读一行数据的方法。public String myReadLine()throws IOException//定义的是功能,出现问题应该标示出去,让调用者处理异常。谁调用谁处理{//定义一个临时容器。原BufferReader封装的是字符数组。//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1){if(ch=='\r')continue;if(ch=='\n')//当最后一行没有换行符时,不返回,丢失一行数据,应该在最后增加返回语句return sb.toString();//将数据返回为Stringelsesb.append((char)ch);} if(sb.length()!=0)return sb.toString();return null;} public void myClose()throws IOException{r.close();} /*覆盖Reader类中的抽象方法。 */public int read(char[] cbuf, int off, int len) throws IOException{return r.read(cbuf,off,len) ;} public void close()throws IOException{r.close();}} class  MyBufferedReaderDemo{public static void main(String[] args) throws IOException//应该try,但是为了演示方便{FileReader fr = new FileReader("buf.txt"); MyBufferedReader myBuf = new MyBufferedReader(fr); String line = null; while((line=myBuf.myReadLine())!=null){System.out.println(line);}myBuf.myClose();}}


 

装饰设计模式

/*

装饰设计模式:

当想要对已有的对象进行功能增强时,

可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。

那么自定义的该类称为装饰类。

 

装饰类通常会通过构造方法接收被装饰的对象。

并基于被装饰的对象的功能,提供更强的功能。

 

注意:

装饰类中的加强功能里面调用了被装饰类的功能,装饰类的实例对象不能直接调用被装饰类的功能。

 

*/

class Person{public void chifan(){System.out.println("吃饭");}} class SuperPerson {private Person p ;SuperPerson(Person p){this.p = p;}public void superChifan(){System.out.println("开胃酒");p.chifan();System.out.println("甜点");System.out.println("来一根");}} class  PersonDemo{public static void main(String[] args) {Person p = new Person(); //p.chifan(); SuperPerson sp = new SuperPerson(p);sp.superChifan(); }}


 

装饰设计模式和继承的区别

1. 装饰模式比继承要灵活。避免了继承体系臃肿。

而且降低了类于类之间的关系。

 

2. 装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。不是继承中的覆盖方法,所以装饰类和被装饰类通常是都属于一个体系中的。

 

3. 从继承结构转为组合结构

 

/*

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

|--MyTextReader

|--MyBufferTextReader

|--MyMediaReader

|--MyBufferMediaReader

|--MyDataReader

|--MyBufferDataReader

问题:缓冲类代码臃肿,扩展性差

 

class MyBufferReader

{

MyBufferReader(MyTextReader text)

{}

MyBufferReader(MyMediaReader media)

{}

}

上面这个类扩展性很差。

找到其参数的共同类型。通过多态的形式。可以提高扩展性。

 

class MyBufferReader extends MyReader

{

private MyReader r;

MyBufferReader(MyReader r)

{}

}

 

 

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

|--MyTextReader

|--MyMediaReader

|--MyDataReader

|--MyBufferReader

 

以前是通过继承将每一个子类都具备缓冲功能。

那么继承体系会复杂,并不利于扩展。

 

现在优化思想。单独描述一下缓冲内容。

将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。

这样继承体系就变得很简单。优化了体系结构。

 

 

*/

 

LineNumberReader

概念:

跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。

默认情况下,行编号从 开始。该行号随数据读取在每个行结束符处递增,并且可以通过调用 setLineNumber(int) 更改行号。

 

构造方法摘要

LineNumberReader(Reader in) 
          使用默认输入缓冲区的大小创建新的行编号 reader。in - 提供底层流的 Reader 对象

 

LineNumberReader(Reader in, int sz) 
          创建新的行编号 reader,将字符读入给定大小的缓冲区。sz - 指定缓冲区大小的 int 值

 

 

class LineNumberReaderDemo 

{

public static void main(String[] args)throws IOException 

{

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

 

LineNumberReader lnr = new LineNumberReader(fr);

 

String line = null;

lnr.setLineNumber(100);

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

{

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

}

 

lnr.close();

}

}

 

自定义MyineNumberReader

//练习:模拟一个带行号的缓冲区对象。

 

import java.io.*;class MyLineNumberReader extends MyBufferedReader//继承MyBufferedReader类{private int lineNumber;MyLineNumberReader(Reader r){super(r);} public String myReadLine()throws IOException{ lineNumber++;return super.myReadLine();}public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;}} /*与父类很多重复的代码,所以直接继承父类,复写方法;class MyLineNumberReader {private Reader r;private int lineNumber;MyLineNumberReader(Reader r){this.r = r;} public String 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();elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;} public void myClose()throws IOException{r.close();}}*/class  MyLineNumberReaderDemo{public static void main(String[] args) throws IOException{FileReader fr = new FileReader("copyTextByBuf.java"); MyLineNumberReader mylnr = new MyLineNumberReader(fr); String line = null;mylnr.setLineNumber(100);while((line=mylnr.myReadLine())!=null){System.out.println(mylnr.getLineNumber()+"::"+line);} mylnr.myClose();}}


 

4. 字节流File读写操作

实例1

/*

字符流:

FileReader

FileWriter

 

BufferedReader

BufferedWriter

 

字节流:

InputStream  OutputStream

FileOutputStream()只能生成文件,不能生成文件夹

 

long

skip(long n) 
          从输入流中跳过并丢弃 n 个字节的数据。

int

read() 
          从此输入流中读取一个数据字节。

 int

read(byte[] b) 
          从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。

 int

read(byte[] b, int off, int len) 
          从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。

 

 

需求,想要操作图片数据。这时就要用到字节流。

复制一个图片.

 

 

*/

import java.io.*;class  FileStream{public static void main(String[] args) throws IOException{readFile_3();} public static void readFile_3()throws IOException{FileInputStream fis = new FileInputStream("fos.txt");//int num = fis.available();//返回的是文件的大小(包含反斜杠等字符)byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。//此方法慎用,数据太大的,内存可能溢出。还是以readFile_2()为常用。 fis.read(buf); System.out.println(new String(buf)); fis.close();}  public static void readFile_2()throws IOException{FileInputStream fis = new FileInputStream("fos.txt"); byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf))!=-1){System.out.println(new String(buf,0,len));} fis.close();}  public static void readFile_1()throws IOException{FileInputStream fis = new FileInputStream("fos.txt"); int ch = 0; while((ch=fis.read())!=-1){System.out.println((char)ch);} fis.close();} public static void writeFile()throws IOException{FileOutputStream fos = new FileOutputStream("fos.txt"); fos.write("abcde".getBytes()); fos.close(); }}


 

实例2-COPY图片

 

/*

字符流:

FileReader

FileWriter

 

BufferedReader

BufferedWriter

 

字节流:

InputStream  OutputStream

 

需求,想要操作图片数据。这时就要用到字节流。

复制一个图片.

 

*/

import java.io.*;class  test{public static void main(String[] args) throws IOException{FileInputStream fi=null;FileOutputStream fo = null;try{fi= new FileInputStream("c:/jietu.png");fo =new FileOutputStream("c:/jietu_copy.png"); byte ch[]= new byte[1024]; int len=0; while((len=fi.read(ch))!=-1) { fo.write(ch,0,len); }}catch(IOException e){throw new RuntimeException("复制文件失败");}finally{try{if(fi!=null){fi.close();}}catch(IOException e){throw new RuntimeException("读取关闭失败");}try{if(fo!=null){fo.close();}}catch(IOException e){throw new RuntimeException("写入关闭失败");}}}}


 

字节流缓冲区

/*

字节流缓冲区:

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

 

7.构造BufferedInputStream的合适参数是哪个? CA 

A BufferedInputStream// BufferedInputStream(InputStream in, int size)

 

B BufferedOutputStream 

 

C FileInputStream 

 

D FileOuterStream 

 

E. File

 

演示mp3的复制。通过字节流缓冲区。

BufferedOutputStream

BufferedInputStream

 

*/

import java.io.*;class  CopyMp3{public static void main(String[] args) throws IOException{long start = System.currentTimeMillis();copy_2();long end = System.currentTimeMillis(); System.out.println((end-start)+"毫秒");} public static void copy_2()throws IOException{MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));int by = 0; //System.out.println("第一个字节:"+bufis.myRead()); while((by=bufis.myRead())!=-1){bufos.write(by);} bufos.close();bufis.myClose();} //通过字节流的缓冲区完成复制。public static void copy_1()throws IOException{BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));int by = 0; while((by=bufis.read())!=-1){bufos.write(by);} bufos.close();bufis.close();}}


 

自定义字节流的缓冲区-readwrite的特点

 

public class myBuf//装饰设计模式{private InputStream in;private byte buf[] = new byte[1024*5];//缓冲区private int pos=0;//定义指针 private int count=0;//定义计数器myBuf(InputStream in){this.in=in;}//一次读一个字节,8个二进制位,从缓冲区(字节数组)获取。public int myread() throws IOException{//通过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;//将前面的3个字节的二进制问1换成0}else if(count >0){byte b= buf[pos];count--;pos++;return b&0xff;//十六进制的255表现形式}return-1;}public void myclose() throws IOException{in.close();}}

/*

一次读取一个字节,8个二进制位;

11111111-111111110000000000101001001010100101010010101001010

 

 

byte: -1  --->  int : -1;

00000000 00000000 00000000 11111111  (255)

提升为:

11111111 11111111 11111111 11111111

 

11111111  -->提升了一个int类型 那不还是-1吗?是-1的原因是因为在81前面补的是1导致的。

那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。

怎么补0呢?

 

 11111111 11111111 11111111 11111111                        

&00000000 00000000 00000000 11111111 

------------------------------------

 00000000 00000000 00000000 11111111 

 

1的二进制:0000-0001

 

1111-1110

000000001

1111-1111  -1的二进制:

 

 

结论:为什么read()返回类型是int不是byte呢?

字节流的读一个字节的read方法为什么返回值类型不是byte,而是int

因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.

那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。

所以,为了避免这种情况将读到的字节进行int类型的提升。

并在保留原字节数据的情况前面了补了240,变成了int类型的数值。

 

而在写入数据时,write只写该int类型数据的最低8位,前面多于的补0会被忽略掉;

*/

 

读取键盘录入(单个字节录入)

 

/*

读取键盘录入。

System.out:对应的是标准输出设备,控制台。

System.in:对应的标准输入设备:键盘。

 

 

需求:

通过键盘录入数据。

当录入一行数据后,就将该行数据进行打印。

如果录入的数据是over,那么停止录入。

 

*/

import java.io.*;class  test{public static void main(String[] args) throws IOException{InputStream in = System.in;StringBuilder sb = new StringBuilder();while(true){int i=in.read();if(i=='\r')continue;if(i=='\n'){String s = sb.toString();if("over".equals(s))break;System.out.println(s.toUpperCase());sb.delete(0, sb.length());//缓冲区应清空}elsesb.append((char)i);}}}


5. 转换流

转换流

l InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。

OutputStreamWriter: 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。

转换流的由来

• 字符流与字节流之间的桥梁

• 方便了字符流与字节流之间的操作

转换流的应用

• 字节流中的数据都是字符时,转成字符流操作更高效。

•可以指定字符编码表: 当用不同的编码进行保存或读取文件时,就用到转换流

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

 

常用读取键盘录入--读取,写入转换流(字节流~字符流

/*

读取键盘录入。

System.out:对应的是标准输出设备,控制台。

System.in:对应的标准输入设备:键盘。

 

 

需求:

通过键盘录入数据。

当录入一行数据后,就将该行数据进行打印。

如果录入的数据是over,那么停止录入。

 

*/

import java.io.*;class  test{public static void main(String[] args) throws IOException{//获取键盘录入对象。//InputStream in = System.in; //将字节流对象转成字符流对象,使用转换流。InputStreamReader//InputStreamReader isr = new InputStreamReader(in); //为了提高效率,将字符流进行缓冲区技术高效操作。使用BufferedReader //BufferedReader bufr = new BufferedReader(isr);  //键盘的最常见写法。BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));//OutputStream out = System.out;//OutputStreamWriter osw = new OutputStreamWriter(out);//BufferedWriter bufw = new BufferedWriter(osw);//键盘的最常见写法。BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));String line =null;while((line=buf.readLine())!=null){if("over".equals(line))break;/*bw.write(line.toUpperCase());bw.newLine();bw.flush();*/System.out.println(line.toUpperCase());}buf.close();}} 


6. IO流操作规律

 

/*

1,

源:键盘录入。

目的:控制台。

 

2,需求:想把键盘录入的数据存储到一个文件中。

源:键盘。

目的:文件。

System.out改为:new FileOutputStream("out.txt");

 

3,需求:想要将一个文件的数据打印在控制台上。

源:文件。

目的:控制台。

System.in改为:new FileInputStream("CopyMp3.java");

 

 

流操作的基本规律:

最痛苦的就是流对象有很多,不知道该用哪一个。

 

通过三个明确来完成。先确认体系,再找对象

 

1,明确源和目的。

源:输入流。InputStream  Reader

目的:输出流。OutputStream  Writer

2,操作的数据是否是纯文本。

是:字符流。

不是:字节流。 

 

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

通过设备来进行区分:

源设备:内存,硬盘。键盘

目的设备:内存,硬盘,控制台。

 

1,将一个文本文件中数据存储到另一个文件中。复制文件。 

源:因为是源,所以使用读取流。InputStream Reader 

是不是操作文本文件。

是!这时就可以选择Reader

这样体系就明确了。

 

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

明确设备:硬盘。上一个文件。

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

 

是否需要提高效率:是!。加入Reader体系中缓冲区 BufferedReader.

 

 

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

BufferedReader bufr = new BufferedReader(fr);

 

 

目的:OutputStream Writer

是否是纯文本。

是!Writer

设备:硬盘,一个文件。

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

是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter

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

BufferedWriter bufw = new BufferedWriter(fw);

 

 

练习:将一个图片文件中数据存储到另一个文件中。复制文件。要按照以上格式自己完成三个明确。

 

 

---------------------------------------

 

2,需求:将键盘录入的数据保存到一个文件中。

这个需求中有源和目的都存在。

那么分别分析

源:InputStream Reader

是不是纯文本?是!Reader

设备:键盘。对应的对象是System.in.

不是选择Reader吗?System.in对应的不是字节流吗?

为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。

所以既然明确了Reader,那么就将System.in转换成Reader

用了Reader体系中转换流,InputStreamReader

 

InputStreamReader isr = new InputStreamReader(System.in);

 

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

BufferedReader bufr = new BufferedReader(isr);

 

 

目的:OutputStream  Writer

是否是存文本?是!Writer

设备:硬盘。一个文件。使用 FileWriter

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

需要提高效率吗?需要。

BufferedWriter bufw = new BufferedWriter(fw);

 

 

**************

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

目的:OutputStream  Writer

是否是存文本?是!Writer

设备:硬盘。一个文件。使用 FileWriter

但是FileWriter是使用的默认编码表。GBK.

但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。

所以要使用的对象是OutputStreamWriter

而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。

FileOutputStream

 

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

 

需要高效吗?需要。

BufferedWriter bufw = new BufferedWriter(osw);

 

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

需要用到转换流。

 

 

练习:将一个文本数据打印在控制台上。要按照以上格式自己完成三个明确。

 

 

 

*/

 

class  TransStreamDemo2{public static void main(String[] args) throws IOException{//重新分配“标准”输入流System.setIn(new FileInputStream("PersonDemo.java"));//重新分配“标准”输出流System.setOut(new PrintStream("zzz.txt"));//可用来打印指定文件,生成文件,copy文件,但是不常用 //键盘的最常见写法。BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); String line = null; while((line=bufr.readLine())!=null){if("over".equals(line))break;bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();} bufr.close(); }}


 

7.  PrintStream-异常的日志信息

打印流:PrintStream(调用的是System.out), PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException可在写入 byte 数组之后自动调用 flush 方法,可调用其中一个 println 方法,或写入一个换行符或字节 ('\n')

 

 

 

class  ExceptionInfo{public static void main(String[] args)throws IOException {try{int[] arr = new int[2];System.out.println(arr[3]);}catch (Exception e){try{Date d = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");//h与H是有区别的String s = sdf.format(d); PrintStream ps = new PrintStream("c:/exeception.log");ps.println(s);//打印方法,可将时间加入“输出流中”//写出去ps.write(d.toString().getBytes());System.setOut(ps); //重新分配标准的输出流,将异常信息输出到控制台转为输出到log文件 }catch (IOException ex){throw new RuntimeException("日志文件创建失败");}e.printStackTrace(System.out);// e.printStackTrace(new PrintStream("exeception.log"));}}}


//开发中不用上面方法,用log4j工具

 

 

8. 获取系统信息-列表输出

 

class  SystemInfo{public static void main(String[] args) throws IOException{Properties prop = System.getProperties(); //Properties是Hashtable的子类,也就是Map集合的一个子类对象。 //System.out.println(prop)//list方法将属性列表输出到指定输出流;prop.list(new PrintStream("sysinfo.txt"));}}


 

 


------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

0 0
原创粉丝点击