黑马程序员——7.1.IO(其他对象API(System类、Runtime类、Math类、Date类)字节流与字符流、IO异常处理、缓冲区、键盘录入、转换流、异常日志、流的操作总结)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

System类:

System类中的字段和方法都是静态的。

常见方法:
long currentTimeMillis();
获取当前时间的毫秒值,可以通过此方法检测程序的执行时间。

public class SystemDemo{
    public static void main(String[] args){
        long l1 = System.currentTimeMillis();
        System.out.println(l1);

        code...

        long l2 = System.currentTimeMillis();

        //两个时间相减,得到程序的运行时间
        System.out.println(l2-l1);
    }
}

Properties getProperties();
确定当前的系统属性。

Properties集合中存储的都是String类型的键和值。
最好使用它自己的存储和取出的方法来完成元素的操作。

import java.util.*;

public class SystemDemo{
    public static void main(String[] args){

        //获取系统的属性信息,并存储到了Properties集合中
        Properties prop = System.getProperties();

        //获取Properties集合中的name集合
        Set<String> nameSet = prop.stringPropertyNames();

        //通过name获取value
        for(String name : nameSet){
            String value = prop.getProperty(name);
            System.out.println(name + " = " + value);
        }
    }
}

给属性设置一些属性信息,这些信息是全局的,其他程序都可以使用。例:System.setPeroperty(“myclasspath”,”c:\myclass”);。

Runtime类:

每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。应用程序不能创建自己的 Runtime 类实例。

P.S.
Runtime:没有构造方法摘要,说明该类不可以创建对象。又发现还有非静态的方法,说明该类应该提供静态的返回该类对象的方法。而且只有一个,说明Runtime类使用了单例设计模式。

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

        //通过该类的静态方法获取Runtime对象
        Runtime r = Runtime.getRuntime();

        //使用该对象调用程序打开软件,并返回一个控制进程的Process实例对象
        Process p = r.exec( "notepad.exe D:\\code\\day20\\RuntimeDemo.java");

        Thread.sleep(5000);

        //杀掉子进程
        p.destroy();
    }
}

Math类:

提供了操作数学运算的方法,都是静态的。

常用方法:
ceil():返回大于参数的最小整数。
floor():返回小于参数的最大整数。
round():返回四舍五入的整数。
pow(a,b):a的b次方。

Date、DateFormat类:

import java.util.*;

public class DateDemo{
    public static void main(String[] args){

        //将当前日期和时间封装成Date对象
        Date date1 = new Date();
        System.out.println(date1);

        //将指定毫秒值封装成Date对象
        Date date2 = new Date(1405244787235l);
        System.out.println(date2);
    }
}

日期对象和毫秒值之间的转换

毫秒值–>日期对象:

  1. 通过Date对象的构造方法 new Date(timeMillis);
  2. 还可以通过setTime设置。
    因为可以通过Date对象的方法对该日期中的各个字段(年月日等)进行操作。

日期对象–>毫秒值:

  1. getTime方法。因为可以通过具体的数值进行运算。

对日期对象进行格式化:
将日期对象–>日期格式的字符串。
使用的是DateFormat类中的format方法。

import java.text.*;
import java.util.*;

public class DateDemo{
     public static void main(String[] args){
        Date date = new Date();

        //获取日期格式对象,具备着默认的风格。也可以指定为FULL、LONG风格。
        DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);

        //使用DateFormat对象格式化date
        String str_date1 = df.format(date);
        System.out.println(str_date1);

        df = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.LONG);
        String str_date2 = df.format(date);
        System.out.println(str_date2);

        //如果风格是自定义的如何解决呢?
        //创建自定义格式的DateFormat对象
        df = new SimpleDateFormat("yyyy--MM--dd" );

        //格式化date
        String str_date3 = df.format(date);
        System.out.println(str_date3);
    }
}

将日期格式的字符串–>日期对象。
使用的是DateFormat类中的prase方法。

import java.text.*;
import java.util.*;

public class DateDemo{
    public static void main(String[] args) throws Exception {
        String str_date1 = "2012年4月19日" ;
        String str_date2 = "2012--4--19";

        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);

