黑马程序员——自学总结(四)Java IO技术之流对象

<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!

一、System类

        该类位于java.lang包中,用于描述系统的一些信息,不能被实例化,没有构造函数,静态成员有err(标准错误流),in(标准输入,默认是键盘),out(标准输出,默认是控制台),System类中方法和属性都是静态的。

        System.getProperties()获取系统属性信息,返回Properties类对象,Properties是Hashtable子类,可以用Map中的方法取出该集合中的元素。该集合中存储的键和值都是字符串,没有泛型定义。还可以用Properties对象的方法Set<String> stringPropertyNames()返回键的集合。

       在系统中自定义一些特有信息,可以通过System类中的setProperty(String,String),但是不能永久改变。获取单个信息用getProperty(key),找不到时value返回null。可以在虚拟机启动时,动态的加载一些属性信息,命令格式:java -D 键=值

二、Runtime类

        Runtime也在java.lang包中,不能被构造,方法都是非静态的,除了静态方法static Runtime getRuntime()可以返回Runtime对象,该方法中采用了饿汉式单例模式。

        调用Runtime对象的Process exec(String command)方法可以开启一个可执行线程,返回一个Process对象,如果命令名非绝对路径,系统会在Path变量里设置的默认路径里找。Process对象的destroy()方法可以杀掉子进程,只能杀通过exec()方法启动的进程,command还可以带命令参数,比如往记事本写入文件数据。

三、Date类

       在java.util包中Date类用于描述时间信息,构造一个Date对象打印出来,感觉格式不习惯,可以导入java.text.*;,该包内有一 SimpleDataFormat类,可以格式化date对象。

       Date d=new Date();

       SimpleDataFormat sdf=new SimpleDataFormat("yyyy年MM月dd日");

       sdf.format(d);

       将模式封装到SimpleDataFormat对象中,调用formar()方法,让模式格式化指定的data对象,返回String。

       用"yyyy”格式化date对象,返回String,得到年份,再用Integer.parseInt()转换,可得到date对象的年份数值。

四、Calendar类

        该类是抽象类,可以通过静态方法Calendar.getInstance()实例化,可以在实例化时传递时区对象返回指定的日历对象。Calendar类中封装了多个静态字段,可以返回日历对象的年份,月份,星期,日期等值。get(Calendar.YEAR)获得年份,get(Calendar.MONTH)获得月份,get(Calender.DAY_OF_MONTH)获得某月的几号,Calendar.MONTH值从0到11。显示时,可以建立String数组,存储"一月"到“十二月”,利用查表法输出正确汉字格式的月份值。set(int 年份值,int 月份值,int  日期值)可以更改日历对象字段属性,注意月份从0开始,add(Calendar.YEAR,4)增加4年。

       练习:(1)、获取任意年的二月有多少天。思路:根据指定的年设置一个时间c.set(year,2,1)得到某一年的3月1日,c.add(Calendar.DAY_OF_MONTH,-1)得到某一年2月的最后一天,c.get(Calendar.DAY_OF_MONTH)得到某一年2月有多少天。

       代码如下:

import java.util.*;
class getday{
	public static int getday(int year){
		Calendar c=Calendar.getInstance();
		c.set(year,2,1);
		c.add(Calendar.DAY_OF_MONTH,-1);
		return c.get(Calendar.DAY_OF_MONTH);
	} 
	public static void main(String[] args){
		for(int year=2000;year<2016;year++)
			System.out.println(getday(year));	
	}
}


 

                   (2)、获取昨天的现在这个时刻

                   代码如下:

import java.util.*;
class gettime{
	public static Calendar gettime(){
		Calendar c=Calendar.getInstance();
		c.add(Calendar.DAY_OF_MONTH,-1);
		return c;
	} 
	public static void main(String[] args){
		System.out.println(gettime());
	}
}


注意:星期从星期日开始算起,星期日返回0,星期六返回0。

