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——用于提高效率