程序员_Java基础之<十>-IO流<1>

时间:2023-02-16 13:12:24

 

IO流:数据流
1.IO流用来处理设备之间的数据传输。
2.Java对数据的操作是通过流的方式。
3.Java用于操作流的对象都在IO包中
4.流按照操作数据分为两种:字节流,字符流。
5.流按流向分为:输入流,输出流。

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

字符流:
数据的最常见体现形式:文件。
需求:在硬盘上,创建一个文件并写入一些文字数据。
找到一个专门用于操作文件的Writer子类对象.FileWriter,后缀名是父类名,前缀名是该流对象的功能。

<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个FileWriter对象。该对象一被初始化就必须要明确别操作的文件。没有空参数构造函数。
//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
//其实该步就是在明确数据要存放的目的地。
FileWriter fw=new FileWriter("demo.text");


//调用write方法,将字符串写到流里。
fw.write("abcdef");
//刷新该流的缓冲。
//fw.flush();

fw.close();//关闭流资源,但关闭之前会刷新一次内部的缓冲中的数据。
//将数据刷到目的地中。
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。


}
}</span>


/*IO异常的处理方式*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
FileWriter fw=null;//为使fw成为全局变量。
try
{
fw=new FileWriter("demo.text");
fw.write("abcdefg");

}
catch (IOException e)
{
System.out.println(e.toString);
}
finally
{
try
{
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}

}



}
}</span>


/*文件的续写:
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileWriterDemo3
{
public static void main(String[] args)throws IOException
{

//传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写。
FileWriter fw=new FileWriter("demo.txt",true);
fw.write("hah\r\naha");
fw.close();
}
}</span>




/*文本文件读取方式一*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileWriterDemo4
{
public static void main(String[] args)throws IOException
{
//创建一个文件读取流对象,和指定的文件相关联。
//要保证该文件时已经存在,如果不存在,会发生FileNotFoundException异常
FileReader fr=new FileReader("demo.txt");
//调用读取流对象的read方法
//read()方法:一次读一个字符。而且会自动往下读。如果读到末尾返回-1
/*while(true)
{
int ch=fr.read();
if(ch==-1)
break;
System.out.print((char)ch);
}
*/
int ch=0;
while((ch=fr.read())!=-1)//此处的read()方法返回值是读到的字符
{
System.out.println((char)ch);
}

fr.close();
}
}</span>


/*第二种方式:通过字符数组进行读取*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileReaderDemo5
{
public static void main(String[] args)throws IOException
{
FileReader fr=new FileReader("demo.txt");
//定义一个字符数组,用于存储读到的字符。
//该read(char[])返回的是读到字符个数。
char[] buf=new char[1024];
/*
int num=fr.read(buf);
System.out.println("num="+num+"..."+new String(buf));
*/
int num=0;
while((num=fr.read(buf))!=-1)//该处的read(buf)返回值是读到的字符数,如果返回的数组个数不是-1,就证明还没到最后,一直循环。
{
System.out.println(new String(buf,0,num));
}
fr.read();

}
}</span>




/*IO流-拷贝文本文件*/
/*将C盘一个文本文件复制到D盘

复制原理:
其实就是将c盘下的文件数据存储到D盘的一个文件中。

步骤:
1.在D盘创建一个文件,用于存储才c盘文件中的数据。
2.定义读取流和c盘文件关联。
3.通过不断的读写完成数据存储。
4.关闭资源。


*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class CopyText
{
public static void main(String[] args)throws IOException
{

copy_1();
copy_2();
}
//从c盘读取一个字符,就往D盘写一个字符。
public static void copy_1()throws IOException
{
//创建目的地
FileWriter fw=new FileWriter("RuntimeDemo_copy.txt");
//与已有文件关联
FileReader fr=new FileReader("Demo.txt");
int ch=0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
public static void copy_2()throws IOException
{

FileWriter fw=null;

FileReader fr=null;

try
{
fw=new FileWriter("RuntimeDemo_copy.txt");
fr=new FileReader("Demo.txt");
char[] buf=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}

finally
{
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
}

}



fw.close();
fr.close();
}
}
</span>


/*字符流的缓冲区:
缓冲区的出现提高了对数据的读写效率。
对应类:
BufferedWriter
BufferReader
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强。

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

该缓冲区中提供了跨平台的换行符。newLine();
*/
//BufferdeWriter,字符写流缓冲区
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
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("abcde"+x);
bufw.newLine();//相当于windows里的\r\n,linux中的\n
//记住,只要用缓冲区,就要记得刷新。
bufw.flush();
}


