黑马程序员---IO(Input Output)流(键盘录入、流操作的基本规律)

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------


System.out  “标准”输出流。通常,对应于显示器输出。

实际上是一个打印流对象  public static final PrintStream out  是输出流OutputStream的子类。

 

System.in   “标准”输入流。通常,对应于键盘输入。

实际上是一个输入流对象  public static final InputStream in

 

键盘录入,录一行,打印一行:

import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		StringBuilder sb = new StringBuilder();
		while(true)
		{
			int num = System.in.read();
			if(num=='\r')
				continue;
			if(num=='\n')
			{
				String s = sb.toString();
				if(s.equals("over"))
					break;
				System.out.println(s.toUpperCase());
				sb.delete(0,sb.length());
			}
			else
				sb.append((char)num);
		}
	}
}


 

我们发现这个原理有点像字符流缓冲区的readLine()方法

下面我们就利用字符流reader的子类InputStreamReader(转换流)的构造方法,传一个字节流InputStream对象进去,将字节流转换成字符流。

代码如下:

import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		InputStream in = System.in;
		Reader r = new InputStreamReader(in);
		BufferedReader br = new BufferedReader(r);
		
		String s = null;
		while((s=br.readLine())!=null)
		{
			if(s.equals("over"))
				break;
			System.out.println(s.toUpperCase());
		}
		br.close();
	}
}

这样代码就简化了许多。

 

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

将我熟悉的字符以字节形式存储到硬盘中去。我录入的是字符,存到硬盘的是以字节形式存储的。

 字符流Writer可以直接操作字符串:

import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		//InputStream in = System.in;
		//InputStreamReader r = new InputStreamReader(in);
		//BufferedReader br = new BufferedReader(r);
		//键盘录入最常见写法:
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		//OutputStream os = System.out;
		//OutputStreamWriter w = new OutputStreamWriter(os);
		//BufferedWriter bw = new BufferedWriter(w);
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		
		String line = null;
		while((line=br.readLine())!=null)
		{
			if(line.equals("over"))
				break;
			bw.write(line.toUpperCase());
			bw.newLine();
			bw.flush();
		}
		br.close();
	}
}


 

流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪一个。

通过三个明确来完成。

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);


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

源:使用读取流(InputStream  Reader)
是不是操作纯文本文件?
不是!使用InputStream
设备:硬盘,一个文件
InputStream体系中可以操作文件的对象是FileInputStream
是否需要提高效率:是!加入InputStream体系中缓冲区BufferedInputStream


BufferedInputStream bis = new BufferedInputStream(new FileInputStream("cat.jpg"));


目的:使用写入流(OutputStream Writer)
是否是纯文本文件。
否!OutputStream
设备:硬盘,一个文件
Output体系中可以操作文件的对象FileOutputStream
是否需要提高效率:是!加入OutputStream体系中缓冲区BufferedOutputStream


BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\cat2.jpg"));

import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("cat.jpg"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\cat2.jpg"));
		int num = 0;
		while((num=bis.read())!=-1)
		{
			bos.write(num);
		}
		bis.close();
		bos.close();
	}
}


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

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-8),将数据存到文件中。
 
 目的:OutputStream  Writer
 是否是存文本?是!Writer。
 设备:硬盘。一个文件。使用 FileWriter。
 但是FileWriter是使用的默认编码表。GBK.
 
 但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。
 所以要使用的对象是OutputStreamWriter。
 而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream

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

构造方法摘要
OutputStreamWriter(OutputStream out,String charsetName)
          创建使用指定字符集的 OutputStreamWriter。

 需要高效吗?需要。
 BufferedWriter bufw = new BufferedWriter(osw);

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


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

源:InputStream Reader
是否是纯文本,是!Reader
设备:硬盘,一个文本文件,FileReader
是否需要提高效率?是!BufferedReader


BufferedReader br = new BufferedReader(new FileReader("Person.java"));