五、Math类

        Math类静态成员E,PI,分别表示自然对数的底数和圆周率,abs(double d)返回绝对值,ceil(double d)返回大于或等于参数的最小整数,返回值double型,floor(double d)返回小于等于参数的最大整数,返回值double型,long round(double d)返回四舍五入后的整数值,pow(double a, double b)求幂,random()返回[0,1)之间的随机double值,可new Random()创建随机数对象,随机数对象有nextInt(),nextDouble()等返回随即整数,浮点数等。

       练习:给定一个小数,保留该小数的后两位。 

class myround{
	public static double myround(double d){
		return Math.round(d*100)/100.0;
		
	} 
	public static void main(String[] args){
		System.out.println(myround(3.141592653));
	}
}


六、IO流

        IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中,流按操作数据分为两种:字节流和字符流,流按流向分为输入流和输出流。

        字节流的抽象基类:InputStream,OutputStream,字符流的抽象基类:Reader,Writer,由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。如InputStream的子类FileInputStream,Reader的子类FileReader。Write类包含各种重载的write方法。

        需求:在硬盘上,创建一个文件并写入一些文字数据。

        使用FileWriter类(后缀名是父类名,前缀名是该流对象的功能)FileWriter类构造函数中需传递文件信息,该对象一被初始化就必须要明确被操作的文件,声明捕捉异常,该文件会被创建到指定的目录下,如果该目录下已有同名文件,写操作后将被覆盖。
     
 

import java.io.*;
class IOdemo{
	public static void main(String[] args){
		FileWriter fw=null;
		try{
			fw=new FileWriter("iodemo.txt");
			fw.write("hello!");
			fw.flush();
		}catch(IOException e){
			throw new RuntimeException(e);	
		}finally{
			try{
				if(fw!=null)
					fw.close();
			}catch(IOException e){
				throw new RuntimeException(e);
			}
		}
	}
}



       调用writer()方法将字符串写入到流中,再flush()清空缓冲区,数据送至目的地。close()关闭流资源,但是关闭之前会刷新一次内部缓冲区中的数据,再调用write()将写不进去,抛出异常,而调用flush()后可以继续写数据,close()和flush()都需声明抛出IO异常。

        一般应采用如下格式创建流对象:

        try{

        }catch(IO异常)

        finally(关闭流) 确保即使出现异常,也能关闭流。如果流对象在try块中声明,那么在finally中将无法访问,所以try块外边建立流对象,在try内进行流对象初始化。关闭流对象同样需要声明捕捉异常,为了防止出现调用空的流对象的close()方法,在关闭流对象之前,需判断是否为空。初始化FileWriter对象时,可能会抛出FileNotFoundException,它是IOException的子类。

       如果不覆盖原有文件内容,只是对已有文件的数据续写,用write(数据,true);注意:在Windows中,回车符由两个字符表示,\r\n,Linux\n可以换行。

       对文本文件读取使用Reader抽象类,使用构造方法创建一个文件读取流对象,和指定名称的文件相关联,要保证文件是已经存在的,如果不存在,会发生FileNotFoundException异常。

        Reader类中多种重载的read()方法,方法内部一次读一个字符,将读到的字符作为int返回,而且会自动往下读,读到末尾返回-1,编程时用while(reader.read(char[]))循环判断,read(char[])返回读到的字符个数,到末尾返回-1,按照字符数组的长度读取相应的字符存入字符数组,继续读字符会在字符数组中循环存储,已全部取完到文件末尾,返回-1,通常将字符数组长度定义为1024的整数倍。

        练习:读取一个.java文件,并打印在控制台上。

 

import java.io.*;
class IOdemo2{
	public static void main(String[] args){
		Reader reader=null;
		try{
			reader=new FileReader("IOdemo2.java");
			char[] buff=new char[1024];
			int len=0;
			while((len=reader.read(buff))!=-1)
				System.out.print(new String(buff,0,len));
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(reader!=null)
				try{
					reader.close();
				}catch(IOException e){
					throw new RuntimeException(e);
				}
		}
	}	
}


         将C盘一个文本文件复制到D盘,复制原理其实就是将C盘下的文件数据存储到D盘的一个文件中,步骤:1、在D盘创建一个文件,用于存储C盘文件中的数据;2、定义一个读取流和C盘文件关联;3、通过不断的读写完成数据的存储;4、关闭资源。

