黑马程序员——java的IO之流操作的基本规律,Properties类,打印流,序列流

------- android培训java培训、期待与您交流! ----------

前言:通过观看毕向东老师的java基础视频,查漏补缺,将一些自己掌握的还不牢固的知识写出来,希望和大家交流分享。

1.流操作的基本规律

1.流操作的基本规律:对于IO流的使用,由于流对象有很多,不知道该用哪一个。 可以通过三个明确来完成:

     1)  明确源和目的。

            源:输入流。InputStream  Reader

            目的:输出流。OutputStream  Writer

     2)操作的数据是否是纯文本。

            是:字符流

            否:字节流

     3 ) 当体系明确后,再明确要使用哪个具体的对象。通过设备来进行区分:

            源设备:内存,硬盘,键盘

            目的设备:内存,硬盘,控制台

2.举例说明:

       1) 将一个文本文件中数据存储到另一个文件中。复制文件。

              a)源:因为是源,所以使用读取流:InputStream和Reader

                   明确体系:是否操作文本:是,Reader

                   明确设备:明确要使用该体系中的哪个对象:硬盘上的一个文件。Reader体系中可以操作文件的对象是FileReader

                   是否需要提高效率:是,加入Reader体系中缓冲区 BufferedReader.

           FileReader fr = new FileReader("a.txt");

           BufferedReader bufr = new BufferedReader(fr);

             b)目的:输出流:OutputStream和Writer

                   明确体系:是否操作文本:是,Writer

                   明确设备:明确要使用该体系中的哪个对象:硬盘上的一个文件。Writer体系中可以操作文件的对象FileWriter。

                   是否需要提高效率:是,加入Writer体系中缓冲区 BufferedWriter

           FileWriter fw = new FileWriter("b.txt");

           BufferedWriter bufw = new BufferedWriter(fw);

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

                  a)源:输入流,InputStream和Reader

                        是否是文本?否,InputStream

                        源设备:硬盘上的一个文件。InputSteam体系中可以操作文件的对象是FileInputSteam

                        是否需要提供效率:是,BufferedInputStream

              BufferedInputSteam bis=new  BufferedInputStream(new FileInputStream("1.jpg"));

                  b)目的:输出流,OutputStream和Writer

                        是否是文本?否,OutputStream

                        源设备:硬盘上的文件,FileOutputStream

                        是否需要提高效率:是,加入BufferedOutputStream

              BufferedOutputStream bos=new  BufferedOutputStream(new FileOutputStream("2.jpg"));

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

                  a)源:InputStream和Reader

                       是不是纯文本?是,Reader

                       设备:键盘。对应的对象是System.in。——为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。

                       所以既然明确了Reader,那么就将System.in转换成Reader。用Reader体系中转换流,InputStreamReader

                       需要提高效率吗?需要,BufferedReader 

             InputStreamReader isr = new InputStreamReader(System.in); 
<pre name="code" class="java">              
             BufferedReader bufr = new BufferedReader(isr);    
 

                b)目的:OutputStream  Writer

                     是否是存文本?是!Writer。

                     设备:硬盘。一个文件。使用 FileWriter。需要提高效率吗?需要。  

            FileWriter fw = newFileWriter("c.txt");

            BufferedWriter bufw = new BufferedWriter(fw);

3.  扩展:想要把录入的数据按照指定的编码表(UTF-8)(默认编码表是GBK),将数据存到文件中。用到转换流。

        目的:OutputStream  Writer

        是否是存文本?是!Writer。

        设备:硬盘上的一个文件。使用 FileWriter。——但是FileWriter是使用的默认编码表:GBK。

        而存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。

        该转换流对象要接收一个字节输出流,而且还可以操作的文件的字节输出流:FileOutputStream

<pre name="code" class="java">    OutputStreamWriter osw =new OutputStreamWriter(newFileOutputStream("d.txt"),"UTF-8");
 

        需要高效吗?需要,BufferedWriter

        BufferedWriter bufw = new BufferedWriter(osw);

       转换流什么使用? 字符和字节之间的桥梁。通常,涉及到字符编码转换时,需要用到转换流。

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

        1)源:InputStreamReader

            是文本?是:Reader

            设备:硬盘。上的文件:FileReader

            是否需要提高效率?是:BufferedReader

             BufferedReader br=new BufferedReader(newFileReader("1.txt"));

       2)目的:OutputStream Writer

            是文本?是:Writer

            设备:控制台。对应对象System.out。由于System.out对应的是字节流,所以利用OutputSteamWriter转换流

            是否提高效率?是:BufferedWriter

              BufferedWriter bw =new BufferedWriter(newOutputStreamWriter(system.out));

4.通过System类的setIn,setOut方法可以对默认标准输入输出设备进行改变

        System.setIn(newFileInputStream(“1.txt”));//将源改成文件1.txt。

        System.setOut(newFileOutputStream(“2.txt”));//将目的改成文件2.txt