目的:OutputStream  Writer
是否是纯文本,是!Writer
设备:控制台,对应的对象是System.out
System.out 属于OutputStream,所以需要使用转换流OutputStreamWriter转换为Writer
是否需要提高效率:是!BufferedWriter


BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new FileReader("ReadIn.java"));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		String s = null;
		while((s=br.readLine())!=null)
		{
			bw.write(s);
			bw.newLine();
			bw.flush();
		}
		br.close();
		bw.close();
	}
}


改变标准输入输出设备:

在System类中提供了一个方法,可以改变标准输入输出设备:

static void setIn(InputStream in)

static void setOut(PrintStream out)

import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		System.setIn(new FileInputStream("Person.java"));
		System.setOut(new PrintStream("2.txt"));

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		String line = null;
		while((line=br.readLine())!=null)
		{
			if(line.equals("over"))
				break;
			bw.write(line.toUpperCase());
			bw.newLine();
			bw.flush();
			
		}
		br.close();
		
	}
}


异常的日志信息:

java.lang.Throwable
printStackTrace() 
          将此 throwable 及其追踪输出至标准错误流。
printStackTrace(PrintStream s) 
          将此 throwable 及其追踪输出到指定的输出流。

System.out 对应的对象就是 PrintStream 的对象

实际上第一个空参数的方法就是调用了第二个方法 printStackTrace(System.out)


java.lang.Object
  继承者 java.io.OutputStream
      继承者 java.io.FilterOutputStream
          继承者 java.io.PrintStream
构造方法摘要
PrintStream(File file)
          创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file,String csn)
          创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out)
          创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush)
          创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush,String encoding)
          创建新的打印流。
PrintStream(String fileName)
          创建具有指定文件名称且不带自动行刷新的新打印流。(使用这个)
PrintStream(String fileName,String csn)
          创建具有指定文件名称和字符集且不带自动行刷新的新打印流。

import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo 
{
	public static void main(String[] args) 
	{
		try
		{
			int[] demo = new int[2];
			System.out.println(demo[3]);
		}
		catch (Exception e)
		{
			try
			{
				Date d = new Date();
				PrintStream ps = new PrintStream("exception1.log");
				//ps.write(d.toString().getBytes());
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E HH:mm:ss");
				String time = sdf.format(d);
				ps.println(time);
				
				System.setOut(ps);
			}
			catch (IOException e2)
			{
				throw new RuntimeException("创建异常日志失败");
			}
			
			e.printStackTrace(System.out);//或者空参是一个效果
			/*
			try
			{
				e.printStackTrace(new PrintStream("exception.txt"));
			}
			catch (IOException e1)
			{
				throw new RuntimeException("创建异常日志失败");
			}
			*/
		}

	}
}

//log4j

真正生成日志文件的话,不用这么做,这么做很麻烦,

网络上有一个工具叫:log4j

把这个工具下载下来,这个工具提供很多对象,可以完成你的日志信息的建立。


系统信息:

java.lang.System
static Properties getProperties() 
                         获取当前的系统属性。

java.lang.Object
  继承者 java.util.Dictionary<K,V>
      继承者 java.util.Hashtable<Object,Object>
          继承者 java.util.Properties
list(PrintStream out)
          将属性列表输出到指定的输出流。

import java.io.*;
import java.util.*;
class SystemInfo 
{
	public static void main(String[] args) throws IOException
	{
		Properties p = System.getProperties();
		//Properties是一个Map集合,也可以使用遍历的方法打印。
		
		//System.out.println(p);//打印结果:一大堆,没有换行。

		
		//我们发现Properties这个对象可以和流相关联。
		//p.list(System.out);//打印结果有换行,格式很好看
		p.list(new PrintStream("systemInfo.txt"));//输出到文件中
	}
}

打印结果中:sun.jnu.encoding=GBK,表示:默认编码GBK。


 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值