bufw.close();//缓冲区的关闭,其实就是关闭了其对应的流对象,因为流才是与文件关联的。




}
}</span>


/*
字符读取流缓冲区:BufferedReader
字符缓冲区提供了一个一次读一行的方法 readLine,方便与对文本数据的获取。
当返回null时,表示读到文件末尾。

readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">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.println(line);
}
bufr.close();


}
}</span>


/*
小练习:
通过缓冲区复制一个.java文件
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class CopyTextByBuf
{
public static void main(String[] args)throws IOException
{
FileWriter fw=new FileWriter("copy_buf.txt");
FileReader fr=new FileReader("buf.txt");
BufferedReader bufr=null;
BufferedWriter bufw=null;

try
{
bufw=new BufferedWriter(fw);
bufr=new BufferedReader(fr);
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
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("写入失败");


}
}
}
}
</span>


/*明白了BufferedReader类中特有方法readerLine的原理后。
我们可以自定义一个类中的包含一个功能和readLine一致的方法。
来模拟一下BufferedReader*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class MyBufferedReader
{
private FileReader r;
MyBufferedReader(FileReader r)//此处可以改成(Reader r),那么就可以增强一组对象,但该装饰类要继承Reader类,才能使用Reader对象,另外还要实现Reader中的抽象方法。
{
this.r=r;
}
public String myReadLine()throws IOException//谁调用谁处理,直接抛出去,不要自己处理了
{
//定义一个临时容器。原BufferedReader封装的字符数组。
//为了演示方便,定义一个StringBuilder容器,因为最终还要讲数据变成字符串。
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')//windows下的换行是\r\n
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
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();
}
}
</span>

/*装饰设计模式
当想要对已有的对象进行功能增强时,可以定义类,
将已有的对象传入,基于已有功能,并提供加强功能。
那么自定义的该类称为装饰类。

装饰类通常会通过构造方法接 收被装饰对象。
并基于被装饰的对象的功能,提供更强的功能。
装饰类与继承:
1. 装饰类比继承要灵活,避免了继承体系臃肿。
而且降低了类与类之间的关系。
2. 装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。
所以装饰类和被装饰类通常是都属于一个体系,都属于同一个父类或接口。
*/

/*带行号的装饰类:LineNumberReader*/

<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class LineNumberReaderDemo
{
public static void main(String[] args)throws IOException
{
FileReader fr=new FileReader("Demo.txt");
LineNumberReader lnr=new LineNumberReader(fr);


String line=null;
lnr.setLineNumber(100);//指定行号从100开始
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+"::"+line);
}
lnr.close();
}
}</span>


/*MyineNumberReader:模拟实现LineNumberReader*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class MyLineNumberReader
{
private int lineNumber;
private Reader r;
MyLineNumberReader(Reader r)
{
this.r=r;
}
public void setLineNumber(int lineNumber)
{
this.lineNumber=lineNumber;
}
public int getLineNumber()
{
return lineNumber;
}
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 myClose()throws IOException


{
r.close();
}
}


class MyLineNmberReaderDemo
{
public static void main(String[] args)throws IOException
{
FileReader fr=new FileReader("buf.txt");
MyLineNumberReader mylnr=new MyLineNumberReader(fr);
String line=null;
while((line=mylnr.myReadLine())!=null)
{
System.out.println(mylnr.getLineNumber()+":::"+line);
}
mylnr.myClose();
}
}</span>


/*
字符流:
FileReader
FileWriter

BufferedReader
BufferedWriter

字节流:
InputStream(读)
OutputStream(写)(可以站在机器短的角度理解)(in out 对应读写)
需求:想要操作图片数据,这时就要用到字节流。
*/
//字节流写,OutputStream
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileStream
{
public static void main(String[] args)
{
writeFile();
}
public static void writeFile()throw IOException
{
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());
}
}</span>


//字节流读,InputStream
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class FileStream
{
public static void main(String[] args)throws IOException
{
//writeFile();
readFile_1();
readFile_2();
readFile_3();
}
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 readFile_2()throws IOException//读到数组里
{
FileInputStream fis=new FileInputStream("fos.txt");
byte[] buf=new byte[1024];//1024才是最合适的大小
int len=0;
while((len=fis.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));
}
fis.close();
}
public static void readFile_3()throws IOException//字节流特有方法
{
FileInputStream fis=new FileInputStream("fos.txt");
//int num=fis.available();//文件字节个数
byte[] buf=new byte[fis.available()];//定义一个刚刚好的数组,1024才是最合适的大小
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
public static void writeFile()throws IOException
{
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());
fos.close();
}
}
</span>

/*复制一个图片:
思路:
1,用字节读取流对象和图片关联。
2.用字节写入流创建一个图片文件,用于存储获取到的图片数据。
3.通过循环读写,完成数据的存储。
4。关闭资源。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class CopyPic
{
public static void main(String[] args)
{
FileOutputStream fos=null;
FileInputStreamfis=null;
try
{
fis=new FileInputStream("f:\\1.JPG");
fos=new FileOutputStream("f:\\2.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("写入关闭失败");
}
}
}
}</span>


/*字节流的缓冲区
通过mp3的复试,演示缓冲区
BufferedOutputStream
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">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_1()throws IOException
{
BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("f:\\1.mp3"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("f:\\2.mp3"));
int by=0;
while((by=bufis.read())!=-1)//bufis.read()是从缓冲区一个一个读,不是从硬盘。
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
//自己模拟缓冲区的read()方法:
public static void copy_2()throws IOException
{
MyBufferedInputStream bufis=new MyBufferedInputStream(new FileInputStream("f:\\1.mp3"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("f:\\2.mp3"));
int by=0;
System.out.println("第一个字节:"+bufis.myRead());
while((by=bufis.myRead())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.myClose();
}
}
//自己模拟缓冲区,模拟缓冲区的read()方法
class MyBufferedInputStream
{
private InputStream in;
private byte[] buf=new byte[1024];
private int pos=0,count=0;//pos是数组指针,每从数组中取一个字节,pos++,count是每次存入到数组的字节个数。
MyBufferedInputStream(InputStream in)
{
this.in=in;
}
//一次读一个字节,从缓冲区(字节数组)获取
public int myRead()throws IOException
{
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;//为什么&255呢?看下面注解
}
return -1;
}
public void myClose()throws IOException
{
in.close();
}
}</span>


/*
在Mp3文件中可能出现如下情况:
11111111-1111111100000000000011101010101
而其中的11111111是返回byte时是十进制-1


注意到在函数返回时是int型,那么11111111-->提升了一个int类型,那不还是-1吗?是-1的原因是因为
在8个1前面补的是1导致的。
11111111-->1111-1111 1111-1111 1111-1111 1111-1111
那么我们只要在前面补0,即可以保留原字节数据不变,又可以避免出现-1情况。
怎么补0呢??


 1111-1111 1111-1111 1111-1111 
&0000-0000 0000-0000 1111-1111
-----------------------------------
 0000-0000 0000-0000 1111-1111
 当byte数据强制返回int类型时,8位一个字节就变成4个字节了?
 岂不是返回的多了?在用write(by)时,强制只写最低四位,从而保证原数据不变化。
*/

/*读取键盘录入
System.out:对应的是标准输出设备,控制台
System.in:对应的标准输入设备:键盘

需求:
通过键盘录入数据。
当录入一行数据后,将该行数据进行打印。
当录入的数据时over,那么停止录入。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class ReadIn
{
public static void main(String[] args)throws IOException
{
InputStream in=System.in;
/*int ch=0;
while((ch=in.read())!=-1)//当录入的不是-1时,继续一个一个的读
{
System.out.println(ch);
}
in.close();
*/
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))//当输入over时,结束程序
break;
System.out.println(s.toUpperCase());
sb.delete(0,sb.length());//每次打印完,清空缓冲区
}
else
sb.append((char)ch);
}
}
}
</span>

/*通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。
也就是readLine方法。

能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢??

readLine方法是字符流BufferedReader类中的方法。
而键盘录入的read方法是字节流InputStream的方法。

那么能不能将字节流转成字符流再使用字符流缓冲区的readLine方法呢?
使用转换流:InputStreamReader:字节流到字符流的桥梁。
*/