import java.io.*;
class IOdemo3{
	public static void main(String[] args){
		Reader reader=null;
		Writer writer=null;
		try{
			reader=new FileReader("C:\\IOdemo3.java");
			writer=new FileWriter("D:\\IOdemo3_copy.java");
			char[] buff=new char[1024];
			int len=0;
			while((len=reader.read(buff))!=-1){
				writer.write(new String(buff,0,len));
				writer.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(reader!=null)
				try{
					reader.close();
				}catch(IOException e){
					throw new RuntimeException(e);
				}finally{
					if(writer!=null)
					try{
						writer.close();
					}catch(IOException e){
						throw new RuntimeException(e);
					}
				}
		}
	}	
}


        Reader读取文本文件有两种方式:(1)单个字符读取;(2)字符数组读取。

        字符流中的缓冲区的出现提高了对数据的读写效率,对应类为BufferedWriter,BufferedReader,缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强。缓冲区的出现是为了提高流的操作效率,所以在创建缓冲区之前,必须要先有流对象,缓冲区的原理其实就是在内部封装了一个数组。只要用到缓冲区,就要记得刷新flush(),否则数据写不出去,关闭缓冲区就是在关闭缓冲区中的流对象,不用再重复关闭。BufferedWriter中的newLine()方法跨平台,在不同的操作系统中可以本地化输出换行符。BufferedReader类为了提高效率,加入了缓冲技术,构造时将字符读取流对象作为参数传递给缓冲对象的构造器,该缓冲区提供了一个依次读一行的方法readLine()方法,方便对文本数据的获取,到文件末尾返回null。

        练习:通过缓冲区复制.java文件

import java.io.*;
class IOdemo4{
	public static void main(String[] args){
		BufferedReader br=null;
		BufferedWriter bw=null;
		try{
			br=new BufferedReader(new FileReader("C:\\IOdemo4.java"));
			bw=new BufferedWriter(new FileWriter("D:\\IOdemo4_copy.java"));
			String buff=null;
			while((buff=br.readLine())!=null){
				bw.write(buff);
				bw.newLine();
				bw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(br!=null)
				try{
					br.close();
				}catch(IOException e){
					throw new RuntimeException(e);
				}finally{
					if(bw!=null)
					try{
						bw.close();
					}catch(IOException e){
						throw new RuntimeException(e);
					}
				}
		}
	}	
}


       readLine()方法返回的时候只返回回车符之前的数据,并不返回回车符。

     下面构建MyBufferedeReader类,自定义readLine()方法和close方法。

import java.io.*;
class MyBufferedReader{
	private FileReader fr;
	public MyBufferedReader(FileReader fr){
		this.fr=fr;
	}
	public void myclose(){
		if(fr!=null)
			try{		
				fr.close();
			}catch(IOException e){
				throw new RuntimeException(e);
			}
	}
	public String myreadLine(){
		StringBuilder sb=new StringBuilder();
		int c;
		try{
			while((c=fr.read())!=-1){
				if(c=='\r')
					continue;
				if(c=='\n')
					return sb.toString();
				else
					sb.append((char)c);
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}
		if(sb.length()!=0)
			return sb.toString();
		return  null;		
	}	
}


 

import java.io.*;
class IOdemo5{
	public static void main(String[] args){
		MyBufferedReader br=null;
		BufferedWriter bw=null;
		try{
			br=new MyBufferedReader(new FileReader("C:\\IOdemo5.java"));
			bw=new BufferedWriter(new FileWriter("D:\\IOdemo5_copy.java"));
			String buff=null;
			while((buff=br.myreadLine())!=null){
				bw.write(buff);
				bw.newLine();
				bw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(br!=null)
			    br.myclose();
			if(bw!=null)
			    try{
				bw.close();
			    }catch(IOException e){
				throw new RuntimeException(e);
			    }	
		}
	}	
}


          为了确保最后一行数据也能读到,在myreadLine()方法内while循环结束后,判断如果因为读到文件尾且sb中有数据,则将最后一行数据返回。

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

