----------android培训、java培训、期待与您交流! ----------
/**
* Java之字节流小结:
*
* 1 :IO之--字节流
* 2 :拷贝图片
* 3 :演示mp3的复制,通过缓冲区。
* 4 :自定义流缓冲区及其原理讲解
* 5 :读取键盘录入。以三种不同的方式:
* 6 :流操作规律
* 7 :改变标准输入输出设备
* 8 :流异常信息
* 9 :打印系统信息,并保存到文件中
*/
/** 1 :IO之--字节流
*
* 我们学过的字符流有:字符流仅限于操作文本。
* FileReader
* FileWriter
*
* BufferedReader
* BufferedWriter
*
* 如果我们想要操作一张图片的话,该怎么办呢?
* 这时就需要用到字节流了:
* InputStream OutputStream
*
* 需求:想要操作图片数据这时就要用到字节流。
*
* public abstract class InputStream extends Object implements Closeable
* 此抽象类是表示字节输入流的所有类的超类。 需要定义 InputStream 子类的应用程序
* 必须总是提供返回下一个输入字节的方法。
*
* public abstract class OutputStream extends Object implements Closeable, Flushable
* 此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。
* 需要定义 OutputStream 子类的应用程序必须始终提供至少一种可写入一个输出字节的方法。
*
* public class FileOutputStream extends OutputStream,文件输出流是用于将数据写入 File
* 或 FileDescriptor 的输出流。
*/
import java.io.*;
public class FileStream {
public static void main(String[] args) throws IOException
{
//writerFile();
//readFile_1();
//readFile_2();
readFile_3();
}
public static void writerFile() throws IOException
{
FileOutputStream fos = new FileOutputStream("fos.txt");
/*
* void write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。
*/
fos.write("adfjdi".getBytes());
/*
* 但是为什么没有刷新呢:
* 字符流:其实是一样走的字节,但是需要把字节临时存起来。如果存中文的话,
* 一个汉字对应两个字节,如果存了一个字节,那么还需要一个字节,当两个字节
* 完成后,还需要去查表。
*
* 如果直接使用字节流:如果没有直接指定缓冲区的话,是不需要刷新的。
*/
fos.close(); //这个需要写
}
public static void readFile_1() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
int ch = 0;
/* int read() 从此输入流中读取一个数据字节。
*
* int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
*/
while((ch=fis.read())!=-1)
{
//这样的方式,无法输出汉语
System.out.print((char)ch);
}
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.print(new String(buf,0,len)+":::");
}
fis.close();
}
public static void readFile_3() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
//int num = fis.available();
//System.out.println("num"+num); //字节数目
byte[] buf = new byte[fis.available()];
/*定义一个刚刚好的缓冲区,不用再循环了。
*
* 使用情况:当数据不是太大时,可以使用这种方法
* 由于java的初始内存是64mb的,所以对于一个电影来说,这种操作会发生内存溢出。
* 建议这种方法慎用。推荐使用固定大小:1024的整数倍。
*/
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
}
/** 2 :拷贝图片
*
* 拷贝一张图片
* 思路:
* 1,用字节读取流对象和图片关联。
* 2,用字节写入流对象创建一个图片文件,用于存储获取到的图片数据。
* 3,通过循环读写,完成数据的存储
* 4,关闭资源。
*
* 问题:用字符流可以复制么?
* 可以的。但是复制完的图片有可能打不开。字符流复制图片时会不断的去查编码表,如果找到了
* 对应的编码,则可以,如果找不到对应的编码,就会以相似的编码替代。因此,新旧编码可能会
* 变化,有可能会打不开。
* 字符流是用于处理文字的。不能拿来处理媒体文件。谨记。
*
*/
import java.io.*;
public class CopyPic {
public static void main(String[] args)
{
FileInputStream fis = null; //将数据读入字节流
FileOutputStream fos = null; //可以将读入到的字节流写到输出流中
try
{
fos = new FileOutputStream("G:\\龟龟2.bmp");
fis = new FileInputStream("G:\\龟.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("写入关闭失败");
}
}
}
}
/** 3 :演示mp3的复制,通过缓冲区。
*
*BufferedinputStream
* public class BufferedInputStream extends FilterInputStream
* BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和
* reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。
* 在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一
* 次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入
* 流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。
*
*BufferedOutputStream
* public class BufferedOutputStream extends FilterOutputStream
* 该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底
* 层输出流中,而不必针对每次字节写入调用底层系统。
*
*
*/
import java.io.*;
public 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 bfis = new BufferedInputStream(new FileInputStream("G:\\不屑.mp3"));
BufferedOutputStream bfos = new BufferedOutputStream(new FileOutputStream("G:\\很不屑.mp3"));
/* FileInputStream("G:\\不屑.mp3")从硬盘中读取数据,放到缓冲区中。
* BufferedInputStream从缓冲区中读取数据。
*/
int by = 0;
while((by=bfis.read())!=-1)
{
bfos.write(by);
}
bfos.close();
bfis.close();
}
/**
* 问题:能不能自己定义一个缓冲区,来操作数据呢?
* 解决方法见下,工具类MyBufferedInputStream在第14讲:
*/
public static void copy_2() throws IOException
{
MyBufferedInputStream bfis = new MyBufferedInputStream(new FileInputStream("G:\\不屑.mp3"));
BufferedOutputStream bfos = new BufferedOutputStream(new FileOutputStream("G:\\很不屑.mp3"));
/* FileInputStream("G:\\不屑.mp3")从硬盘中读取数据,放到缓冲区中。
* BufferedInputStream从缓冲区中读取数据。
*/
//System.out.println("第一次读到的是:"+bfis.myRead());
int by = 0;
while((by=bfis.myRead())!=-1)
{
bfos.write(by);
}
bfos.close();
bfis.myClose();
}
}
/** 4 :自定义流缓冲区及其原理讲解
*
*/
import java.io.*;
public class MyBufferedInputStream
{
private InputStream in;
private byte[] buf = new byte[1024];
private int pos = 0,count = 0;
/**
* pos是标识位置的,他和count(计数器)搭配使用,
* 当向一个缓冲区数组中填入数据后,count的值就是该数组的长度,
* 那么当向外去数据的时候,每取一次,那么缓冲区数组的长度就会减1,
* 那也就代表着还可以取的次数就会少一次。直到缓冲区数组的长度为0(此时,
* count也为0,表示数组空了,要从新向里面插入数据了。
*/
MyBufferedInputStream(InputStream in) //构造函数。传入一个参数。
{
this.in = in;
}
//一次读一个字节,从缓冲区中(字节数组)读取
public int myRead() throws IOException
/**问题:
* return b;中的b是byte类型的,那么该方法的返回值类型为什么不是byte类型呢?
*/
{
//通过in对象读取硬盘上的数据,并存储到buf中。
if(count==0)
/*当count==0时,表示数据取光了。要重新向缓冲区中添加数据
* 其实,当count==0时,数组为空,添加完数据后,在该if语句里,就
* 只取了一次数据,即0角标的数据,之后count就不为0,会进入到
* else if语句里,知道该块搞完,此时count再次为0,又到这个if
* 语句取数据,知道数据被取完。
*/
{
count = in.read(buf); //read方法会将读到的数据放到数组buf中,并返回读取到字节数。
if(count<0) //数据取完了。
return -1;
pos = 0; //装完数据后,pos要归0;
byte b = buf[pos]; //取数据,首先会取到0角标元素。
count--; //你敢取一次,我就少一次
pos++; //下一次取就是接着的数据
return b&255;
}
else if(count>0)
/*
* 该代码块就是在取数据
*/
{
byte b = buf[pos]; //取数据,首次会取到1角标元素。
count--;
pos++;
return b&0xff;//(16进制的255)
}
return -1;
}
public void myClose() throws IOException
{
in.close();
}
}
/*
* 问题:为什么返回值是int,而不是byte?
* Mp3的数据都是二进制的数据,即都是由1,0组成的。所以在MP3的二进制字节中,会存在11111111
* 和00000000的情况,也就是说,MP3的二进制里会出现-1,这和判断文件结束的标记“-1”冲突,
* 那怎么解决呢?
* byte在内存中占用1个字节即8位,由于我们知道,-1的二进制是1取反再加1,也就是11111111.
* 如果我们按照byte类型返回的话,那么还是-1,还是会冲突。那么我们怎么保证如果取到的值是
* -1,又能正常返回,而又不和结束标记冲突呢?
* 将其转为int类型,int类型在内存中占4个字节,32位,如果取到的值是-1,我们在其前3位补0
* 那么结果就得以保存,而又不冲突。
*
* 因为myRead的返回值是int类型的,当b取到了11111111后,以int(32位)类型返回,类型提升,
* 就成了 11111111 11111111 11111111 11111111
* 而write方法,内部会进行强转,仅仅取得返回值的后8位,仍旧是-1,此时,程序就会结束。
*
* byte类型 -1 == 11111111
*
* byte类型 -1 --转成--> int类型的 -1 == 11111111 11111111 11111111 11111111
*
* 00000000 00000000 00000000 11111111 == 255 ,就不是-1了。
*
* 那么就有一种假设:如果在byte转成int类型是,将前面的24位补成0,而不是1,就会保留
* 原数据,那么就会避免-1的出现了。那么怎么实现这种操作呢?
*
* **异或操作。
*
* 11111111 ---》提升了一个int类型,那不还是-1么? 是-1的原因是因为在8个1前面
* 补的是1导致的。那么我只要在前面补0,既可以保留原字节数据不变,又可以避免-1的出现。
*
* 那么怎么补0呢?
* 11111111 11111111 11111111 11111111
* & 00000000 00000000 00000000 11111111
* --------------------------------------
* 00000000 00000000 00000000 11111111
*/
/**问题:类型提升过后,是不是就由1个字节变成了4个字节??
* 那就是说,读1个字节,得到4个字节。那么再往回写的时候,不是要扩大4倍么?
* write方法其实在做一个强转动作。 write仅仅把最低的8位写入。
*
* read方法在做提升。而write在做强转。
*/
/** 5 :读取键盘录入。以三种不同的方式:
*
* 字符流:4个
* FileWriter
* FileReader
* BufferedReader
* BufferedWriter
*
* 字节流:4个
* FileInputStream
* FileOutputStream
* BufferedInputStream
* BufferedOutputStream
*
* InputStreamReader:字节流通向字符流的桥梁
* OutputStreamWriter:字符流通向字节流的桥梁
*
* 读取键盘录入:
* System.out:标准的输出设备,控制台
* System.in: 标准的输入设备,键盘。
*
* 需求: 通过键盘录入数据,当录入一行数据后,就将该行数据打印,如果录入的数据
* 是over的话,就停止打印。
*
* 通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。也就
* 是readLine()方法。
*
* 那么能不能直接使用readLine方法来完成键盘录入一行数据的读取呢?
*
* readLine()是BufferedReader类中的方法,而键盘录入的read方法是字节流InputStream的方法。
* 那么能不能将字节流转成字符流再使用字符流缓冲区中的readLine方法呢?
*/
import java.io.*;
public class TransStreamDemo {
public static void main(String[] args) throws IOException
{
// method_1();
//method_2();
method_3();
}
//第一种方式:
public static void method_1() throws IOException
{
InputStream in = System.in; //System.in的返回类型是InputStream
//System.out.println('\r'+0); // \r = 13
//System.out.println('\n'+0); // \n = 10
//int by = in.read(); //read()方法是一个阻塞式方法。
//int by1 = in.read(); //读取一个字节。
//int by2 = in.read(); //读取一个字节。
//System.out.println(by);
//System.out.println(by1);
//System.out.println(by2);
/*
* 当读入的数据少于要打印的数据时,就会以回车符代替。
* 比如:上面有三次输出,如果只读入一个字符,如a,那么后面两个就会以回车符替代。
*/
StringBuilder sb = new StringBuilder(); //临时缓冲区。
while(true)
{
int ch = in.read();//一次读一个字符
if(ch=='\r')
continue;
if(ch=='\n')
/*如果换行就到结尾了
* 然后将输入的数据转成String,然后可以判断
*/
{
String s = sb.toString();
if("over".equals(s))
break;
System.out.println(s.toUpperCase());
//sb = new StringBuilder(); //清空缓冲区。利于判断。但是new一个对象占内存
sb.delete(0, sb.length()); //清空缓冲区,否则每一次添加的长度都在增长。
}
else
sb.append((char)ch);
}
in.close(); //不关也可以,因为程序结束后,就停止了。
}
//第二种方式:第一次效率提高。
public static void method_2() throws IOException
{
/*
* public class InputStreamReader extends Reader
* InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节
* 并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默
* 认的字符集。
* 每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一
* 个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,
* 使其超过满足当前读取操作所需的字节。
* 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
* BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
*
* InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。
*/
//1,获取键盘录入对象
InputStream in = System.in;
//2,将字节流对象转成字符流对象。 使用转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//3,为了提高效率,将字符流进行缓冲区技术高效操作。使用 BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equalsIgnoreCase(line)){ //判断结束。
break;
}
System.out.println(line.toUpperCase());
}
bufr.close();
}
/**写入转换流
* 字符通向字节的桥梁:OutputStreamWriter
* 第三种方式:
*/
public static void method_3() throws IOException
{
//1,获取键盘录入对象
//InputStream in = System.in;
//2,将字节流对象转成字符流对象。 使用转换流InputStreamReader
//InputStreamReader isr = new InputStreamReader(in);
//3,为了提高效率,将字符流进行缓冲区技术高效操作。使用 BufferedReader
//BufferedReader bufr = new BufferedReader(isr);
/**
* 以上的写法很麻烦。
* 键盘录入的最常见的写法
*/
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//***以后凡是键盘录入都用这种写法。
//OutputStream out = System.out;
//OutputStreamWriter osw = new OutputStreamWriter(out);
//BufferedWriter bufw = new BufferedWriter(osw);
/*
* public class OutputStreamWriter extends Writer
* OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要
* 写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将
* 接受平台默认的字符集。(详情参考文档)
*/
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()); 替换为
//osw.write(line.toUpperCase()+"\r\n"); 替换为:
bufw.write(line.toUpperCase());
bufw.newLine();
/*只写这个没有显示输出。OutputStream内部使用了缓冲区,数据都被缓冲了。
* 因此要刷新
*
* 添加上了换行操作符,但是这只能让windows识别。所以还要改。
* 那么能不能使用newLine()方法呢?
*/
//osw.flush(); //但是只加上刷新输出和输入数据界面看着不爽,所以还要改。
//替换为:
bufw.flush();
}
bufw.close();
}
}
/** 6 :流操作规律
* 1,
* 源:键盘录入
* 目的:控制台。
* 2,需求:想把键盘录入的数据存储到一个文件中。
* 源:键盘
* 目的:文件
*
* 3,需求:想要将一个文件的数据打印在控制台上。
* 源:文件
* 目的:控制台。
*
* 流操作的基本规律:
* 最痛苦的就是:流对象有很多,不知道该用哪一个?
* 通过三个明确来完成:
* 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
* BufferedWriter bufw = new BufferedWriter(fw);
*
*** 扩展一下:想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
*
* 目的: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);
*
* 所以,记住,转换流什么时候使用呢?字符和字节之间的桥梁,通常,涉及到字符编码
* 转换时,需要用到转换流。
*
* 练习:将一个文本数据打印在控制台上。要按照上面格式自己完成三个明确。
*/
import java.io.*;
public class TransStreamDemo2 {
public static void main(String[] args) throws IOException
{
//need_1();
need_1();
}
/**
* 对应需求2
*/
public static void need_1() throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//***以后凡是键盘录入都用这种写法。
//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("stream.txt",true)));
//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("stm.txt")));
/*
* 第一次
*/
//BufferedWriter bufw1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("stm.txt"),"GBK"));
/*
* 第二次
*/
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("stm.txt"),"UTF-8"));
/*
* 第三次。
*/
/**以后凡是键盘输出都用这种写法。
* 写的目的地换成文件了。
*/
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line)) //判断结束。
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufw.close();
}
/**
* 对应需求3
*/
public static void need_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();
}
bufw.close();
}
}
/** 7 :改变标准输入输出设备。
*/
import java.io.*;
public class TransStreamDemo22 {
public static void main(String[] args) throws IOException
{
/**setOut和setIn能将默认的System.in的源地址和System.out的目的地址给改成
* 自己定义的文件。
*
* static void setOut(PrintStream out) 重新分配“标准”输出流。
* 能讲输出的目的给改了。
* static void setIn(InputStream in) 重新分配“标准”输入流。
* 能将输入的源地址给改了
*
*public class PrintStream extends FilterOutputStream implements Appendable, Closeable
* PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
* 它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;
* 而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,
* 可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,
* 可调用其中一个 println 方法,或写入一个换行符或字节 ('\n')。
* PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字
* 符而不是写入字节的情况下,应该使用 PrintWriter 类。
*/
/*将源给改了。
*/
//System.setIn(new FileInputStream("TransStreamDemo.java"));
/*将目的给该了
*/
System.setOut(new PrintStream("haha.html"));
/**
* 如果将以上2者结合起来,就是文件的复制了。
*/
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();
}
bufw.close();
}
}
/** 8 :流异常信息
* 自己编写的打印日志格式的异常并不好看,网上有一个log4j包,
* 专门用来处理日志的,而且格式还好看。
*/
import java.io.*;
import java.util.*;
import java.text.*;
public class ExceptionInfo {
public static void main(String[] args) throws IOException
{
try{
int[] arr = new int[2];
System.out.println(arr[3]);
}
catch(Exception e)
{
/*e.printStackTrace(); //异常信息打印到控制台上没有什么意义,
* e.printStackTrace(new PrintStream("error.txt"));
*
* public StringBuffer format(Date date,StringBuffer toAppendTo,FieldPosition pos)
* 将给定的 Date 格式化为日期/时间字符串,并将结果添加到给定的 StringBuffer。
* 下面怎么可以返回String类型呢?
*/
try{
Date t = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd,HH-mm-ss");
String s = sdf.format(t);
/*该format在系统类中的体现
public final String format(Date date)
{
return format(date, new StringBuffer(),
DontCareFieldPosition.INSTANCE).toString();
}
*/
//System.setOut(new PrintStream("exception.log"));
PrintStream ps = new PrintStream("exception.log");
ps.println(s);
System.setOut(ps);
}
catch(IOException ex)
{
throw new RuntimeException("日志文件创建失败");
}
e.printStackTrace(System.out);
}
}
}
/** 9 :打印系统信息,并保存到文件中
*/
import java.io.*;
import java.util.*;
public class SystemInfo {
public static void main(String[] args) throws IOException
{
Properties prop = System.getProperties();
//System.out.println(prop); //打印太乱。
//prop.list(System.out); //系统信息打印在了控制台,但是我想把这些信息保存在文件中。
/*
* void list(PrintStream out) 将属性列表输出到指定的输出流。
*/
prop.list(new PrintStream("systeminfo.txt"));
}
}
/**小结:
* 1,IO字节流介绍。
* 2,练习:拷贝一张图片(字符流还是字节流?)
* 3,MP3文件的复制。
* 4,缓冲区原理讲解
* 5,流的操作规律介绍。
* 6,改变标准输入输出设备
* 7,实现将流异常信息放到文件中。
* 8,将系统信息放到文件中。
*
* 注意:
* 流在使用时,一定要先区分源是什么,目的是什么,这样,
* 我们才能选用合适的流对象来操作数据。
*
*/
----------android培训、java培训、期待与您交流!----------
详细请查看:http://edu.csdn.net/heima/