<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class TransStreamDemo
{
public static void main(String[] args)throws IOException
{
//获取键盘录入对象
InputStream in=System.in;
//将字节流对象转成字符流对象,使用转换流。InputStreamReader.
InputStreamReader isr=new InputStreamReader(in);//将输入字节流转换成输入字符流

//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferReader
BufferedReader bufr=new BufferedReader(isr);


//以上三句话可写简写成一句话:记住!!!键盘录入最常见写法!
//BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

//将输出字节流转换成输出字符流,OutStreamWriter
OutputStream out=System.out;
OutputStreamWriter osw=new OutputStreamWriter(out);
为了使用换行功能newLine(),使用输出缓冲区BufferedWriter
//BufferedWriter bufw=new BufferedWriter(osw);


//以上三句话可写简写成一句话:
//BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));






String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
//System.out.println(line.toUpperCase());
bufw.write(line.toUpperCase());//字符流对象可直接使用write方法
bufw.newLine();
bufw.flush();
}
bufr.close();

}
}</span>




/*流操作规律:
1.  源:键盘录入。
目的:控制台。
2.需求:想把键盘录入的数据存储到一个文件中。
源:键盘.
目的:文件。
3.需求:想要将一个文件的数据打印在控制台上。
源:文件。
目的:控制台
4.流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪个.

通过三个明确来完成:
a.明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream  Writer
b.操作的数据是否是纯文本
是:字符流
不是:字节流
c.当体系明确后,再明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,控制台。

需求:将一个文本文件中的数据存储到另一个文件中。复制文件。
源:因为是源,所以使用读取流,InputStreamReader
是不是操作文本文件?
是!这时就可以选择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);


练习:1。将一个图片文件中数据存储到另一文件中,复制文件,要按照以上格式完成三个明确。
2.将键盘录入的数据保存到一个文件中。


这个需求中有源目的都存在。
那么分别分析:
源:InputStream Reader
是不是纯文本?是!Reader
设备:键盘。对应的对象时System.in(字节流对象)
不是选择Reader吗?System.in对应的不是字节流吗?
为了操作键盘的文本数据方便,那么就将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-8),将数据存到文件中。
目的: OutputStream  Writer
是否是纯文本?是!Writer
设备:硬盘。一个文件。使用FileWriter
但是FileWriter是使用的默认编码表,GBK


但存储时,需要加入指定编码表,而指定的编码表只有转换流才可以指定。
所以要使用的对象是OutputStreamWriter
而转换流对象要接受一个字节输出流,而且是还可以操作文件的字节输出流。FileOutStream
   OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8";)
需要提高效率吗?需要
BufferedWriterbufw=new BufferedWriter(osw);
所以,记住,转换流什么时候用,字符和字节之间的桥梁,通常涉及到字符编码转换时需要用到转换流。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
class TransStreamDemo2
{
public static void main(String[] args)throws IOException
{
/* 需求1
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));


BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out);
*/
/*需求2
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));


//源没变,目的由控制台变成文件,所以将下句中System.out变为文件即可
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt"),"UTF-8"));//此处可指定编码表,不写默认为GBK
*/

/*需求3*/
BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("out.txt")));


//源没变,目的由控制台变成文件,所以将下句中System.out变为文件即可
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));


String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
//System.out.println(line.toUpperCase());
bufw.write(line.toUpperCase());//字符流对象可直接使用write方法
bufw.newLine();
bufw.flush();
}
bufr.close();

}
}</span>


改变标准输入输出设备
*************************************************、
<span style="font-family:KaiTi_GB2312;font-size:18px;">class TransStreamDemo2
{
public static void main(String[] args)throws IOExcetion
{
System.setIn(new FileInputStream("PersonDemo.java"));//指定输入流为文件输入流,文件输入流又指定文件为PersonDemo.java
System.setOut(new PrintStream("zzz.txt"));


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;
//System.out.println(line.toUpperCase());
bufw.write(line.toUpperCase());//字符流对象可直接使用write方法
bufw.newLine();
bufw.flush();
}
bufr.close();



}
}
</span>

//异常的日志信息:
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo
{
public static void main(String[] args)
{
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);//指定输出流为PrintStream流,PrintStream指定输出文件为exception.log
}
catch (IOException ex)
{
throw new RuntimeException("日志文件创建失败。");
}
e.printStackTrace(System.out);
}
}
}
</span>

//注解:建立java日志信息工具:log4j
/*系统信息*/
<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.util.*;
import java.io.*;
class SystemInfo
{
public static void main(String[] args)throws IOException
{
Properties prop=System.getProperties();
//System.out.println(prop);
prop.list(new PrintStream("sysinfo.txt"));//list()方法:将属性输出到指定的输出流。
}
}
</span>