5. 简单的异常日志信息:当程序运行出现异常时,不希望直接打印在控制台,而是打印到日志文件中,方便程序员查看,并及时调整的。

package file;

import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionToLog {
	public static void main(String[] args) {
		try {
			int[] a = new int[2];
			System.out.println(a[3]);
		} catch (Exception e) {
			try {
				//创建时间对象  
				Date date = new Date();
				//时间模块格式对象  
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd HH:mm:ss");
				String s = sdf.format(date);
				//打印流对象  
				PrintStream ps = new PrintStream("e.log");
				//修改输出流设备  
				System.setOut(ps);
				//输出时间  
				ps.print(s);
			} catch (Exception e2) {
				throw new RuntimeException("文件创建失败!");
			}
			e.printStackTrace(System.out);//将异常信息输出指定输出流  
		}
	}
}
运行结果:

6.系统属性信息存入文本

package file;

import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;

/**
 * 系统属性信息存入文本
 * 获取系统信息:Properties getProperties()
 * 将信息输出到指定输出流中:void list(PrintStream out)
 * 将输出流中数据存入指定文件中:new PrintStream("systeminfo.txt")
 * @author songwenju
 *
 */
public class SystemInfor {
	public static void main(String[] args) throws IOException {
		Properties p = System.getProperties();
		PrintStream ps = new PrintStream("systemInfo.txt");
		System.setOut(ps);
		p.list(System.out);
	}
}

2.Properties——配置文件类

1.Properties是Hashtable的子类,它具备Map集合的特点。而且它里面还有存储的键值对,都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。

2. 可用于键值对形式的配置文件,在加载时,需要数据有固定的格式,常用的是:键=值

3.方法:

     1)设置

        Object setProperty(String key,String value);//设置键和值,调用Hashtable的方法put

    2)获取

        String getProperty(String key); //指定key搜索value

        Set<String> stringPropertyName();//返回属性列表的键集,存入Set集合

3、加载流和存入流

        void load(InputStream ism); //从输入字节流中读取属性列表(键和元素对)。又称将流中的数据加载进集合。

        void load(Reader reader);//从输入字符流中读取属性列表(键和元素对)。又称将流中的数据加载进集合。

        void list(PrintStream out);//将属性列表输出到指定的输出流

        void store(OutputStreamout,String comments);//对应load(InputStream )将属性列表(键值对)写入输出流。comments属性列表的描述。

        void store(Writerwriter, String comments); //对应load(Reader)将属性列表(键值对)写入输出流。comments属性列表的描述。

      代码示例一:

package file;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {
	public static void main(String[] args)throws Exception {
		//setAndGet();
		//getFromFile();
		loadDemo();
	}
	
	/**
	 * 使用Properties方法加载文件,修改文件并保存文件
	 * @throws Exception
	 */
	public static void loadDemo()throws Exception{
		FileInputStream fis = new FileInputStream("infor.txt");
		//定义Properties集合  
		Properties p = new Properties();
		//加载文件
		p.load(fis);
		FileOutputStream fos = new FileOutputStream("infor.txt");//位置应该放在这里不然会被全覆盖。
		//修改相应配置并保存
		p.setProperty("sex", "female");
		p.store(fos, "修改了一下");
		p.list(System.out);
		fos.close();
		fis.close();
	}
	
	/**
	 * 演示,如何将流中的数据存储到集合中。  想要将info.txt中键值数据存到集合中进行操作。  
	 * 1,用一个流和info.txt文件关联。 
	 * 2,读取一行数据,将该行数据用"="进行切割。 
	 * 3,等号左边作为键,右边作为值。
	 * 存入到Properties集合中即可。 
	 * 将文件数据存储进Properties集合方法  
	 */
	public static void getFromFile()throws Exception{
		//定义Properties集合  
		Properties p = new Properties();
		//使用字符读取缓冲流关联文件  
		BufferedReader bfr = new BufferedReader(new FileReader("infor.txt"));
		String line = null;
		while ((line = bfr.readLine())!= null) {
			//System.out.println(line);
			String[] pStrings =line.split("=");//将一行数据以“=”号进行分割  
            //将=左边作为键存入,将=右边作为值存入  
			p.setProperty(pStrings[0], pStrings[1]);
		}
		bfr.close();//关流
		System.out.println(p);
		
	}
	/**
	 * 设置属性和得到属性
	 */
	public static void setAndGet(){
		Properties p = new Properties();
		p.setProperty("name", "song");
		p.setProperty("age", "13");
		
		//System.out.println(p);
		Set<String> keys = p.stringPropertyNames();
		p.setProperty("age", 20+"");
		for (String string : keys) {
			System.out.println(string+":"+p.getProperty(string));
		}
	}
}
代码示例二:
package file;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Properties;

/**
 * 练习:用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。
 * 分析: 很容易想到的是:计数器。可是该计数器定义在程序中,随着该应用程序的退出,该计数器也在内存中消失了。
 * 所以要建立一个配置文件,用于记录该软件的使用次数。该配置文件使用键值对的形式。键值对数据是map集合。
 * 数据是以文件形式存储。使用io技术。那么map+io——>Properties。
 * 思路:
 *  1、用读取流关联文本信息文件。如果存在则读取,如果不存在,则创建
 *  2、每次运行,将文件数据存入集合中,读取值,判断次数,如果小于等于5次,则次数增加1次,如果大于则输出提示信息。
 *  3、将值小于等于5次的信息数据存入文件中
 * @author songwenju
 */
public class RunCount {
    public static void main(String[] args) throws Exception {
        //创建集合对象  ,文件+io考虑properties
        Properties prop = new Properties();
        //将文件进行封装  
        File file = new File("count.ini");
        //判断是否存在
        if (!file.exists()) {
            file.createNewFile();
        }
        //将文件于读取流进行关联  
        FileReader fReader = new FileReader(file);
        //加载流中的文件数据到集合中  
        prop.load(fReader);
        
        //定义计数器  
        int count = 0;
        //获取次数值  
        String vaule = prop.getProperty("time");
        //如果值不等于null,则将其赋值给count  
        if (vaule != null) {
            count = Integer.parseInt(vaule);
            
        }
        //每启动一次自增  
        count++;
        if (count >= 5) {
            System.out.println("软件试用次数5次已经到了,请购买!");
            return ;
        }
        //将次数记录住集合  
        prop.setProperty("time", count+"");
        FileWriter fWriter = new FileWriter(file);
        //将集合中的数据存入硬盘文件中  
        prop.store(fWriter, "软件使用次数");
        //关流  
        fWriter.close();
        fWriter.close();
        
    }
}
运行结果:

3.打印流

1.打印流包括:PrintStream和PrintWriter,该流提供了打印方法,可将各种类型的数据都原样打印。

2.字节打印流:PrintStream

        构造方法中可接收的参数类型:

        1)File对象。File(能接受文件的对象都是需要重点掌握的)

        2)字符串路径:String

        3)字符输出流:OutputStream

3.字符打印流:PrintWriter

        构造方法中可接受的参数类型

        1)File对象:File

        2)字符串路径:String

        3)字节输出流:OutputStream

        4)字符输出流:Writer

      与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,

      而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。

有2,3可知,3的功能更强大。

代码示例:

package file;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;

/**
 * @author songwenju
 *
 */
public class PrintWriteDemo {
	public static void main(String[] args) throws Exception {
		//键盘录入  
		BufferedReader bur = new BufferedReader(
				new InputStreamReader(System.in));
		//对流的操作,打印到控制台
		//PrintWriter pw = new PrintWriter(System.out,true);
		//打印流关联文件,自动刷新 
		PrintWriter pw = new PrintWriter(new FileWriter("a.txt"),true);//对println,printf进行自动刷新。只对流有用。
		
		String line = null;
		while ((line = bur.readLine())!= null) {
			if (line.equals("over")) {
				break;
			}
			pw.println(line.toUpperCase());
			//pw.flush();
		}
		//关闭流
		pw.close();
		bur.close();
	}
}
4.序列流

1)SequenceInputStream对多个读取流进行合并成一个读取流。也被称为合并流。

2)常用构造函数

        SequenceInputStream(Enumeration<?extends FileInputStream> e)

3)常见合并多个流文件步骤

        a)创建集合,并将流对象添加进集合

        b)创建Enumeration对象,将集合元素加入。

        c)创建SequenceInputStream对象,合并流对象

        d)创建写入流对象,FileOutputStream关联写入文件

        e)利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作。

代码示例:

package file;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

/**
 * 将三个文件的内容合并为一个
 * SequenceInputStream 合并流 
 * 需求:将三个文本文件中的数据合并到一个文本文件中 
 * 思路:1、创建一个Vector集合,将三个文本文件字节流添加到集合中 
 *     2、创建Enumeration对象,创建SequnceInputStream对象关联Enumeration 
 *     3、输出流关联新文本文件 
 *     4、反复读写操作 
 * @author songwenju
 *
 */
public class SequenceDemo {
	public static void main(String[] args) throws Exception {
		//创建vector集合,并添加相关流对象  
		Vector<FileInputStream> vector = new Vector<FileInputStream>();
		vector.add(new FileInputStream("1.txt"));
		vector.add(new FileInputStream("2.txt"));
		vector.add(new FileInputStream("3.txt"));
		//创建枚举对象  
		Enumeration<FileInputStream>  e = vector.elements();
		//合并流  
		SequenceInputStream sis = new SequenceInputStream(e);
		//关联写入文件  
		FileOutputStream fos = new FileOutputStream("4.txt");
		
		//反复读写操作  
		byte[] b = new byte[1024];
		int len;
		while ((len = sis.read(b))!= -1) {
			fos.write(b,0,len);
			fos.flush();
		}
		//关流
		fos.close();
		sis.close();
	}
}
运行结果:


------- android培训java培训、期待与您交流! ----------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值