黑马程序员技术交流社区
标题:
流重新分配
[打印本页]
作者:
曹昌豪
时间:
2012-5-28 13:23
标题:
流重新分配
一直不明白System.setOut System.setIn 这俩的情况,重新分配标准输入流和标准输出流,这到底是怎么做的,搞不明白啊,所以一般回避这个,求支招!!!!!
作者:
小小企鹅
时间:
2012-5-28 17:51
System.setIn(InputStream in) 分配标准输入流为参数in指向的文件,System.in指向的就由默认的键盘改为in所指的文件
File f = new File("e:" + File.separator + "123.txt");
System.setIn(new FileInputStream(f));
InputStream in = System.in;
byte[] b = new byte[1024];
int len = in.read(b);
in.close();
System.out.println(new String(b, 0, len));
System.setOut(PrintStream out)重新分配“标准”输出流。
System.setOut(new PrintStream("文件路径"));
System.out.println("Hello World");//输出到了文件
提前定义System.in引用恢复默认键盘输入:
InputStream old = System.in;
//System.setIn();
System.setIn(old);
定义System.out的引用恢复默认显示器输出:
PrintStream out = System.out;
//System.setOut();
System.setOut(out);
作者:
揭耀祖
时间:
2012-5-28 18:04
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
以上两句中,源设备是键盘,目的是控制台。
通过System.setIn(new FileInputStream("abc.txt"));这句语句后源设备就变成了文件了,也就是硬盘。
通过System.setOut(new PrintStream("zzz.txt"));这句后目的地就由控制台变成了硬盘了。
作者:
闾丘日月
时间:
2012-5-29 01:13
感谢楼主提出的问题,我开始以为楼主要知道setIn的原理,所以查看了System的源代码,又学到一些东西,现在拿来和大家分享一下
先上有关
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}
private static void checkIO() {
SecurityManager sm = getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setIO"));
}
}
private static native void setIn0(InputStream in);
前面的checkIO很好的解释了API中的这段话。
首先,如果有安全管理器,则通过 RuntimePermission("setIO") 权限调用其 checkPermission 方法,查看是否可以重新分配“标准”输入流。
关键是这样一个setIn0,没有方法体的方法,一般如果是抽象方法的话这就能解释了,但是System这个类是final的,也就是说不能被继承,那它怎么能有抽象方法呢?
通过查找百度,发现这样一个网页写的十分详细http://karoii.bokee.com/5869823.html
以下是摘抄的其中几句。
Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
可以将native方法比作Java程序同C程序的接口,其实现步骤:
1、在Java中声明native()方法,然后编译;
2、用javah产生一个.h文件;
3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
4、将第三步的.cpp文件编译成动态链接库文件;
5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
那么这里我记住了如果要提升性能的话,我们也可以自定义native方法。不过到底怎么做到用的时候再翻也来的及。
还有一个问题是这个方法在哪里?在jdk的lib目录下的jvm.lib文件中就有这些native方法的实现,我的理解是在include目录下的.h文件中一定有这些函数
的声明,不过我怎么找都找不到,如果老师能看到希望能指教下。
至于怎么用就很简单了,而且我可以告诉lz,在System这个类中有这个函数private static void initializeSystemClass(){}
其中有一段FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
setIn0(new BufferedInputStream(fdIn));
可以看到,System初始化的时候也调用了这个函数,和上面两位同学的用法并无不同,所以我们的标准输入输出一开始就是控制台和键盘,如果改掉这些代码的话,呵呵。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2