背景
在学习io的时候,都会讲到标准输入输出的东西。这里将最容易出现的几个问题整理一下,方便以后的使用和参考。
命令行程序的特点:
命令行参数解析
从System.in中按每行进行数据读取
程序示例
我们先给出一个最简单的例子,然后加入变化。
原始
这个例子实现了一个读取Systrem.in的每一行,并处理第一行的小程序(我们的处理方式就是把它们都打印出来)。
import java.io.*;
import wy.tools.log.P;
import wy.tools.regexp.Regexp;
public class ReadLineFromSystemIn {
/**
* 从System.in中读取每行
* @param args
*/
public static void main(String[] args) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bis = new BufferedReader(isr);//转成buffered才有读行的能力
String s;
try {
s = bis.readLine();
while(null != s) {
handleLine(s);
s = bis.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void handleLine(String s) {
P.rintln("read line:" + s);
}
}
这里有个要说明的地方就是关于流的关闭问题,应该写在finally中来确保一定会被执行,如果写一try中可以会由于前面代码出现异常后没有执行close,程序不断的进行这个流程应会不断的吞噬系统资源,后果严重。
变化1 如果输入exit程序自动结束
private static void handleLine(String s) {
if (Regexp.isMatch("exit", s))
closeApp();
P.rintln("read line:" + s);
}
private static void closeApp() {
System.exit(0);
}
需要将handleLine进行修改,使用System.exit(0)表示程序主动的正常退出。
变化2 加入行号的读取功能
public static void main(String[] args) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);//转成buffered才有读行的能力
LineNumberReader lnr = new LineNumberReader(br); //支持行号读取的装饰器
String s;
try {
s = lnr.readLine();
int lineNumber = lnr.getLineNumber();
while(null != s) {
handleLine(s,lineNumber);
s = lnr.readLine();
lineNumber = lnr.getLineNumber();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
lnr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void handleLine(String s, int lineNumber) {
if (Regexp.isMatch("exit", s))
closeApp();
P.rintln("read line " + lineNumber + ": " + s);
}
读取行号就要使用LineNumberReader装饰器,里面提供了getLineNumber()的方法。
注意:系统每调用一次readLine()会自动加行号,所以在readLine之后调用就可心得到从1开始的行号。