黑马程序员_java基础视频第18天_与系统交互的类及IO流


---------------------- android培训java培训、期待与您交流! ----------------------


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("JAVA_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);

}

一开始自己只知道要这样写但是不知道为什么,现在明白了,
 
 
 
 
 
 
 
 

---------------------- android培训java培训、期待与您交流! ----------------------

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值