缓冲区的出现是为了提高流的操作效率的
所以在创建缓冲区之前必须要先有流对象
/*
缓冲区的出现是为了提高流的操作效率的
所以在创建缓冲区之前必须要先有流对象
该缓冲区中提供了一个跨平台的换行方法:newLine
*/
import java.io.*;
class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个字符写入流对象
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流的效率,加入缓冲技术
//原理是此对象中封装了字符数组
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
BufferedWriter bufw = new BufferedWriter(fw);
//缓冲区(bufw)跟流(fw)相关联了,直接使用缓冲区的方法即可
/*
bufw.write("abcde");
bufw.newLine();//写入一个行分隔符。增强跨平台性
//只要用到缓冲区就要刷新
bufw.flush();*/
for(int i=0;i<3;i++)
{
bufw.write("abcd"+i);
bufw.newLine();
bufw.flush();
//写后立即刷新,避免意外时数据没有写入,因缓冲区是在内存中的
}
//关闭缓冲区就是在关闭缓冲区中的流对象
bufw.close();
}
}
/*
字符读取流缓冲区:
该缓冲区提供一个一次读一行的方法 readLine,方便于对文本数据的获取
当返回null,表示读到文件末尾。
*/
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 s1 = bufr.readLine();
System.out.println("s1:"+s1);
String s2 = bufr.readLine();
System.out.println("s2:"+s2);*/
String line = null;
while((line=bufr.readLine())!=null)
{
System.out.println(line);
}
/*
while((bufr.readLine())!=null)
{
System.out.println(bufr.readLine());//abcd1
//null
}
*/
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();//若不换行,则copy出的文件中数据不整齐
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("写入关闭失败");
}
}
}
}
readLine方法的原理:无论是读一行还是获取多个字符,其实最终都是在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个。readLine在其内部封装好一个数组,字符一个个读取到数组中,读到换行符时(换行符不放到数组中),将数组中内容变为字符串返出。
/*
在了解BufferedReader类中特有的方法readLine的原理后,
可以自定义一个类中包含一个功能和readLine一致的方法来模拟BufferedReader。
readLine方法是对read方法的增强。
*/
import java.io.*;
class MyBufferedReader
{
private FileReader r;
MyBufferedReader(FileReader r)
{
this.r = r;
}
public String myReadLine() throws IOException
{
//定义一个临时容器。原BufferedReader封装的是字符数组。
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.read())!=-1)
{ //若某行没有换行,则只会存入不会输出。
//如去掉文件中最后一行的换行。
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
return null;
}
public void myClose() throws IOException
{
r.close();
}
}
class MyBufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
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("开胃菜");
System.out.println("喝点酒");
//System.out.println("吃饭");
p.chifan();
System.out.println("甜点");
}
}
class DecorateDemo
{
public static void main(String[] args)
{
Person p = new Person();
//p.chifan();
SuperPerson sp = new SuperPerson(p);
sp.superchifan();
}
}
装饰和继承的区别
如:
MyReader // 专门用于读取数据的类
|--MyTextReader //子类
|--MyBufferTextReader//子类的装饰类
|--MyMediaReader
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader
若子类过多,装饰类会更多。此时,可以先定义一个缓冲区,哪个需要哪个传进去
class MyBufferReader
{
MyBufferReader(MyTextReader text)
{}
MyBufferReader(MyMediaReader media)
{}
//每有一个子类需要加强,都需传进来,同时需增加MyBufferReader()
//因此类MyBufferReader扩展性很差。
}
找其参数的共同类型,通过多态的形式,可以提高扩展性。
class MyBufferReader extends MyReader
{
private MyReader r;
MuBufferReader(MyReader r)
{}
}
然后上述体系变为
MyReader
|--MyTextReader
|--MyMediaReader
|--MyDataReader
|--MyBufferReader
装饰模式比继承要灵活,避免了继承体系的臃肿。
而且降低了类与类之间的关系。(如原加强类需继承对应子类,现只需继承父类即可)
import java.io.*;
class LineNumberReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("buf.txt");
LineNumberReader lnr = new LineNumberReader(fr);
//跟踪行号的缓冲字符输入流。默认情况下行编号从0开始
String line = null;
lnr.setLineNumber(100);//设置当前行号
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+":"+line);
//getLineNumber() 获取当前行号
}
lnr.close();
}
}
import java.io.*;
class MyLineNumberReader extends MyBufferedReader
{
private FileReader r;
private int lineNumber;
MyLineNumberReader(FileReader 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();
else
sb.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;
while((line=mylnr.myReadLine())!=null)
{
System.out.println(mylnr.getLineNumber()+"::"+line);
}
mylnr.myClose();
}
}
字符流一样需要用字节流,但需要将字节临时存储。字符流的底层使用的是字节流的缓冲区。
如:一个中文对应两个字节,读了一个字节后不能立即操作。读了两个字节后临时存储,再去查表找对应字符。
字节流读取一个字节后即可操作,而字符流不行,所以字节流不需刷新二字符流需要。
字节流同样需要关闭资源。
/*
字符流
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流
InputStream OutputStream
需求:想要操作图片数据就要用到字节流。
*/
import java.io.*;
class FileStreamDemo
{
public static void main(String[] args) throws IOException
{
//writeFile();
//readFile_1();
readFile_2();
//readFile_3();
}
public static void readFile_3() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
//int num = fis.available();//计数字节数。
//每个字母是一个字节。Windows中的回车是"\r\n",是两个字节。
//System.out.println("num:"+num);
byte[] buf = new byte[fis.available()];
//定义一个刚好的缓冲区,不用再循环.
//不过此方法慎用!数据过大会发生内存溢出
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)//read(buf); 将数据读入数组buf中.
{
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());
//write(byte[] b) FileOutputStream中的方法,将b.length个字节从指定byte数组写入此文件输出流中
//getBytes() String类中的方法,将此String编码为byte序列,并将结果存储到一个新的byte数组中。
fos.close();
}
}
/*
复制一张图片
思路:
1.用字节读取流对象和图片关联。
2.用字节写入流创建一个图片文件。用于存储获取到的图片数据。
3.通过循环读写,完成数据的存储。
4.关闭资源。
*/
import java.io.*;
class CopyPic
{
public static void main(String[] args)
{
FileOutputStream fos = null;
FileInputStream fis = null;
try
{
fos = new FileOutputStream("F:\\黑马程序员 Java\\第十九天\\days19\\12(1).jpg");
fis = new FileInputStream("F:\\黑马程序员 Java\\第十九天\\days19\\12.jpg");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("复制文件失败");
}
finally
{
try
{
if(fis!=null)
fis.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(fos!=null)
fos.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class CopyMp3
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
copy_1();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy_1() throws IOException
{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream(
"F:\\黑马程序员 Java\\第十九天\\days19\\0.mp3"));
//此时数据已从硬盘存至缓冲区中了
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream(
"F:\\黑马程序员 Java\\第十九天\\days19\\1.mp3"));
int by = 0;
while((by=bufis.read())!=-1) //此时是从缓冲区中取的数据
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
}
import java.io.*;
class MyBufferedInputStream
{
private InputStream in;
private byte[] buf = new byte[1024];
private int pos = 0,count = 0;
MyBufferedInputStream(InputStream in)
{
this.in = in;
}
//一次读一个字节,从缓冲区(字节数组)获取。
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;
}
else if(count>0)
{
byte b = buf[pos];
count--;
pos++;
return b&0xff;
}
return -1;
}
public void myClose() throws IOException
{
in.close();
}
}
/*
byte:-1 (提升)---> int:-1
11111111 ---> 11111111 11111111 11111111 11111111
11111111 (提升)---> 到int类型,还是-1.是因为在8个1前面补的是1导致的。
所以只要在前面补0即可保留原字节数据不变又可避免-1的出现。
即11111111 & 00000000 000000000 0000000 11111111 (255)
MyRead方法中数据经过提升有一个字节升为4个字节,而write方法有一个强转动作,
write会把最低的8位即最后一字节写出。
*/
/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class CopyMp3
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
//copy_1();
copy_2();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy_1() throws IOException
{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream(
"F:\\黑马程序员 Java\\第十九天\\days19\\0.mp3"));
//此时数据已从硬盘存至缓冲区中了
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream(
"F:\\黑马程序员 Java\\第十九天\\days19\\1.mp3"));
int by = 0;
while((by=bufis.read())!=-1) //此时是从缓冲区中取的数据
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
public static void copy_2() throws IOException
{
MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream(
"F:\\黑马程序员 Java\\第十九天\\days19\\0.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream(
"F:\\黑马程序员 Java\\第十九天\\days19\\2.mp3"));
int by = 0;
System.out.println("第一个字节:"+bufis.MyRead());//-1
//一个字节由8个二进制码表示。当第一个字节为1111-1111即-1,2.mp3大小为0字节
while((by=bufis.MyRead())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.myClose();
}
}
/*
读取键盘录入
System.out; 对应的是标准输出设备,控制台。
System.in; 对应的是标准输入设备,键盘。
System中的in有字节读取流对象InputStream
*/
import java.io.*;
class ReadIn
{
public static void main(String[] args) throws IOException
{
InputStream in = System.in;
/*
int by = in.read();//此时read是一个阻塞式方法。
//即在控制台中等待输入才会执行下一步。
//int by = in.read();一次只能读一个字节。输入字母,打印数字,因类型提升。
System.out.println(by);*/
StringBuilder sb = new StringBuilder();
while(true)
{
int ch = in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String s = sb.toString();
if("over".equals(s))
break;
System.out.println(s.toUpperCase());
sb.delete(0,sb.length()); //清空缓冲区
}
else
sb.append((char)ch);
}
}
}
/*
字符流
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
直接使用readLine方法来完成键盘录入的一行数据的读取
readLine方法是字符流BufferedReader类中的方法。
而键盘录入的read方法是字节流InputStream的方法
键盘录入停止的方法:Ctrl+c或者自定义结束标记
*/
import java.io.*;
class TransStreamDemo
{
public static void main(String[] args) throws IOException
{
//获取键盘录入对象
InputStream in = System.in;
//将字节流对象转成字符流对象,要使用转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//InputStreamReader 是字节流通向字符流的桥梁
//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
bufr.close();
}
}
import java.io.*;
class TransStreamDemo
{
public static void main(String[] args) throws IOException
{
/*
//获取键盘录入对象
InputStream in = System.in;
//将字节流对象转成字符流对象,要使用转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
bufr.close();*/
//InputStream in = System.in;
//InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//键盘录入的最常见写法
//OutputStream out = System.out;//目的是屏幕输出
//OutputStreamWriter osw = new OutputStreamWriter(out);
//OutputStreamWriter 是字符流通向字节流的桥梁
//OutputStreamWriter字符输出流内部有自己的缓冲区,需要刷新.
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();
}
}
流操作的基本规律:
(流对象有很多)
1.要明确源和目的。
源:输入流。 InputStream Reader
目的:输出流。OutputStream Writer
2.操作的数据是否为纯文本。
是纯文本:字符流Reader,Writer
不是:字节流 InputStream,OutputStream
3.当体系明确后,再明确要使用的哪个具体对象。
通过设备进行区分:
源设备:内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。
例:
将一个文本文件中数据存储到另一个文件中。即复制文件。
源:因为是源,所以使用读取流。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);
import java.io.*;
class TransStreamDemo2
{
public static void main(String[] args) throws IOException
{
//method_1();
method_2();
}
/*
需求:把键盘录入的数据存储到一个文件中。
源:键盘录入
目的:文件
*/
public static void method_1() throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt")));
//OutputStreamWriter 输出的是字节流文件.字节输出流能操作的文件的对象是FileOutputStream
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
/*
需求:将一个文件的数据打印在控制台上
源:文件
目的:控制台
*/
public static void method_2() throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("buf.txt")));
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();
}
}
}
import java.io.*;
class TransStreamDemo2
{
public static void main(String[] args) throws IOException
{
//method_1();
//method_2();
//method_3();
method_4();
}
/*
需求:把键盘录入的数据存储到一个文件中。
源:键盘录入
目的:文件
这个需求中有源和目的。
那么分别分析
源: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(使用默认的字符编码即java平台的编码也就是GBK)
FileWriter fw = new FileWriter("c.txt");
需要提高效率
BufferedWriter bufw = new BufferedWriter(fw);
*/
public static void method_1() throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt")));
//OutputStreamWriter 输出的是字节流文件.字节输出流能操作的文件的对象是FileOutputStream
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
/*
需求:将一个文件的数据打印在控制台上
源:文件
目的:控制台
*/
public static void method_2() throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("buf.txt")));
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();
}
}
/*
扩展一下:
想要把录入的数据按照指定的编码表(UTF-8),将数据存到文件中。
键盘录入中文的时候,GBK和UTF-8两张码表都能识别。
目的:OutputStream Writer
是纯文本 Writer
设备:硬盘上的一个文件,使用FileWriter
但是存储时,需要加入指定编码表。而指定的编码表只有转换流可以指定,FileWriter使用的是指定编码表GBK。
所以要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
转换流是字符和字节之间的桥梁,通常在涉及到字符编码转换时需要用到。
*/
public static void method_3() throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d.txt"),"GBK"));
//默认编码是GBK。若指定编码为UTF-8,输入数据一样但产生的文件大小不同。
//同时,FileReaer只能读编码为GBK的文件。若要读编码为UTF-8的文件需要
//用读取转换流InputStreamReader指定编码。
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
public static void method_4() throws IOException
{
System.setIn(new FileInputStream("TransStreamDemo.java"));
//若将源//掉,键盘录入将会成源,目的是e.txt
System.setOut(new PrintStream("e.txt"));
//若将目的//掉,控制台将会成为目的,源是TransStreamDemo.java
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();
}
}
}
/*
异常的日志信息
*/
import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo
{
public static void main(String[] args) throws IOException
{
/*
try
{
int[] arr = new int[2];
System.out.println(arr[3]);
}
catch (Exception e)
{
System.setOut(new PrintStream("exception.log"));
e.printStackTrace(System.out);
}*/
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");
String s = sdf.format(d);//将日期格式化
PrintStream ps = new PrintStream("exception.log");
ps.println(s);
System.setOut(ps);
ps.close();
}
catch (IOException ie)
{
throw new RuntimeException("日志文件创建失败");
}
e.printStackTrace(System.out);
}
}
}
import java.util.*;
import java.io.*;
class SystemInfo
{
public static void main(String[] args) throws IOException
{
Properties prop = System.getProperties();
//Properties lang包System类中的子类。
//getProperties 确定当前系统属性
//Syste.out.println(prop);//控制台中打印的系统信息很混乱没有换行。
//prop.list(System.out);//控制台
prop.list(new PrintStream("SystemInfo.txt"));
}
}