您的位置:首页 > 编程语言 > Java开发

Java IO流--字符流

2015-08-06 18:33 381 查看

其它对象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);  //获取现在的月份-1
int 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 = {"一月","二月","三月","四月","五月","六月","七月","八月","
4000
九月","十月","十一月","十二月"};
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循环遍历,读到末尾的时候会返回-1
System.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转换成字符串。
else
sb.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) {

}

}
}

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: