IO流——字符流

一、字符IO类

1.基本概念

IO流用来处理设备之间的数据传输,java对数据的操作是通过流的方式。

流按操作数据分:字节流和字符流

  字符流的由来:其实就是字节流读取文字字节后,不直接操作,而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。简单说就是:字节流+编码表

流按流向分为:输入流和输出流,相对于内存设备而言。

2.IO常用基类

   (1)字节流的抽象基类

          InputStream、OutputStream

   (2)字符流的抽象基类

   Reader、Writer

注意:这四个基类派生出的子类名称都是以其父类名作为子类名的后缀,比如:InputStream的子类FileInputStream,Reader的子类FileReader。

3.实例

(1)写一些字符到文件中

因为写的是一些字符,所以使用字符流来操作。

public void CreateFile()
{
     //创建一个可以往文件中写入字符数据的字符流对象
     FileWriter fw=new FileWriter(“Demo.txt”);
    //调用Writer对象中的writer(string)方法写入数据,此时数据被写入到临时存储区了。
    fw.write("abcde");
    fw.flush();
}

(2)读取一个文本文件,将读取的字符打印出来

public void ReadFile()
{
     //创建一个可以读文件中字符数据的字符流对象
     FileReader fr=new FileReader(“Demo.txt”);
    //调用Reader对象中的read()方法写入数据,此时数据被写入到临时存储区了。
    int ch=0;
    while ((ch=fr.read())!=-1)
    {
         System.out.println((char)ch);
         ch=fr.read();
    }
    fr.close();
}

 利用字符数组,读取字符文件。

char [] buf=new char[3];
FileReader fr=new FileReader("Demo.txt");
//假设demo.txt文件中有abcde5个字符
int num=fr.read(buf);  //一次读入3个字符,所以num为3,buf中为abc
System.out.println(new String(buf)); //打印abc
int num1=fr.read(buf);  //一次读入3个字符,所以num1为2,buf中为dec
System.out.println(new String(buf)); //打印dec,因为c未被覆盖
int num2=fr.read(buf);  //一次读入3个字符,所以num3为-1,buf中为dec

//如果要输出abcde
char [] buf=new char[3];
FileReader fr=new FileReader("Demo.txt");
int num=0;
while((num=fr.read(buf))!=-1)
{
    System.out.println(new String(buf));
}
fr.close();

二、常用类

1.System

System.currentTimeMillis(),获取系统时间到1970年1月1日0时0分0秒的毫秒数。

System.getProperties() ,获取系统信息

System.setProperties(key,value),这些设置的信息是全局的,其它程序也可以用。
Runtime没有构造方法摘要,说明该类不可创建对象,但是却有非静态的方法,说明该类应该提供静态的返回该类对象的方法。而且只有一个,说明Runtime类使用了单例设计模式,即通过getRuntime()方法返回Runtime对象。

2.Runtime

Runtime r=Runtime.getRuntime();

r.exec("notepad.exe");

如果用

Process p=r.exec("notepad.exe");

Thread.sleep(5000);

r.destory();  

可以杀进程。但是只能杀它自己开启的进程。

3.Math

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

Math.ceil();

Math.floor();

Math.round();

4. Random

Random r=new Random();

r.nextInt(6);

5.Date

注意月份是0-11

(1)毫秒值转日期对象:

1.通过Date对象的构造方法 new Date(timeMillis)

2.还可以通过setTime设置

可以通过Date对象的方法对该日期中的年月日进行操作

(2)日期对象转毫秒值

getTime方法

因为可以通过具体的数值进行运算,比如时间差。

Date类的日期格式化已废弃,在jdk1.1后可用Calendar类实现日期和时间字段之间的转换,用DateFormat类来格式化和解析日期字符串。

要格式化一个当前语言环境下的日期,可使用某个静态工厂方法。

myString=DateFormat.getDateInstance().format(myDate);

将日期转成字符串