        //把符合该格式的字符串日期转换成Date对象
        Date date1 = dateFormat.parse(str_date1);
        System.out.println(date1);

        dateFormat= new SimpleDateFormat("yyyy--MM--dd" );
        Date date2 = dateFormat.parse(str_date2);
        System.out.println(date2);
    }
}

IO中的流分为字节流和字符流两大类

字节流:

可以对各种数据流进行操作

    抽象基类:InputStream,OutputStream

字符流:

基于字节流,为了文字编码转换方便而产生的流,只适用于有文字编码的情况

    抽象基类:Reader,Writer

其中各子类都是以父类名结尾,前缀名为该子类功能

FileWriter:专门用于操作文件(File)的字符写入流(Writer)

//该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖
FileWriter fw = new FileWriter("demo.txt");

//传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写
FileWriter fw = new FileWriter("demo.txt",true);

//调用write方法,将字符串写入到流中。
fw.write("abcde");

//刷新流对象中的缓冲中的数据,将数据刷到目的地中
fw.flush();

//关闭流资源,但是关闭之前会先调用一次flush刷新一次内部的缓冲中的数据
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭
fw.close();

FileReader:专门用于操作文件(File)的字符读取流(Reader)

//创建一个文件读取流对象,和指定名称的文件相关联
//要保证该文件是已经存在的,如果不存在,会发生FileNotFoundException异常
FileReader fr = new FileReader("demo.txt");

//读一个字符,会自动往下读,读到结尾返回-1
fr.read();
int ch = 0;

//调用read方法循环读取文件数据并打印,读到结尾时结束循环
while((ch=fr.read())!=-1)
{
    System.out.println("ch="+(char)ch);
}

//定义一个字符数组。用于存储读到字符
char[] buf = new char[1024];
int num = 0;

//read(char[]):将字符读入数组;返回的是读到的字符个数,如果到达流的末尾返回-1
while((num=fr.read(buf))!=-1)
{
    //将buf转成字符串输出
    System.out.println(new String(buf,0,num));
}

IO异常处理:因为IO中容易出现异常,所以需要进行异常处理

标准IO异常处理方式:
import java.io.*;
class FileWriterDemo2
{
    public static void main(String[] args) 
{
        //try与finally使用了同一个FileWriter对象,因此要在try外定义全局对象
        FileWriter fw = null;  

        try
        {
            //创建文件可能发生异常,要try
            fw = new FileWriter("demo.txt");
            fw.write("abcdefg");
        }

        //定义异常处理方式(要定义具体的处理方式,不能单单打印一下错误信息;要catch具体的异常对象,不能只简单catch父类;需要时可以定义多个catch)
        catch (IOException e)
        {
            System.out.println("catch:"+e.toString());
        }

        //IO的finally一般用于关闭流
        finally
        {
            //流一定要关闭,但也可能出现异常,也要try
            try
            {
                //前面也可能创建对象不成功,因此要判断一下
                if(fw!=null)
                    fw.close(); 
            }
            catch (IOException e)
            {
                System.out.println(e.toString());
            }
        }       
    }
}

字符流的缓冲区:

缓冲区的出现是为了提高流的操作效率而出现的。
所以在创建缓冲区之前,必须要先有流对象。

字符流缓冲区类:BufferReader、BufferWriter

BufferedWriter:

import java.io.*;
class BufferedWriterDemo
{
    public static void main(String[] args) throws IOException
    {
        //创建一个字符写入流对象。
        FileWriter fw = new FileWriter("buf.txt");

        //为了提高字符写入流效率。加入了缓冲技术。
        //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
        BufferedWriter bufw = new BufferedWriter(fw);

        //循环写入数据
        for(int x=1; x<5; x++)
        {
            bufw.write("abcd"+x);

            //该缓冲区中提供了一个跨平台的换行符newLine()
            bufw.newLine();

            bufw.flush();
        }

        //记住,只要用到缓冲区,就要记得刷新。
        //bufw.flush();

        //其实关闭缓冲区,就是在关闭缓冲区中的流对象。
        bufw.close();
    }
}

BufferedReader:

import java.io.*;
class BufferedReaderDemo
{
    public static void main(String[] args) throws IOException
    {
        //创建一个读取流对象和文件相关联。
        FileReader fr = new FileReader("buf.txt");

        //为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
        BufferedReader bufr = new BufferedReader(fr);

        String line = null;

        //该缓冲区提供了一个一次读一行的方法readLine()
        //当返回null时,表示读到文件末尾。
        while((line=bufr.readLine())!=null)
        {
            System.out.print(line);
        }
        bufr.close();
    }
}

练习:
/*
通过缓冲区复制一个.java文件。
*/

import java.io.*;
class  CopyTextByBuf
{
    public static void main(String[] args) 
    {
        //在try外定义全局对象
        BufferedReader bufr = null;
        BufferedWriter bufw = null;

        try
        {
            //在try里面进行实例化
            bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
            bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));

            String line = null;

            //循环读取文件数据直到结尾
            while((line=bufr.readLine())!=null)
            {
                //将数据写入缓冲区
                bufw.write(line);

                //readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符,因此要用到newLine()
                bufw.newLine();

                bufw.flush();
            }
        }

        //定义异常处理方式
        catch (IOException e)
        {
            throw new RuntimeException("读写失败");
        }

        //在finally中关闭输入输出流
        finally
        {
            //关闭流可能出现异常,要try
            try
            {
                if(bufr!=null)
                    bufr.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("读取关闭失败");
            }

            //就算其中一个流关闭失败,另一个流也要进行关闭动作。因此要分开try
            try
            {
                if(bufw!=null)
                    bufw.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("写入关闭失败");
            }
        }
    }
}

LineNumberReader:

带行号的缓冲区,默认从1开始。有读一行方法

void setLineNumber(int lineNumber)
设置当前行号。

FileInputStream:用于操作文件(File)的字节读取流(InputStream)

import java.io.*;
class FileStream
{
    public static void main(String[] args) throws IOException
    {
        readFile_3();
    }

    //一个特殊的读取方式(慎用)
    public static void readFile_3()throws IOException
    {
        //创建FileInputStream对象跟fos.txt关联
        FileInputStream fis = new FileInputStream("fos.txt");

        //定义一个刚刚好的缓冲区。不用在循环了。
        //此方法慎用,内存可能不够用
        //available():返回字节数
        byte[] buf = new byte[fis.available()];

        //将字节读入数组中
        fis.read(buf);

        //将数组转换成字符串进行打印输出
        System.out.println(new String(buf));

        fis.close();
    }

    //一般还是用这种方法
    public static void readFile_2()throws IOException   
    {
        FileInputStream fis = new FileInputStream("fos.txt");

        //定义一个1024的字节数组
        byte[] buf = new byte[1024];

        int len = 0;

        //循环读取字节数据
        while((len=fis.read(buf))!=-1)
        {
            //将字节数组转换成字符串输出
            System.out.println(new String(buf,0,len));
        }

        fis.close();
    }
}

读取键盘录入:

System.in:对应的标准输入设备:键盘。
System.out:对应的是标准输出设备,控制台。

System.in是个阻塞式方法

class ReadIn
{
    public static void main(String[] args) throws IOException
    {
        //把System.in跟InputSream关联起来
        InputStream in = System.in;

        //创建缓冲区StringBuilder
        StringBuilder sb = new StringBuilder();

        while(true)
        {
            //定义ch存储读取到的数据
            int ch = in.read();

            //判断是否是换行标记
            if(ch=='\r')
                continue;
            if(ch=='\n')
            {
                //把缓冲区中数据转换成字符串
                String s = sb.toString();

                //判断为over时结束循环
                if("over".equals(s))
                    break;

                //否则把数据转换成大写
                System.out.println(s.toUpperCase());

                //转换完之后把缓冲区中的数据删除
                sb.delete(0,sb.length());
            }

            //不是换行就把数据写入缓冲区
            else
                sb.append((char)ch);
        }
    }
}

改变默认输入输出方式:

System.setIn(new FileInputStream(“PersonDemo.java”));

System.setOut(new PrintStream(“zzz.txt”));
转换流:

用于字节流与字符流之间的转换,当字节流中的数据都是字节时,转换成字节流操作更加高效。
也用于不同字符编码之间的转换