        装饰和继承的区别:继承扩展性不好,非常臃肿。装饰模式比继承模式要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常都是属于一个体系中的。装饰模式实际上由继承结构变成了组合结构。

        自定义装饰类,继承自Reader,覆盖Reader中的抽象方法:read(char[],int off ,int len)和close()。

        修改上例中的MyBufferedReader类:

import java.io.*;
class MyBufferedReader extends Reader{
	private Reader r;
	public MyBufferedReader(Reader r){
		this.r=r;
	}
	public int read(char[] cbuf, int off, int len) throws IOException{
		return r.read(cbuf,off,len);
	}  
	public void close(){
		if(r!=null)
			try{		
				r.close();
			}catch(IOException e){
				throw new RuntimeException(e);
			}
	}
	public String myreadLine(){
		StringBuilder sb=new StringBuilder();
		int c;
		try{
			while((c=r.read())!=-1){
				if(c=='\r')
					continue;
				if(c=='\n')
					return sb.toString();
				else
					sb.append((char)c);
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}
		if(sb.length()!=0)
			return sb.toString();
		return  null;		
	}	
}


 

        BufferedReader有一子类LineNumberReader,该类有getLineNumber()方法获得当前行号,setLineNumber(int lineNumber)方法设置行号,readLine()方法读取一行数据。 感觉这个程序有点小问题,如果是汉字字符,把汉字字符的两个字节拆成两次读取,可能会出现错误字符。大哭

        练习:模拟一个带行号的缓冲区对象。

        代码如下:

import java.io.*;
class MyLineNumberReader{
	private Reader r;
	private int linenumber;
	public MyLineNumberReader(Reader r){
		this.r=r;
		linenumber=0;
	}
	public void close() throws IOException{
		if(r!=null)
			try{		
				r.close();
			}catch(IOException e){
				throw e;
			}
	}
	public String readLine(){
		linenumber++;
		StringBuilder sb=new StringBuilder();
		int c;
		try{
			while((c=r.read())!=-1){
				if(c=='\r')
					continue;
				if(c=='\n')
					return sb.toString();
				else
					sb.append((char)c);
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}
		if(sb.length()!=0)
			return sb.toString();
		return  null;		
	}
	public int getLineNumber(){
		return linenumber;
	}
	public void setLineNumber(int lineNumber){
		linenumber=lineNumber;
	}	
}


 

import java.io.*;
class IOdemo6{
	public static void main(String[] args){
		MyLineNumberReader br=null;
		BufferedWriter bw=null;
		try{
			br=new MyLineNumberReader(new FileReader("C:\\IOdemo6.java"));
			br.setLineNumber(100);//从101起开始记录行数
			bw=new BufferedWriter(new FileWriter("D:\\IOdemo6_copy.java"));
			String buff=null;
			while((buff=br.readLine())!=null){
				bw.write(br.getLineNumber()+buff);
				bw.newLine();
				bw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(br!=null)
			    try{
			    	br.close();
			    }catch(IOException e){
			    	throw new RuntimeException(e);
 			    }finally{
				if(bw!=null)
			    	try{
					bw.close();
			    	}catch(IOException e){
					throw new RuntimeException(e);
			    	}
			    }	
		}
	}	
}


程序运行结果如下:

        字节流主要有两个基类InputStream和OutputStream,想要操作图片数据,这时就要用到字节流。其实字符流内部也是按照字节流进行操作,只不过将读到的字节数据临时存储,比如汉字2个字节读两次,然后一起刷新读出。而字节流不设置缓冲区,直接输入或输出,不用刷新。字节流有两种读取方式,一个一个地读,或存储到字节数组地读(该方法内部通过available()方法得到剩余文件大小,以确定还将往数组中存储多少数据),可在读取开始调用available()方法获取文件大小,建立刚刚好大小的数组读。java虚拟机启动默认占用内存是64M,可以启动时调整大小,因为若文件太大的话建立刚刚好大小的数组则不合适,会造成内存溢出。一般定义数组大小为1024整数倍最合适。

        复制一个图片。思路:1、用字节读取流对象和图片关联;2、用字节数组存储获取到的图片数据3、通过循环读写完成数据存储,4、关闭资源。注意不要拿字符流处理字节文件,因为若读到未知编码数据,可能会改变数据。

import java.io.*;
class IOdemo7{
	public static void main(String[] args){
		InputStream is=null;
		OutputStream os=null;
		try{
			is=new FileInputStream("C:\\Pic.jpg");
			os=new FileOutputStream("D:\\Pic_copy.jpg");
			byte[] buff=new byte[1024];
			int len=0;
			while((len=is.read(buff))!=-1)
				os.write(buff,0,len);
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(is!=null)
				try{
					is.close();
				}catch(IOException e){
					throw new RuntimeException(e);
				}finally{
					if(os!=null)
						try{
							os.close();
						}catch(IOException e){
							throw new RuntimeException(e);
						}
				}
		}
	}
}


        字节流的缓冲区BufferedInputStream和BufferedOutStream,通过字节流的缓冲区完成复制MA3文件,记录复制时间。可调用System.currentTimeMills()方法获得系统当前时间。

 

import java.io.*;
class IOdemo8{
	public static void main(String[] args){
		Long start=System.currentTimeMillis();
		BufferedInputStream bis=null;
		BufferedOutputStream bos=null;
		try{
			bis=new BufferedInputStream(new FileInputStream("C:\\Pic.jpg"));
			bos=new BufferedOutputStream(new FileOutputStream

("D:\\Pic_copy.jpg"));
			int data=0;
			while((data=bis.read())!=-1)
				bos.write(data);
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			if(bis!=null)
				try{
					bis.close();
				}catch(IOException e){
					throw new RuntimeException(e);
				}finally{
					if(bos!=null)
						try{
							bos.close();
						}catch(IOException e){
							throw new RuntimeException(e);
						}
				}
		}
		System.out.println("复制成功!总共耗时"+(System.currentTimeMillis()-start)+"

毫秒");
	}
}



        说明一点:MP3数据都是01代码,有可能出现第一个字节全是1,这时如果read()方法将得到的字节数据转换为int型返回,将返回-1,那么读取就将结束。而实际上为了防止出现这种情况,Java在设计read()方法时,对得到的字节数据是将其高位全部补0提升至int型返回,write()方法写入数据时只写int变量的强转,只写入数据低8位。

        需求:通过键盘录入数据,当录入一行数据后,就将该行数据进行打印,如果录入的数据是over,那么就停止录入,在命令窗口按ctrl+c,实际上就是加结束标记,read此时返回-1。

 

import java.io.*;
class IOdemo9{
	public static void main(String[] args){
		BufferedReader br=null;
		BufferedWriter bw=null;
		try{
			br=new BufferedReader(new InputStreamReader(System.in));
			bw=new BufferedWriter(new OutputStreamWriter(System.out));
			String buff=null;
			while((buff=br.readLine())!=null){
				if("over".equals(buff))
					break;
				bw.write(buff);
				bw.newLine();
				bw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			try{
					br.close();
			}catch(IOException e){
					throw new RuntimeException(e);
			}finally{	
				try{
					bw.close();
				}catch(IOException e){
					throw new RuntimeException(e);
				}
			}
		}
	}
}


        System.out 对应的是标准输出设备—控制台,System.in对应的是标准输入设备—键盘,程序中br.read()方法是阻塞方法。为了提高读写效率,可以采用BufferedReader类的readLine()方法,但Systenm.in是InputStream,考虑使用InputStreamReader转换流,将InputStream转换为Reader对象。步骤:(1)获取键盘录入对象;(2)使用转换流将字节流对象转成字符流对象;(3)为了提高效率,将字符串进行缓冲区技术高效操作,使用装饰类包装。对应的,OutputStreamWriter类可将字节输出流转换成字符输出流。

        上面代码中数据源是键盘录入,数据目的是控制台,现在想把键盘录入的数据存储到文件中。

 

import java.io.*;
class IOdemo10{
	public static void main(String[] args){
		BufferedReader br=null;
		BufferedWriter bw=null;
		try{
			br=new BufferedReader(new InputStreamReader(System.in));
			bw=new BufferedWriter(new FileWriter("D:\\data.txt"));
			String buff;
			while((buff=br.readLine())!=null){
				if("over".equals(buff))
					break;
				bw.write(buff);
				bw.newLine();
				bw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			try{
				br.close();
			}catch(IOException e){
					throw new RuntimeException(e);
			}finally{
				if(bw!=null)
					try{
						bw.close();
					}catch(IOException e){
						throw new RuntimeException(e);
					}
			}
		}
	}
}


        需求:想要将一个文件的数据打印在控制台上。

 

import java.io.*;
class IOdemo11{
	public static void main(String[] args){
		BufferedReader br=null;
		BufferedWriter bw=null;
		try{
			br=new BufferedReader(new FileReader("D:\\data.txt"));
			bw=new BufferedWriter(new OutputStreamWriter(System.out));
			String buff;
			while((buff=br.readLine())!=null){
				bw.write(buff);
				bw.newLine();
				bw.flush();
			}
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally{
			try{
				br.close();
			}catch(IOException e){
					throw new RuntimeException(e);
			}finally{
				if(bw!=null)
					try{
						bw.close();
					}catch(IOException e){
						throw new RuntimeException(e);
					}
			}
		}
	}
}

        使用流操作最纠结的就是流对象很多,不知道该用哪个。可以通过两个明确来完成。(1)明确源和目的,数据源用输入流,数据目的用输出流;(2)操作的数据是否是纯文本,是纯文本使用字符流,不是使用字节流;(3)当体系明确后再明确要使用哪个具体的流对象,通过设备来进行区分,数据源设备有内存,硬盘,键盘等,数据目的设备有内存,硬盘,控制台等。

        需求:将一个文本文件中数据存储到另一个文件中,复制文件。

        分析:被复制文件是数据源,使用输入流,操作纯文本文件,使用Reader,体系明确了,接下来明确要使用该体系中的哪个对象,明确数据源设备是文件(硬盘),体系中可以操作文件的对象是FileReader。

                    复制文件是数据目的,使用输出流,操作纯文本,使用Writer,数据目的设备是硬盘,Writer可以操作文件的类是FileWriter。

                    需要提高效率,加入Reader体系中的缓冲区BufferedReader。

        练习:将一个图片文件中数据存储到另一个文件中,复制文件,要按照以上格式自己完成三个明确。

        分析:被复制文件是数据源,使用输入流,不是操作纯文本文件,使用InputStream,体系明确了,接下来明确要使用该体系中的哪个对象,明确数据源设备是文件(硬盘),体系中可以操作文件的对象是FileInputStream。

                    复制文件是数据目的,使用输出流,不是操作纯文本,使用OutputStream,数据目的设备是硬盘,OutputStream类中可以操作文件的类是FileOutputStream。

                    需要提高效率,加入InputStream体系中的缓冲区BufferedInputStream

        需求:将键盘录入的数据保存到一个文件中

        这个需求中源和目的都存在,分别分析:

        键盘录入是数据源,且操作纯文本,使用Reader,文件(硬盘)是数据目的,需要提高效率,使用BufferedWriter(new FileWriter())。这里键盘System.in对应的是字节流,为了操作键盘的文本数据方便,转成字符流,用到了Reader体系中的转换流InputStreamReader。需要提高效率,用BufferedReader包装。

        扩展一下,想要把录入的数据按照指定的编码表存入到文件中,比如指定编码表UTF-8,因为FileWriter使用的是默认编码表GBK,所以只有转换流OutputStreamWriter才能完成,该转换流对象要接收一个FileOutputStream对象,OutputStreamWriter对象写入数据时可以指定编码表。转换流使用场合:字符流和字节流需要转换,涉及到字符编码转换时。

        练习:将一个文本数据打印在控制台上,按照以上格式完成三个明确。

        改变标准输入输出设备System.setIn(),System.setOut(PrintStream)。可以通过重新设定标准输出设备,将异常信息记录到指定文件中。网上有建立日志信息的工具,比如log4j。

        Properties可以和流对象结合,Properties对象的list(PrintStram)方法可以输出系统信息,通过指定PrintStream得到系统信息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值