您的位置:首页 > 编程语言 > Java开发

Java I/O流操作(一)---入门篇和System和Properties类介绍

2013-03-23 16:58 489 查看
System和Properties类:

主要介绍了System类的用法 通过java API可以很详细了解System类的用法:API文档使我们学习的最好帮手:
System是final的 所以可以看出他不允许别人去修改的,如果不是final的别人就可以extends,就可以覆写他的方法了.



下面就对上面的javaAPI 片段做简单的介绍
这个System类包含了一些有用的服务类字段和方法,他不能实例化,也就是说他的构造方法是私有的,
System类提供了一些标准输出输入流和错误输出流,



而且还提供copy数组的方法如:



下面就上面的的功能来做一些具体的应用:
输出环境变量
Properties properties = System.getProperties();

//获取所有的系统环境变量

for (Object key : properties.keySet()) {

String value = (String)properties.get(key);

System.out.println(key+" ---> "+value);

}

//获取某个系统环境变量

String value = properties.getProperty("java.vm.version");

System.out.println(value);

//自定义一些系统环境变量

properties.setProperty("myPro", "my system properties");

System.out.println(properties.getProperty("myPro"));
又如:
public class TestSystem

{

public static void main(String[] args) throws Exception

{

//获取系统所有的环境变量

Map<String,String> env = System.getenv();

for (String name : env.keySet())

{

System.out.println(name + " ------> " + env.get(name));

}

//获取指定环境变量的值

System.out.println(System.getenv("J***A_HOME"));

//获取所有的系统属性

Properties props = System.getProperties();

//将所有系统属性保存到props.txt文件中

props.store(new FileOutputStream("props.txt") , "System Properties");

//输出特定的系统属性

System.out.println(System.getProperty("os.name"));

}

}



Runtime类:
Runtime代表java程序的运行是环境,每一个java程序都有一个与之对应的Runtime实例 ,应用程序通过该对象与运行时环境相连.正如API文档所说.



从上可得知,该类是不能直接实例化的,但是可以通过getRumtime方法获取实例,这是明显的单例模式singleton 既然一个java程序对应一个Runtime所以在一个java程序中只能存在一个RUntime,所以是单例的.
查看API可以得到一些常用的方法:
public class TestRuntime

{

public static void main(String[] args)

{

Runtime rt = Runtime.getRuntime();

System.out.println("处理器数量:" + rt.availableProcessors());

System.out.println("空闲内存数:" + rt.freeMemory());

System.out.println("总内存数:" + rt.totalMemory());

System.out.println("可用最大内存数:" + rt.maxMemory());

}

}
而且还可以打开程序
public class TestExec

{

public static void main(String[] args)throws Exception

{

Runtime rt = Runtime.getRuntime();

Process p = rt.exec("notepad.exe");
// p.destroy();关闭进程

}

}
而且可以打开某个特定的文件如
rt.exec("notepad.exe SystemTest.java");


IO的基本操作:
流的分类:
输入流:只能从中读取数据,主要以InputStream和Reader作为基类。
输出流:只能向其写数据,主要以OutputStream和Writer作为基类。
字节流和字符流操作方式几乎一样,区别只是数据单元有区别而已,字节流操作的单元是字节,字符流操作的单元是字符。
输入输出流的体系:



首先来看一下FileWriter是一个字符输出流,
FileWriter fw =new FileWriter("test.txt");//指定输出流操作的文件
当我们往该文件写数据的时候fw.writer("test");
运行可以到文件依然没有数据,可是我们明明已经写了,这是因为我们写的数据还是在内存中,没有写到磁盘上,我们需要通过fw.flush方法把内存中的数据刷新到目的,或者通过close方法,因为close方法内部也是先调用flush方法再调用close方法的.
还要注意的是,如果我们指定的文件在磁盘中已经存在那么,这个文件将被覆盖.
public class FileWriterTest{
public static void main(String[] args) throws Exception{
FileWriter fw= new FileWriter("test.txt");
fw.writer("asdf");
fw.close();
}
}
上面的程序有一个不足就是没有进行IO异常处理:
在main方法的3行主要代码,都有可能抛出异常
所以应该try catch一下

public class FileWriterTest{
public static void main(String[] args) {
try{
FileWriter fw= new FileWriter("test.txt");//在磁盘创建test.txt文件,如果存在就覆盖
fw.writer("asdf");
fw.close();
}catch(IOException e){
System.out.println(e.toString());//但是在正真的开发中是不能这样的而是要做一些实际的处理
}finally{//我们知道finally一般用来关闭资源的
try{
fw.close();
}catch(IOException e){
System.out.println(e.toString());//但是在正真的开发中是不能这样的而是要做一些实际的处理
}
}
}
}
但是编译的时候还是会报错,说找不到fw变量,因为fw在try块里面,那么为什么在try块里面就找不到fw呢?因为在 FileWriter fw= new FileWriter("test.txt");代码前可能还有代码如果这些代码报异常的话那么就执行不到 FileWriter fw= new FileWriter("test.txt");了,所以必须把FilwWriter定义在try前面.

还要注意的是,我们为了保证程序的健壮性,在关闭资源的情况下要判断fw时候为null,所以在这里我们可以总结,调用一个方法我们要注意,我们首先要考虑方法的调用者是否存在,如果这个方法有参数,我们还要判断参数是否存在,这两点在编写程序的时候要注意.可以增前的程序的健壮性.不要程序动不动就抛异常.

事实上,异常机制的存在就是为了让程序有更好的健壮性.
我们知道上面的程序不能实现文件的续写,因为如果文件存在则会被覆盖,我们怎么实现文件的续写呢?
查看API文档:



boolean类型 的参数就是暗示是否在已有的文件上append.

public static void main(String[] args) {
FileWriter fw =null;
try {
fw =new FileWriter("test.txt",true);
fw.write("hello!");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (fw!=null) {
fw.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
执行前的文件内容:



文件的读取FileReader类



从上面的API可以看出当文件读完了后会返回-1 并且他的返回值是int 如果文本文件里面是字符需要baint转为char.
这样就有了循环条件了,这个类很简单,看来API都可以使用.这里就不举例子了.


文件读取方式



在上面的两个读取方法虽然他的返回值虽然相等,但是它们的意义是不一样的
没有参数的read()方法是读取单个字符,返回的内容的int形式,
有参数的read()方式是把读取到的内容放进字符数组.返回的是读取的个数.










发现长度不足字符数组的长度,就用框号代替
如果程序改成这样就不会出现这样的情况了

fr = new FileReader("test.txt");
char[] buffer = new char[10];
int length = 0;
while((length=fr.read(buffer))!=-1){
System.out.println("length="+length+" --- content="+new String(buffer,0,length));
}
表示读取到了多长就写多长.
这下才明白为什么自己在编写复制文件的程序时候需要这样写

byte[] buffer = new byte[1024];
int length = 0;
while ((length=is.read(buffer))!=-1) {
os.write(buffer, 0, length);
}

转载请注明出处 :
/article/3711883.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: