读取键盘录入
System.out :标准输出流,对应输出设备,控制台
System.in :标准输入流,对应输入设备,键盘
public static final InputStream in System.in是InputStream字节流类型
public static final PrintStream out
需求:
通过键盘输入数据并打印其大写,当录入一行数据后就将该数据打印,如果录入over,回车后停止录入
原理:其实就是读取一行数据的原理,也就是readLine方法
readLine()方法是字符流BufferedReader;类中的方法
而键盘录入的read方法是字节流InputStream的方法,无法直接调用readLine()方法
读取键盘录入
import java.io.*; class ReadIn { public static void main(String[] args) throws IOException { InputStream in = System.in; StringBuilder sb = new StringBuilder();//创建字符串缓冲区 while (true) { int ch = in.read();//读取一个输入的字符 if(ch==' ') continue; if(ch==' ') //换行判断 { String s = sb.toString();//换行时将缓冲区转成字符串 if("over".equals(s)) break;// 当输入over时结束运行 System.out.println(s.toUpperCase());//将小写转换成大写 sb.delete(0,sb.length()); //每次输入输出后清空字符串缓冲区 } else sb.append((char)ch); //将read()返回的int值转换成字符,并添加在字符串缓冲区的末尾 } } }
将字节流转换成字符流再使用字符流缓冲区中的readLine方法;用到转换流
转换流:
InputStreamReader转换流,该类是Rreader类的子类;是字节流通向字符流的桥梁,可以将字节流转换成字节流,以便于调用字节流的方法
OutputStreamWriter转换流,该类是Writer类的子类;是字符流通向字节流得桥梁,可以将字符流转换成字节流
键盘录入转换转换步奏详解:
InputStream in = System.in; //获取键盘录入对象 InputStreamReader isr = new InputStreamReader(in);//将字节流对象转换成字符流对象 BufferedReader bufr = new BufferedReader(isr); //使用字符流缓冲区提高效率 OutputStream out = System.out; //获取控制台输出对象 OutputStreamWriter osw = new OutputStreamWriter(out);//字符通向字节流 BufferedWriter bufw = new BufferedWriter(osw); //使用
转换流应用
import java.io.*; class TransStreamDemo //转换流:字符>字节>字符 { public static void main(String[] args) throws IOException { 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; //输入over时结束操作 bufw.write(line.toUpperCase()); //写到目的地 bufw.newLine(); bufw.flush(); //osw属于Writer体系;需要刷新 } bufr.close(); bufw.close(); } }
转换操作中可以设置源和目的来控制流
System.setIn(new FileInputStream("ReadIn.java")); //设置源 System.setOut(new PrintStream("printStream.txt")); //设置目的 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//键盘录入的最常见写法,重点掌握! BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
流操作的基本规律:
流对象有很多,容易混淆(重点掌握!)通过三个明确来确定到底使用哪一个体系。
【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);
**************
3, 扩展,想要把录入的数据按照指定的编码表(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);
所以,记住。转换流什么使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时,
需要用到转换流。
练习:将一个文本数据打印在控制台上。要按照以上格式自己完成三个明确。(略)
异常日志
运用io流的知识点创建系统运行的异常日志;开发中可以使用log4j 日志工具包,这里手动实现一下
示例:
import java.io.*; import java.util.*; //Date类的包 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){ try{ Date d = new Date(); //日期类,util包 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式化时间;Text包 String s = sdf.format(d); //将格式化后的日期转成字符串 PrintStream ps = new PrintStream("Exception.log");//System.out返回的是printStream数据类型, ps.println(s); //printStream可以替代System.out; //也可使用: ps.write(d.toString().getBytes());printStreams是字节输出流OutputStream的子类,要转成byte型才能写入 System.setOut(ps);//默认对应控制台,将其指向到日志文件 } catch (IOException ioe){ throw new RuntimeException("创建日志文件失败!"); } e.printStackTrace(System.out);//将此throwable及其追踪输出到指定的输出流 } } }
系统信息
获取系统信息,并保存到文档
import java.io.*; import java.util.*;//Properties类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。 class SystemInfo { public static void main(String[] args) throws IOException { Properties prop = System.getProperties();//System类的方法:确定当前的系统属性。 // System.out.println(prop); prop.list(new PrintStream("SYSinfo.log"));//Properties类的方法;将属性列表输出到指定的输出流。 } }
流的应用小结:
流是用来处理数据的。
处理数据时,一定要先明确数据源,与数据目的地(数据汇)。
数据源可以是文件,可以是键盘。
数据目的地可以是文件、显示器或者其他设备。
而流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理.转换处理等。