对应的类:
InputStreamReader:字节流转成字符流,解码。
OutputStreamWriter:字符流转成字节流,编码。

class TransStreamDemo
{
    public static void main(String[] args) throws IOException
    {
        //获取键盘录入对象。
        //InputStream in = System.in;
        //将字节流对象转成字符流对象,使用转换流。InputStreamReader
        //InputStreamReader isr = new InputStreamReader(in);
        //为了提高效率,将字符串进行缓冲区技术高效操作。
        //BufferedReader bufr = new BufferedReader(isr);

        /*键盘的最常见写法。*/
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

        //创建标准输出流对象
        //OutputStream out = System.out;
        //将字节流对象与字符流对象关联起来,将字符流转换成字节流输出
        //OutputStreamWriter osw = new OutputStreamWriter(out);
        //为了提高效率,加入缓冲区技术
        //BufferedWriter bufw = new BufferedWriter(osw);

        /*标准输出的最常见写法。*/
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

        String line = null;

        //循环录入键盘输入的数据
        while((line=bufr.readLine())!=null)
        {
            //录入数据为“over”时跳出循环
            if("over".equals(line))
                break;

            //否则把数据变成大写
            bufw.write(line.toUpperCase());

            bufw.newLine();

            bufw.flush();
        }
        bufr.close();
    }
}

转换流还可以指定码表

用指定的编码格式编码解码:
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“d.txt”),”UTF-8”);
InputStreamReader isr = new InputStreamReader(System.in,”gbk”);

如果要访问不同编码格式的网站,只需要对数据流进行一次解码跟一次编码就可以了

异常日志:

异常日志简单来说就是把发生的异常信息存储到文件里面保存起来,要注意的是应该要带上时间

import java.io.*;
import java.util.*;
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的时候除了处理异常还要保存异常信息
        catch (Exception e)
        {
            //保存异常信息时也可能出现异常,也要try
            try
            {
                //创建日期对象
                Date d = new Date();

                //创建日期模版格式对象
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                //让模版格式化日期对象
                String s = sdf.format(d);

                //创建exeception.log错误日志文件并与打印流关联起来
                PrintStream ps = new PrintStream("exeception.log");

                //往打印流中输入格式化后的时间(自动刷新到文件中)
                ps.println(s);

                //把打印流设置为默认输出流
                System.setOut(ps);
            }
            catch (IOException ex)
            {
                //创建异常日志失败时的处理方式
                throw new RuntimeException("日志文件创建失败");
            }

            //往默认输出流中输出异常信息
            e.printStackTrace(System.out);
        }
    }
}

流的操作规律

之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。
想要知道对象的开发时用到哪些对象,只要通过四个明确即可。

  1. 明确源和目的
    源:InputStream Reader
    目的:OutputStream Writer

  2. 明确数据是否是纯文本数据
    源:是纯文本:Reader
    否:InputStream
    目的:是纯文本:Writer
    否:OutputStream
    到这里,就可以明确需求中具体要使用哪个体系。

  3. 明确具体的设备
    源设备:
    硬盘:File
    键盘:System.in
    内存:数组
    网络:Socket流
    目的设备:
    硬盘:File
    控制台:System.out
    内存:数组
    网络:Socket流

  4. 是否需要其他额外功能
    是否需要高效(缓冲区):
    是,就加上buffer

什么时候使用转换流呢?

  1. 源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本操作的便捷。
  2. 一旦操作文本涉及到具体的指定编码表时,必须使用转换流。

/*
需求:复制一个文本文件
*/

  1. 明确源和目的。
    源:InputStream Reader
    目的:OutputStream Writer
  2. 是否是纯文本?
    是!
    源:Reader
    目的:Writer
  3. 明确具体设备。
    源:
    硬盘:File
    目的:
    硬盘:File
    FileReader fr = new FileReader(“a.txt”);
    FileWriter fw = new FileWriter(“b.txt”);
  4. 需要额外功能吗?
    需要,高效
    BufferedReader bufr = new BufferedReader(new FileReader(“a.txt”));
    BufferedWriter bufw = new BufferedWriter(new FileWriter(“b.txt”));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值