Java基础——其他类对象,IO流
2015-07-30 16:03
579 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
out:标准输出,默认是控制台
in :标准输入,默认键盘
描述系统的一些信息。
获取系统属性信息:Propertise getPropertises();
运行结果:
既然能获取,就可以设置
setProperty(String key,String value)
获取单个系统信息的方法:String getProperty(String key);
如果参数输入一个不存在的键的话,输出的就是null
那么怎么样在jvm启动的时候就动态的加载一些系统信息呢?
java命令中有这样的指令:
-Dname = value 设置一个系统属性
命令行这样写:
java -Dhahaha=qqqqqq SystemDemo
//就是指定一个键为hahaha 值为qqqqqq的系统信息。
再次执行上边的代码,就会出现这样的结果:
结果发现,在查看hahaha对应的值的时候,可以打印出来该键对应的值。
该类中并没有提供构造函数。说明不可以new对象,那么会直接想到该类中的方法都是静态的。
发现该类中还有非静态方法
说明该类肯定会提供了方法获取本类对象,而且该方法是静态的,并且返回值类型是本类对象。
由这个特点,可以看出该类使用了单例设计模型
下面看一个练习
运行结果为:
运行结果可以看到,程序运行时打开一个空白的记事本程序,4秒之后,记事本程序自动关闭。
然而Runtime类的强大之处还在于:
运行结果:
运行结果显示,打开的记事本程序自动打开了一个SystemDemo.java的文件。
同样的道理,使用Runtime对象如果打开了一个播放器后边跟上一个视频文件,运行程序的时候就会直接播放视频了。
以上代码中写的记事本程序没有写路径,是因为在path中有System32,jvm会先在当前目录下找,如果找不到就在path路径下找,如果再找不到,就会抛出异常,
所以在使用Runtime对象打开本地程序的时候最好加上完整路径。
由Runtime对象开启的本地程序,java可以获取到他的进程对象Process对象,并且关闭掉他,
如果进程不是java打开的,java是拿不到他的进程对象的,也关不掉进程。
可以获取当前的时间
运行结果为:
想要得到自己想要的时间模式,需要创建简单时间格式(SimpleDateFormat)对象,
在构造函数的时候就给定想要的时间的格式,
再用该时间模式的对象调用format 方法,将时间对象d传进去,
就得到了想要的时间。
以上代码中,获取到的年份的值已经变成了一个字符串,没有办法再进行有关年的其他运算,(严格来说也有,Integer.parseInt(),)和调用年的方法。
方法二:
运行结果:
演示set和add方法
运行结果:
练习1:算出指定年份的2月一共有多少天?
运行结果:
练习2:算出昨天的现在的时间点?
运行结果为:
里边都是静态方法。
Math.floor();返回小于该参数的最大整数
Math.round(double d);四舍五入,返回值为long类型的。
Math.pow(double a,double b);求a的b次方,返回值为double
random方法:随机的返回一个大于等于0,且小于1的数。double类型的。
如果想要获取从1到10范围内的十个随机整数呢?
简单:
其实,想要获得以上者样的数字组合,还有另一中方法就是使用util包中的Random类。
运行结果为:
练习:给定一个小数,要求保留小数的后两位。
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按照操作数据分为两种:字节流与字符流
流按流向分为:输入流,输出流。
IO流常用的基类
字节流的抽象基类
InputStream,OutputStream
字符流的抽象基类:
Reader,Writer
注意:由这四个类派生出来的子类名称都是以其父类作为子类名的后缀。
如:InputStream的子类FileInputStream.
如:Reader的子类FileReader
既然IO流是用于操作数据的,那么数据最常见的体现形式就是“文件”
那么先以操作文件为主来演示。
需求:在硬盘上,创建一个文件并写入一些文字数据。
找到一个专门操作文件的Writer子类对象,FileWriter。
后缀名是父类名,前缀名是该流对象的功能
下面以FileWriter为例演示一下IO流的基本写入的方法。
运行结果:
IO异常的处理
编译可以通过,当流对象创建成功了,程序正常运行,并且结束。
当出现错误的值的时候,流对象创建不成功,打印出异常信息。
在硬盘上原有的文件中续写数据
分析,应该先考虑构造函数,因为只要一new新的对象,新创建的文件就会覆盖掉原来的文件。所以从构造函数下手。
查阅API发现:
运行结果:
如果想要在写入数据的时候加上换行的话,需要在数据中间加上\r\n
Ps:Windows系统中认识的换行就是\r\n
运行结果:
结果显示、操作成功。
使用write方法进行写数据的时候,不仅可以写字符串,还可以写字符,字符数组之类的数据。
文件读取方式一
FileReader对象,的read方法。
运行结果为:
文件读取成功。
文件读取方式二
read方法还有重载方法:
上一个是一次读一个字符,这个可以一次读多个字符,
演示一下:
运行结果为:
接下来一个练习,获取一个.java文件,并且打印在控制台上。
运行结果为:
对文本文件进行拷贝:
第一种方法,
读一个字符,写一个字符:
运行结果,拷贝功能可以实现。
这种方法效率很低,因为读取流一次只能读取一个字符,写入流一次也能写一个字符。一点效率都没有,
第二种方法,效率就比较高了。
运行结果为:
这样的效率比较高一些。
System类
System:类中的方法和属性都是静态的。out:标准输出,默认是控制台
in :标准输入,默认键盘
描述系统的一些信息。
获取系统属性信息:Propertise getPropertises();
//获取系统信息的方法演示 import java.util.*; public class SystemDemo { public static void main(String[] args) { Properties prop = System.getProperties(); //Properties 是一个双列集合。 //因为Properties是Hashtable的子类,也就是Map的子类对象 //那么可以通过map集合的取出方式取出该集合 //该集合存储的都是字符串,没有泛型定义 for(Object obj:prop.keySet()) { String s = (String)obj; System.out.println(s+"::"+prop.get(s)); } } }
运行结果:
既然能获取,就可以设置
setProperty(String key,String value)
//获取系统信息的方法演示 import java.util.*; public class SystemDemo { public static void main(String[] args) { //自定义添加系统信息 System.setProperty("mykey","myvalue"); //获取所有的系统信息 Properties prop = System.getProperties(); //打印键值对 for(Object obj:prop.keySet()) { String s = (String)obj; System.out.println(s+"::"+prop.get(s)); } } }
获取单个系统信息的方法:String getProperty(String key);
//获取系统信息的方法演示 import java.util.*; public class SystemDemo { public static void main(String[] args) { //获取单个的系统信息: String s = System.getProperty("os.name"); System.out.println("os.name="+s); } }
如果参数输入一个不存在的键的话,输出的就是null
import java.util.*; public class SystemDemo { public static void main(String[] args) { //获取单个的系统信息: String s = System.getProperty("hahaha"); System.out.println("value="+s); } }
那么怎么样在jvm启动的时候就动态的加载一些系统信息呢?
java命令中有这样的指令:
-Dname = value 设置一个系统属性
命令行这样写:
java -Dhahaha=qqqqqq SystemDemo
//就是指定一个键为hahaha 值为qqqqqq的系统信息。
再次执行上边的代码,就会出现这样的结果:
结果发现,在查看hahaha对应的值的时候,可以打印出来该键对应的值。
Runtime类
每一个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。该类中并没有提供构造函数。说明不可以new对象,那么会直接想到该类中的方法都是静态的。
发现该类中还有非静态方法
说明该类肯定会提供了方法获取本类对象,而且该方法是静态的,并且返回值类型是本类对象。
由这个特点,可以看出该类使用了单例设计模型
下面看一个练习
//用Runtime对象打开一个本地的记事本程序,然后再关掉 //Runtime是虚拟机和运行环境建立的一个连接,也就是说Runtime的对象可以调用操作系统底层的功能 public class RuntimeDemo { public static void main(String[] args) throws Exception { //因为没有办法创建对象,使用java提供的获取对象的方法,返回一个本类的对象 Runtime r = Runtime.getRuntime(); //有了对象就可以调用方法了 //exec("这里写上命令,虚拟机就可以执行该命令") Process p = r.exec("notepad");//调用记事本的命令,会返回一个执行的进程对象p //如果在这里传递的参数写错了,会抛出io异常 //线程睡眠4秒钟 Thread.sleep(4000); //然后记事本关闭 //由java开启的调用底层功能的线程,java可以获取到线程的对象,就可以关闭该线程 p.destroy(); } }
运行结果为:
运行结果可以看到,程序运行时打开一个空白的记事本程序,4秒之后,记事本程序自动关闭。
然而Runtime类的强大之处还在于:
//用Runtime对象打开一个本地的记事本程序,记事本程序默认打来一个文本文件 public class RuntimeDemo { public static void main(String[] args) throws Exception { Runtime r = Runtime.getRuntime(); Process p = r.exec("notepad SystemDemo.java");//中间用空格隔开,写上一个文本文档文件, } }
运行结果:
运行结果显示,打开的记事本程序自动打开了一个SystemDemo.java的文件。
同样的道理,使用Runtime对象如果打开了一个播放器后边跟上一个视频文件,运行程序的时候就会直接播放视频了。
以上代码中写的记事本程序没有写路径,是因为在path中有System32,jvm会先在当前目录下找,如果找不到就在path路径下找,如果再找不到,就会抛出异常,
所以在使用Runtime对象打开本地程序的时候最好加上完整路径。
由Runtime对象开启的本地程序,java可以获取到他的进程对象Process对象,并且关闭掉他,
如果进程不是java打开的,java是拿不到他的进程对象的,也关不掉进程。
Date类
在util包中。可以获取当前的时间
import java.text.*; import java.util.*; public class DateDemo { public static void main(String[] args) { Date d = new Date(); //System.out.println(d);//打印结果为Tue Jul 28 21:31:47 CST 2015 //打印出来的时间看着不爽,怎么办呢? //将简单的时间模式封装到SimpleDateFormat对象中 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日E hh:mm:ss"); //调用foemat方法让模式格式化指定Date对象。 String time = sdf.format(d); System.out.println(time); } }
运行结果为:
想要得到自己想要的时间模式,需要创建简单时间格式(SimpleDateFormat)对象,
在构造函数的时候就给定想要的时间的格式,
再用该时间模式的对象调用format 方法,将时间对象d传进去,
就得到了想要的时间。
Calendar类
我们想要获取当前的年,用Date类的方法是这样的//使用Date对象获取年份 import java.util.*; import java.text.*; public class CalendarDemo { public static void main(String[] args) { Date d = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年"); String year = sdf.format(d); System.out.println(year);//2015年 } }
以上代码中,获取到的年份的值已经变成了一个字符串,没有办法再进行有关年的其他运算,(严格来说也有,Integer.parseInt(),)和调用年的方法。
方法二:
//使用Calendar对象获取年份月份日,还有星期 import java.util.*; import java.text.*; public class CalendarDemo { public static void main(String[] args) { //Calendar是抽象的,所以使用它的静态方法获取一个本类对象 Calendar c = Calendar.getInstance(); //获取对象中的值用get方法,传入给定的字段,返回值,记住前边要标识Calendar sop(c.get(Calendar.YEAR)+"年"); //同样的获取月份和日 //sop(c.get((Calendar.MONTH))+1+"月"); //获取月份的时候要注意,他这里的月份总比我们的月份少1,所以要有一个加1的动作 //但是有了这个动作太麻烦了,我们可以直接定义一个字符串的数组,每一次获取的值直接来数组中取值打印就好了 String[] mons = {"一月","二月","三月","四月" ,"五月","六月","七月","八月" ,"九月","十月","十一月","十二月" }; int index = c.get((Calendar.MONTH));//因为他这里返回的是一个数字,所以就直接当做角标了。 sop(mons[index]); sop(c.get(Calendar.DAY_OF_MONTH)+"日"); //打印星期也是一样的原理 String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"}; int week = c.get(Calendar.DAY_OF_WEEK); sop(weeks[week]); } public static void sop(Object obj) { System.out.println(obj); } }
运行结果:
演示set和add方法
//将时间随意前移或者后退的方法,add方法 import java.util.*; import java.text.*; public class CalendarDemo2 { public static void main(String[] args) { Calendar c = Calendar.getInstance(); //使用set方法可以设置当前的时间值 //c.set(1991,03,25); //使用add方法,可以调整指定的字段值进行前移或者后移 c.add(Calendar.YEAR,5);//将年份,向后推5年 printCalendar(c); //将月份向前移5个月 c.add(Calendar.MONTH,-5); printCalendar(c); } public static void sop(Object obj) { System.out.println(obj); } public static void printCalendar(Calendar c) { sop(c.get(Calendar.YEAR)+"年"); String[] mons = {"一月","二月","三月","四月" ,"五月","六月","七月","八月" ,"九月","十月","十一月","十二月" }; int index = c.get((Calendar.MONTH)); sop(mons[index]); sop(c.get(Calendar.DAY_OF_MONTH)+"日"); String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"}; int week = c.get(Calendar.DAY_OF_WEEK); sop(weeks[week]); } }
运行结果:
练习1:算出指定年份的2月一共有多少天?
//计算出指定的年份的二月有多少天 import java.util.*; import java.text.*; public class CalendarTest1{ public static void main(String[] args) { //获取一个日历对象 Calendar c = Calendar.getInstance(); sop(getErYue(c,2016)); } public static int getErYue(Calendar c,int year) { //将时间设定在某一年的3月1号,这里切记月份是按照数组这样排序的,第一个是0月 c.set(year,2,1); //3月1号向前推一天,也就是二月的最后一天了 c.add(Calendar.DAY_OF_MONTH,-1); //获取到该最后一天是该月份中的第几天 int erYue = c.get(Calendar.DAY_OF_MONTH); return erYue; } public static void sop(Object obj) { System.out.println(obj); } }
运行结果:
练习2:算出昨天的现在的时间点?
import java.util.*; import java.text.*; public class CalendarTest2 { public static void main(String[] args) { Calendar c = Calendar.getInstance(); getYestoday(c); } public static void getYestoday(Calendar c) { //先把日期向前推一天 c.add(Calendar.DAY_OF_MONTH,-1); //把年月日都打印出来 printCalendar(c); //再获取并打印其中的时分秒 sop(c.get(Calendar.HOUR)); sop(c.get(Calendar.MINUTE)); sop(c.get(Calendar.SECOND)); } public static void sop(Object obj) { System.out.println(obj); } //这是之前用过的打印年月日的方法,直接拿过来用 public static void printCalendar(Calendar c) { sop(c.get(Calendar.YEAR)+"年"); String[] mons = {"一月","二月","三月","四月" ,"五月","六月","七月","八月" ,"九月","十月","十一月","十二月" }; int index = c.get((Calendar.MONTH)); sop(mons[index]); sop(c.get(Calendar.DAY_OF_MONTH)+"日"); String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"}; int week = c.get(Calendar.DAY_OF_WEEK); sop(weeks[week]); } }
运行结果为:
Math类
java.lang包中的类。里边都是静态方法。
//ceil方法的使用:返回大于该参数的最小整数 public class MathDemo { public static void main(String[] args) { double d1 = Math.ceil(12.34); sop(d1); double d2 = Math.ceil(16.34); sop(d2); double d3 = Math.ceil(-12.34); sop(d3); } public static void sop(Object obj) { System.out.println(obj); } }
Math.floor();返回小于该参数的最大整数
//floor方法:返回小于该参数的最大整数 public class MathDemo { public static void main(String[] args) { double d1 = Math.floor(12.34); sop(d1); double d2 = Math.floor(16.34); sop(d2); double d3 = Math.floor(-12.34); sop(d3); } public static void sop(Object obj) { System.out.println(obj); } }
Math.round(double d);四舍五入,返回值为long类型的。
public class MathDemo { public static void main(String[] args) { //round方法:四舍五入 long l1 = Math.round(12.34); sop("l1="+l1); long l2 = Math.round(12.54); sop("l2="+l2); } public static void sop(Object obj) { System.out.println(obj); } }
Math.pow(double a,double b);求a的b次方,返回值为double
public class MathDemo { public static void main(String[] args) { //pow();求幂的方法,第一个参数为底数,第二个参数为指数 double d1 = Math.pow(2,3); sop("d1="+d1); double d2 = Math.pow(3,3); sop("d2="+d2); } public static void sop(Object obj) { System.out.println(obj); } }
random方法:随机的返回一个大于等于0,且小于1的数。double类型的。
public class MathDemo { public static void main(String[] args) { //random方法,随机的返回一个大于等于0,且小于1的double类型的数 for (int x = 0;x<10 ;x++ ) { //获取10个这样的数 double d1 = Math.random(); sop(d1); } } public static void sop(Object obj) { System.out.println(obj); } }
如果想要获取从1到10范围内的十个随机整数呢?
简单:
public class MathDemo { public static void main(String[] args) { for (int x = 0;x<10 ;x++ ) { //只要在原来的小数的基础上乘以10再加1就行了 //因为之前的数是0~0.9,乘10后变成0~9,加1变为1~10 int d1 = (int)((Math.random()*10)+1); sop(d1); } } public static void sop(Object obj) { System.out.println(obj); } }
其实,想要获得以上者样的数字组合,还有另一中方法就是使用util包中的Random类。
import java.util.*; public class RandomDemo { public static void main(String[] args) { for (int x =0;x<10 ;x++ ) { Random r = new Random();//创建一个random对象 sop(r.nextInt(10)+1);//获取0到指定数之间的随机整数 } } public static void sop(Object obj) { System.out.println(obj); } }
运行结果为:
练习:给定一个小数,要求保留小数的后两位。
//给定一个小数,要求保留小数的后两位 public class MathTest { public static void main(String[] args) { double d = Math.random()*10+1; sop(d); getTwo(d,2); } //这里定义一个保留小数后几位的方法,既然是方法,为了提高复用性,将要保留几位也作为一个参数传进来。 public static void getTwo(double d,int base) { /* 整体思路是: 保留后的小数最后一位需要四舍五入, 我们在这里就先把小数点后移两位(具体后移几位按需求来说) 然后四舍五入取到值,(是一个long类型的,后边没有小数点。) 在把小数点前移两位。打印出来 */ double num = Math.pow(10,base); long l = Math.round(d*num); sop(l/num); } public static void sop(Object obj) { System.out.println(obj); } }
IO流
IO流用来处理设备之间的数据传输Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按照操作数据分为两种:字节流与字符流
流按流向分为:输入流,输出流。
IO流常用的基类
字节流的抽象基类
InputStream,OutputStream
字符流的抽象基类:
Reader,Writer
注意:由这四个类派生出来的子类名称都是以其父类作为子类名的后缀。
如:InputStream的子类FileInputStream.
如:Reader的子类FileReader
既然IO流是用于操作数据的,那么数据最常见的体现形式就是“文件”
那么先以操作文件为主来演示。
需求:在硬盘上,创建一个文件并写入一些文字数据。
找到一个专门操作文件的Writer子类对象,FileWriter。
后缀名是父类名,前缀名是该流对象的功能
下面以FileWriter为例演示一下IO流的基本写入的方法。
//文件写入流的简单操作 import java.io.*; public class FileWriterDemo { public static void main(String[] args) throws IOException { //创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。 //而且该文件会被创建到指定的目录下,如果该目录下已经有同名文件,将被覆盖。 //其实该步就是再明确数据要存放的目的地。 FileWriter fw = new FileWriter("demo.txt"); //调用write方法,将字符串写入到流中。 fw.write("ni hao shi jie"); //刷新流对象中的缓冲中的数据。 //将数据刷到目的地中, fw.flush(); //关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据 //将数据刷到目的地中。 //和flush的区别,flush刷新后,流可以继续使用,close刷新后,会将流关闭。 fw.close(); } }
运行结果:
IO异常的处理
//IO异常的处理 import java.io.*; public class FileWriterDemo2 { public static void main(String[] args) { FileWriter fw = null;//因为fw对象要放在多个代码块中使用,所以在最外边建立一个空的引用 try { fw = new FileWriter("k:\\demo.txt");//这一步会发生异常 fw.write("hello world");//这一步也会发生异常 //两行代码都会发生异常,而且都有相关的,所以放在同一个try中处理 } catch (IOException e) { System.out.println(e.toString()); } finally//关闭资源的动作必须要执行,所以放在finally中 { try { //因为该步骤涉及到了fw,假如在上方代码中fw没有创建成功,这里的fw就是空指针了 //会发生空指针异常,所以这里先要进行判断 if(fw!=null) fw.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }
编译可以通过,当流对象创建成功了,程序正常运行,并且结束。
当出现错误的值的时候,流对象创建不成功,打印出异常信息。
在硬盘上原有的文件中续写数据
分析,应该先考虑构造函数,因为只要一new新的对象,新创建的文件就会覆盖掉原来的文件。所以从构造函数下手。
查阅API发现:
//演示对已有文件的数据的续写 import java.io.*; public class FileWriterDemo3 { public static void main(String[] args) { FileWriter fw = null; try { //需要在创建流对象的时候传入布尔型的值,true表示如果文件已经存在则不覆盖已有的文件 //在原有的文件上续写数据 fw=new FileWriter("demo.txt",true); fw.write("nihao shijie"); } catch (IOException e) { System.out.println("流对象创建失败啦"); } finally { try { if(fw!=null) fw.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
运行结果:
如果想要在写入数据的时候加上换行的话,需要在数据中间加上\r\n
Ps:Windows系统中认识的换行就是\r\n
//演示对已有文件的数据的续写 import java.io.*; public class FileWriterDemo3 { public static void main(String[] args) { FileWriter fw = null; try { //覆盖掉原有的文件进行重新写入 fw=new FileWriter("demo.txt"); fw.write("nihao shijie\r\nhello world"); } catch (IOException e) { System.out.println("流对象创建失败啦"); } finally { try { if(fw!=null) fw.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
运行结果:
结果显示、操作成功。
使用write方法进行写数据的时候,不仅可以写字符串,还可以写字符,字符数组之类的数据。
文件读取方式一
FileReader对象,的read方法。
//文件读取流方法一演示 import java.io.*; public class FileReaderDemo { public static void main(String[] args) { //先创建一个文件,里边写入数据nihao FileWriter fw = null; try { //覆盖掉原有的文件进行重新写入 fw=new FileWriter("demo.txt"); fw.write("nihao"); } catch (IOException e) { System.out.println("流对象创建失败啦"); } finally { try { if(fw!=null) fw.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } //开始创建读取流对象,读取数据 FileReader fr = null; try { //同样初始化的时候要指定要操作的文件 //传入的文件名称如果存在,继续运行,如果不存在,抛出FileNotFoundException fr = new FileReader("demo.txt"); //read方法只能一个字符一个字符的读,返回的是读取到的字符的ASCII码 //所以在打印的时候需要强转 //read方法读取到字符的末尾的时候,会返回-1 //所以读取方法可以这样写 int ch = 0; while ((ch=fr.read())!=-1) { System.out.println((char)ch); } } catch (IOException e) { System.out.println("读取流创建失败"); } finally { //最后一步,关闭资源: try { if(fr!=null) fr.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
运行结果为:
文件读取成功。
文件读取方式二
read方法还有重载方法:
上一个是一次读一个字符,这个可以一次读多个字符,
演示一下:
//读取文件的另外一种办法 import java.io.*; public class FileReaderDemo2 { public static void main(String[] args) { //先创建一个文件,里边写入数据nihao FileWriter fw = null; try { //覆盖掉原有的文件进行重新写入 fw=new FileWriter("demo.txt"); fw.write("nihao"); } catch (IOException e) { System.out.println("流对象创建失败啦"); } finally { try { if(fw!=null) fw.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } //开始创建读取流对象,读取数据 FileReader fr = null; try { //同样初始化的时候要指定要操作的文件 fr = new FileReader("demo.txt"); //read(char[] chs)方法可以将读取到的字符存储到数组中去,然后返回读取到的数组的个数。 //所以先要创建一个数组:数组的长度创建多大比较合适呢? //如果长度小了,只能读取到长度为数组长度的数据,想要获取到所有的数据还要读取多次 //于是我们一般都把长度定为1024 char[] chs = new char[1024]; int num = fr.read(chs); //然后将所读到的数据打印出来,将数组的一部分转变成字符串,用new String(数组,起始位置,结束位置) System.out.println(new String(chs,0,num)); } catch (IOException e) { System.out.println("读取流创建失败"); } finally { //最后一步,关闭资源: try { if(fr!=null) fr.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
运行结果为:
接下来一个练习,获取一个.java文件,并且打印在控制台上。
//获取一个.java文件,并且打印在控制台上 import java.io.*; public class FileReaderTest { public static void main(String[] args) { FileReader fr = null; try { //获取到文件对象 fr = new FileReader("DateDemo.java"); char[] chs = new char[1024]; int num = 0; while ((num = fr.read(chs))!=-1) { System.out.println(new String(chs,0,num)); } } catch (IOException e) { System.out.println("读取流创建失败"); } finally { //最后一步,关闭资源: try { if(fr!=null) fr.close(); } catch (IOException e) { System.out.println("关闭流资源失败"); } } } }
运行结果为:
对文本文件进行拷贝:
第一种方法,
读一个字符,写一个字符:
//对文本文件进行拷贝 import java.io.*; public class FileCopyDemo { public static void main(String[] args) { copy_1(); } public static void copy_1() { //建立读取流对象的引用 FileReader fr = null; FileWriter fw = null; try { //创建写入流对象,并制定文件名称 fw = new FileWriter("RuntimeDemo.txt"); } catch (IOException e) { throw new RuntimeException("写入流开启失败啦"); } try { //创建读取流对象,并且开始读取数据 fr = new FileReader("RuntimeDemo.java"); int num = 0;//num为读取到的字符的ASCII值 while ((num = fr.read())!=-1) { fw.write((char)num);//将读到的ASCII值强转成char类型,然后使用写入流对象,写入到目标文件中 } } catch (IOException e) { throw new RuntimeException("读取流开启失败啦"); } finally { //最后的动作:关闭资源 //一定要先判断,然后处理,这样两个异常可以都被处理掉, //切记,两个异常不能同时处理。要分开处理 if(fr!=null) { try { fr.close(); } catch (IOException e) { throw new RuntimeException("读取流关闭失败啦"); } } if(fw!=null) { try { fw.close(); } catch (IOException e) { throw new RuntimeException("写入流关闭失败啦"); } } } } }
运行结果,拷贝功能可以实现。
这种方法效率很低,因为读取流一次只能读取一个字符,写入流一次也能写一个字符。一点效率都没有,
第二种方法,效率就比较高了。
//拷贝文本文件的第二中方法 import java.io.*; public class FileCopyDemo2 { public static void main(String[] args) { copy_2(); } public static void copy_2() { //建立两个流对象的引用 FileWriter fw = null; FileReader fr = null; try { //创建写入流对象,并指定文件名称 fw = new FileWriter("SystemDemo.txt"); } catch (IOException e) { //如果流对象创建失败,抛出运行时异常 throw new RuntimeException("写入流开启失败啦"); } try { fr = new FileReader("SystemDemo.java"); int num = 0; char[] chs = new char[1024]; //开始读取数据,并写入数据 while ((num = fr.read(chs))!=-1) { fw.write(chs,0,num); //write方法有自己的重载方法,可以写入一个数组,从指定位置开始,到指定位置结束 } } catch (IOException e) { throw new RuntimeException("读取流开启失败啦"); } //最后的关流动作 finally { if(fr!=null) { try { fr.close(); } catch (IOException e) { throw new RuntimeException("读取流关闭失败啦"); } } if(fw!=null) { try { fw.close(); } catch (IOException e) { throw new RuntimeException("写入流关闭失败啦"); } } } } }
运行结果为:
这样的效率比较高一些。
相关文章推荐
- Spring学习笔记--依赖注入
- spring的事务中程序控制事务成功失败(Transaction marked as rollback)
- Spring Boot 使用
- java string equal出现的问题
- Java HashMap的死循环
- java string 中文转换UTF-8
- Eclipse 编译错误 Access restriction:The type *** is not accessible due to restriction on... 解决方案
- Eclipse/MyEclipse自动补全的设置(自动提示)
- Java编程思想第四章练习7,使用break/return在打印到99时退出
- 关于 64位系统 java连接access 报错java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序
- Java:应用Observer接口实践Observer模式
- 计数排序——JAVA实现
- Java编程思想第四章练习6答案
- Java 正则表达式详解
- 拓扑排序 java
- JAVA对象属性复制
- java 遍历map 方法 集合 五种的方法
- 深入理解java虚拟机-1 内存结构与OutOfMemory溢出异常
- Java中单元测试中:@BeforeClass,@Before,@Test,@After,@AfterClass
- java 设计模式 -- 责任链模式