Java IO流--字符流

来源:互联网 发布:linux删除文件夹还存在 编辑:程序博客网 时间:2024/06/05 00:27

其它对象API

System类

System类中的字段和方法都是静态的,用来描述一些系统信息
Properties getProperties():获取系统属性信息,返回的是一个Properties对象
long currentTimeMillis():获取当前时间的毫秒值,可以通过此方法检测程序的执行时间。
out:标准输出,默认是控制台
in:  标准输入,默认是键盘
class Demo1System {public static void main(String[] args) {//因为Properties是HashTable的子类,也就是Map集合的一个子类对象,所以能用map集合里的方法//该集合中存储都是字符串,没有泛型定义Properties prp = System.getProperties();for(Object obj : prp.keySet()) { //简写了Set<String> s = prp.keySet();String value = (String) prp.get(obj);  //没有定义泛型所以要向下转型System.out.println(value+"="+obj);}}}

Runtime类

该类并没有提供构造函数,说明不可以new对象,那么会直接想到该类中的方法都是静态的。发现该类中还有非静态方法,说明该类肯定会提供了方法获取本类对象。而且该方法是静态的,并返回值类型是本类类型。(单例设计模式)
static Runtime getRuntime():获取对象
class Demo2Runtime {public static void main(String[] args) throws Exception {Runtime runt = Runtime.getRuntime();Process p = runt.exec("notepad.exe");  //exec()运行电脑里面的某一个程序p.destroy();  //销毁该进程}}

Date类

import java.util.*;import java.text.*;class Demo3Date {public static void main(String[] args) {Date d = new Date();System.out.println(d);  //打印时间SimpleDateFormat date = new SimpleDateFormat("yyyy年MM月dd日 E hh:mm:ss");   //创建一个SimpleDateFormat对象,自定义时间显示模式System.out.println(date.format(d));  //调用format方法让模式格式化制定Date对象long l = System.currentTimeMillis();Date d1 = new Date(l);  //new Date()可以传入毫秒值System.out.println("d1:"+d1);}}

毫秒值-->日期对象:
1. 通过Date对象的构造方法 new Date(timeMillis)
2. 还可以通过setTime设置.
日期对象-->毫秒值
1. getTime方法

Calendar类

Calendar 类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
import java.util.*;class Demo4Calendar {public static void main(String[] args) {Calendar cal = Calendar.getInstance(); //获取对象//查表法,定义包含12个月的数组,和一个星期七天的数组String[] mons = {"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六",};int m = cal.get(Calendar.MONTH);  //获取现在的月份-1int d = cal.get(Calendar.DAY_OF_WEEK);  //获取当前星期的第几天(西方每个星期第一天从星期日算起)System.out.println(cal.get(Calendar.YEAR)+"年");  //获取当前年份//System.out.println(cal.get(Calendar.MONTH)+1+"月");System.out.println(mons[m]);   //通过查表法,把获得值传入System.out.println(cal.get(Calendar.DATE)+"日");//System.out.println("星期"+(cal.get(Calendar.DAY_OF_WEEK)-1));System.out.println(weeks[d]);}}

import java.util.*;class Demo5Calendar {public static void main(String[] args) {Calendar cal = Calendar.getInstance();                //对日期进行操作cal.set(2016,11,1);   //修改日期为2016年12月1日cal.add(Calendar.YEAR,+2);  //2016的两年后printCalendar(cal);}public static void printCalendar(Calendar c) {//Calendar cal = Calendar.getInstance();String[] mons = {"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六",};int m = c.get(Calendar.MONTH);int d = c.get(Calendar.DAY_OF_WEEK);System.out.println(c.get(Calendar.YEAR)+"年");System.out.println(mons[m]);System.out.println(c.get(Calendar.DAY_OF_MONTH)+"日");System.out.println(weeks[d]);}}

Math类

Math:提供了操作数学运算的方法,都是静态的
常用方法:
ceil():       返回大于参数的最小整数。
floor():      返回小于参数的最大整数。
round():   返回四舍五入的整数。
pow(a,b):a的b次方
import java.util.Random;class Demo6Calendar {public static void main(String[] args) {double d1 = Math.ceil(11.1);  //ceil返回大于指定数据的最小整数。double d2 = Math.floor(12.9);   //floor返回小于指定数据的最大整数。long l = Math.round(8.7); //四舍五入int r = (int)(Math.random());  //取一个随机数的一种方式,调用Math类里面的random()方法//获取随机数的另外一种方式,创建一个Random对象Random ran = new Random();int ra = ran.nextInt(10)+1;System.out.println(d1);System.out.println(d2);System.out.println(l);System.out.println(r);System.out.println(ra);}}

IO流概述

IO流是用来操作数据的,处理设备之间的的数据的传输,输入流和输出流。

将外设中的数据读取到内存中:输入。
将内存的数写入到外设中:输出。
流按操作数据分为两种:字节流与字符流

字符流的由来:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。再对这个文字进行操作。简单说:字节流+编码表。
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer

Writer

字符输出流
特点演示:
在硬盘上,创建一个文件并写入一些文字数据。
FileWriter。 ,后缀名是父类名。,前缀名是该流对象的功能。
思路:创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。
    而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
    其实该步就是在明确数据要存放的目的地。
import java.io.*;class Demo1FileWriter {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("D:\\Material\\Java\\IO\\WritDemo.txt");  //创建一个FileWriter对象,并明确被操作的文件fw.write("abcdefg");  //调用write方法,将字符串写入到流中。//fw.flush();  //调用flush方法,刷新流对象中缓冲的数据,并且将数据存到目标中fw.close();  //关闭流资源,但是关闭之前会刷新缓冲的数据,并存入数据}}

IO异常的处理方式:
class Demo2FileWriter {public static void main(String[] args) {FileWriter fw = null; //建立一个引用,finally里面要用到try {fw = new FileWriter("WriterDemo.txt");fw.write("I love Java");}catch(IOException e) {System.out.println(e.toString());}finally {  //因为不管有没有发生异常都要对流进行关闭,所以写在finally中try{if(fw != null)        //判断对象是否为空。fw.close();  //因为调用close()也会有异常,所以还要再次处理}catch(IOException e) {System.out.println(e.toString());}}}}
对已有文件的数据续写:
import java.io.*;class Demo3FileWriter {public static void main(String[] args) {FileWriter fw = null;try {fw = new FileWriter("WriterDemo.txt",true);  //在构造函数中,加入true表示对该文件续写fw.write("\r\nI love world");  //windows中换行 只能识别\r\n}catch(IOException e) {System.out.println(e.toString());}finally {if(fw != null) {try {fw.close();}catch(IOException e) {System.out.println(e.toString());}}}}}

Reader

字符输入流
特点演示:
从硬盘上读取一个文件,并打印到控制台。
FileReader
第一种方式:
import java.io.*;class Demo1FileReader {public static void main(String[] args) {FileReader fr = null;try {fr = new FileReader("WriterDemo.txt"); //创建一个文件读取流对象,和指定名称的文件相关联int ch = 0;while((ch = fr.read()) != -1)  //调用read方法读取文件,一次只能读一个字符,所以通过while循环遍历,读到末尾的时候会返回-1System.out.print((char)ch);  //强制转换}catch(IOException e) {}finally {if(fr != null) {try {fr.close();}catch(IOException e) {}}}}}

第二种方式:
/*  通过read(char[])字符数组进行读取 */import java.io.*;class Demo2FileReader {public static void main(String[] args) {FileReader fr = null;try {fr = new FileReader("WriterDemo.txt");char[] buf = new char[1024]; //定义一个字符数组,用于存储读到的字符int num = 0;  //read(char[])返回的是读到的字符个数while((num = fr.read(buf)) != -1) {  //把读取到的字符存入到数组,并返回长度System.out.println(new String(buf,0,num));}}catch(IOException e) {}finally {if(fr != null) {try {fr.close();}catch(IOException e) {}}}}}
复制的原理:
需求将一个文件复制到另一个文件夹中
思路:
1、先创建两个对象,输出流与输入流,并明确要源和目的地
2、读取文件,在把读取的文件写入到目的地中
3、关闭流
import java.io.*;class TestWork {public static void main(String[] args) {FileReader bufr = null;FileWriter bufw = null;try {bufr = new FileReader("WriterDemo.txt");   //读取当前目录下的文件bufw = new FileWriter("D:\\Material\\Java\\IO\\WritDemo.txt");char[] buf = new char[1024];int len = 0 ;while((len = bufr.read(buf)) != -1) {bufw.write(buf,0,len);   //把读取到的文件写入到目的文件中}}catch(IOException e) {}finally{//创建了两个IO流,所以必须要关闭两个对象if(bufr != null) {try {bufr.close();}catch(IOException e) {}}if(bufw != null) {try {bufw.close();}catch(IOException e) {}}}}}

字符流缓冲区

缓冲区的出现提高了对数据的读写效率,在创建缓冲区之前,必须要先有流对象。
作用:在流的基础上对流的功能进行了增强

BufferedWriter

字符输出流缓冲区
import java.io.*;class Demo4BufferedWriter {public static void main(String[] args) {BufferedWriter bufw = null;  //创建一个缓冲区的引用try {bufw = new BufferedWriter(new FileWriter("BufferedWriter.txt")); //把流对象传入缓冲区for(int x = 0; x < 5 ; x++) {bufw.write("I am Buffered.Writer!");  bufw.newLine();  //newLine()跨平台换行bufw.flush();}}catch(IOException e) {}finally{if(bufw != null) {try{bufw.close();}catch(IOException e) {}}}}}

BufferedReader

字符输入流缓冲区:
该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。当返回null时,表示读到文件末尾。
注意:
readLine方法返回的时候只返回回车符之前的数据内容,并不返回回车符。
import java.io.*;class Demo3BufferedReader {public static void main(String[] args) {BufferedReader bufr = null;  //创建缓冲区引用try {bufr = new BufferedReader(new FileReader("BufferedWriter.txt"));  //传入流对象String line  = null;while((line = bufr.readLine()) != null) {  //,一次读取一行,返回的是字符串类型System.out.println(line);}}catch(IOException e) {}finally {if(bufr != null){try {bufr.close();}catch(IOException e) {}}}}}

readLine()方法原理示意图:

自定义一个缓冲区包含和readLine()一样的方法:
import java.io.*;class UserDeReader {private FileReader fr;  //建立一个FileReader引用UserDeReader(FileReader fr) {  //初始化,以便能够接受FileReader对象this.fr = fr;}public String UserDeLine() throws IOException {StringBuilder sb = new StringBuilder(); //用StringBuider容器来存储数据int ch = 0;while((ch = fr.read()) != -1) {if(ch == '\r')  //当读到'\r'的时候,用continue不执行下面语句continue;if(ch == '\n')return sb.toString();  //读到'\n'的时候把,sb转换成字符串。elsesb.append((char)ch);}if((sb.length()) != 0)   //返回之前判断一下sb里面有没有数据return sb.toString();return null;}public void UserDeClose() throws IOException {fr.close();}}//这样的设计模式我们称之为装饰设计模式class Demo5BufReaderUsDef {public static void main(String[] args) {UserDeReader udr = null;  //建立自定义缓冲区的引用try {udr = new UserDeReader(new FileReader("BufferedWriter.txt"));  //传入对象String line = null;while((line = udr.UserDeLine()) != null) {  //读取每行数据System.out.println(line);}}catch(IOException e) {}finally {if(udr != null) {try {udr.UserDeClose();}catch(IOException e) {}}}}}

装饰设计模式

当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能那么自定义的该类称为装饰类。装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。

装饰与继承的关系:
以前是通过继承将每一个子类都具备缓冲功能,那么继承体系会复杂,并不利于扩展。现在优化思想,单独描述一下缓冲内容,将需要被缓冲的对象传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单,优化了体系结构。装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类于类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常是都属于一个体系中的。

LineNumberReader

跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号
import java.io.*;class Demo6LineNumberReader {public static void main(String[] args) {LineNumberReader linenum = null;                try {linenum = new LineNumberReader(new FileReader("D:\\Material\\Java\\day19\\CopyTextByBuf.txt"));String line = null;                       //linenum.setLineNumber(50);可以设置从第几行开始while((line = linenum.readLine()) != null) {System.out.println(linenum.getLineNumber()+line);  //获取行数}}catch(IOException e) {}finally {        if(linenum != null) {                                try {                                    linenum.close;                                 }catch(IOException e) {                                }                        }}}}





0 0
原创粉丝点击