public static void show()
{
    Date date=new Date();
    //默认风格
    DateFormat dateFormat=DateFormat.getDateInstance();
    String str_date=dateFormat.format(date);
    System.out.println(str_date); //2017-10-12
    //指定风格
     dateFormat=DateFormat.getDateInstance(DateFormat.LONG);
    String str_date=dateFormat.format(date);
    System.out.println(str_date); //2017年10月12日
    //自定义风格  //利用DateFormat的子类SimpleDateFormat
     dateFormat=new SimpleDateFormat("yy-MM-dd");
    String str_date=dateFormat.format(date);
    System.out.println(str_date); //17-10-12
}

将日期格式的字符串转成对象

public static void show()
{
     //默认风格
     String str_date="2017-10-12";
     DateFormat dateFormat=DateFormat.getDateInstance();
     Date date=dateFormat.parse(str_date); 
     //指定风格
     str_date="2017年月10月12日";
      dateFormat=DateFormat.getDateInstance(DateFormat.LONG);
     date=dateFormat.parse(str_date);  
    //自定义风格
     str_date="2017----10----12";
     dateFormat=new SimpleDateFormat("yyyy----MM--dd");
     date=dateFormat.parse(str_date);
}

 6.Calendar

public static void show()
{
     Canlendar c=Canlendar.getInstance();
     int year=c.get(Canlendar.YEAR);
     int month=c.get(Canlendar.MONTH)+1;
     int day=c.get(Canlendar.DAY_OF_MONTH);
     System.out.println(year+"年"+month+"月"+day+"日");
}

 三、字符流的缓冲区

缓冲区的出现提高了对数据的读写效率,其实就是对数组及其操作进行封装。

对应类有:BufferedWriter和BufferedReader

缓冲区要结合流才可以使用

在流的基础上对流的功能进行了增强。

例如:读一个文本文件,写到另一个文件中。

public void exec()
{
     FileReader fr=null;
     FileWriter  fw=null;
     try
     {
           fr=new FileReader("1.txt");
           fw=new FileWriter("2.txt");
          //创建一个临时容量,用于缓存读到的字符
         char [] buf=new Char[4096]; //这就是缓冲区,字符缓冲区类只将其进行封装
          //定义一个变量记录读取到的字符数,(其实就是往数组里装的字符个数)
          int len=0;
          while ((len=fr.read(buf))!=-1)
         {
               fw.write(buf,0,len);
         }  
     catch(Exception e)
     {
         throw new RuntimeException("读写失败!");
     }
      finally
      {
            if (fw!=null)
               try
               {
                     fw.close();
                }
                catch(IOException e)
                {
                     e.printStackTrace();
                }
            if (fr!=null)
               try
               {
                     fr.close();
                }
                catch(IOException e)
                {
                     e.printStackTrace();
                }
      }
}

可以利用BufferedReader和BufferedWriter类,BufferedWriter类提供了newLine()方法,使用平台自己的行分隔符概念,此概念由系统属性line.separator定义。(可在System.getProperties()中查看)

public void copy_1()
{
     FileWriter fw=new FileWriter("buf.txt");
     //为了提高写入效率,使用了字符流的缓冲区。
     //创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象关联
     BufferedWriter bufw=new BufferedWriter(fw);
     //使用缓冲区的写入方法将数据写入缓冲区中
     bufw.write("abcdef");
     bufw.newLine(); //输出换行符,和系统有关,win中\r\n,linux为\n
     bufw.write("1234");
     //使用缓冲区的刷新方法将数据刷到目的地中
     bufw.flush();
    //关闭缓冲区,其实关闭的就是被缓冲的流对象fw
     bufw.close();
}

BufferedReader类中有readLline()方法。利用缓冲区对象进行文本文件拷贝,代码如下:

public void copy_buf()
{
       FileReader fr=new FileReader("1.txt");
       BufferedReader bufr=new BufferedReader(fr);

       FileWriter fw=new FileWriter("2.txt");
       BufferedWriter bufw=new BufferedWriter(fw);

       String line=null;
       while ((line=buffer.readLine())!=null)
       {
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
       }
       bufr.close();
       bufw.close();
}

 Writer有一个继承体系:

 Writer

    | ---TextWriter——用于操作文本

    |----MediaWriter——用于操作媒体。

    |----BufferWrited——用于提高效率

 

posted @ 2017-10-11 20:52  jsddj  阅读(561)  评论(0编辑  收藏  举报