Java面向对象 IO (三)



Java面向对象  IO  (三)


知识概要:

                   (1)IO 流的操作规律

                   (2)异常日志信息IO处理

                   (3)系统信息IO处理

                   (4)File类描述

                   (5)Properties与流的结合


IO流的操作规律


1,   需求:将键盘录入的东东打印在控制台上

      源:键盘录入。  

      目的:控制台。


2,需求:想把键盘录入的数据存储到一个文件中。


      源:键盘。
     
目的:文件。


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

      源:文件。
      
目的:控制台。

流操作的基本规律:

通过三个明确来完成。

1,明确源和目的。
      源:输入流。InputStream  Reader
      目的:输出流。OutputStream  Writer。
2,操作的数据是否是纯文本。
     是:字符流。
     不是:字节流。

3,当体系明确后,在明确要使用哪个具体的对象。
     通过设备来进行区分:
     源设备:内存,硬盘。键盘
     目的设备:内存,硬盘,控制台。

 
1,将一个文本文件中数据存储到另一个文件中。复制文件。
 源:因为是源,所以使用读取流。InputStream Reader 
 

 是不是操作文本文件。是!这时就可以选择Reader  。这样体系就明确了。

 接下来明确要使用该体系中的哪个对象。

 明确设备:硬盘。上一个文件。
 Reader体系中可以操作文件的对象是 FileReader 。
是否需要提高效率:是!加入Reader体系中缓冲区

 BufferedReader.

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




 目的:OutputStream Writer
 是否是纯文本。
 是!Writer。
 设备:硬盘,一个文件。
 Writer体系中可以操作文件的对象FileWriter。
 是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter
 
 FileWriter fw = new FileWriter("b.txt");
 BufferedWriter bufw = new BufferedWriter(fw);


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

2,需求:将键盘录入的数据保存到一个文件中。
 这个需求中有源和目的都存在。那么分别分析


 源:InputStream Reader
 是不是纯文本?是!Reader
 
 设备:键盘。对应的对象是System.in.
 不是选择Reader吗?System.in对应的不是字节流吗?
 为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
 所以既然明确了Reader,那么就将System.in转换成Reader。
 用了Reader体系中转换流,InputStreamReader

 InputStreamReader isr = new InputStreamReader(System.in);

 需要提高效率吗?

 需要!BufferedReader
 BufferedReader bufr = new BufferedReader(isr);


 目的:OutputStream  Writer
 是否是存文本?是!Writer。
 设备:硬盘。一个文件。使用 FileWriter。
 FileWriter fw = new FileWriter("c.txt");
 需要提高效率吗?需要。
 BufferedWriter bufw = new BufferedWriter(fw);

 字符编码输出

 目的:OutputStream  Writer
 是否是存文本?是!Writer。
 设备:硬盘。一个文件。使用 FileWriter。
 但是FileWriter是使用的默认编码表。GBK.
 
 但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。
 所以要使用的对象是OutputStreamWriter。
 而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream

 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");//转换流

 需要高效吗?需要。
 BufferedWriter bufw = new BufferedWriter(osw);

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

class  TransStreamDemo2
{
	public static void main(String[] args) throws IOException
	{
		System.setIn(new FileInputStream("PersonDemo.java"));

		System.setOut(new PrintStream("zzz.txt"));

		//键盘的最常见写法。
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));

		
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}

		bufr.close();

	}
}


异常日志信息IO处理

import java.io.*;
import java.util.*;
import java.text.*;
class  ExceptionInfo
{
	public static void main(String[] args)throws IOException 
	{
		try
		{
			int[] arr = new int[2];
			System.out.println(arr[3]);
		}
		catch (Exception e)
		{
			
			try
			{
				Date d = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String s = sdf.format(d);

				PrintStream ps = new PrintStream("exeception.log");
				ps.println(s);
				System.setOut(ps);

				
			}
			catch (IOException ex)
			{
				throw new RuntimeException("日志文件创建失败");
			}
			e.printStackTrace(System.out);
		}
	}
}


系统信息处理

import java.util.*;
import java.io.*;
class  SystemInfo
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = System.getProperties();

		//System.out.println(prop);
		prop.list(new PrintStream("sysinfo.txt"));
	}
}


File类描述

          用来将文件或者文件夹封装成对象   方便对文件与文件夹的属性信息进行操作 。
      File对象可以作为参数传递给流的构造函数。
    


 了解File类中的常用方法。

      File类常见方法:
      1,创建。


      boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
      和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。

 

     boolean mkdir():创建文件夹。

 
     boolean mkdirs():创建多级文件夹。

 
    2,删除。

 
     boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
     void deleteOnExit();在程序退出时删除指定文件。


   3,判断。


     boolean exists() :文件是否存在.
     isFile():
     isDirectory();
     isHidden();
     isAbsolute();

  4,获取信息。
    getName():
    getPath():

    getAbsolutePath()

    getParent(): 
    long lastModified()
    long length()


class FileDemo 
{
	public static void main(String[] args) throws IOException
	{
		method_5();
	}

	public static void method_5()
	{
		File f1 = new File("c:\\Test.java");
		File f2 = new File("d:\\hahah.java");

		sop("rename:"+f2.renameTo(f1));

	}

	public static void method_4()
	{
		File f = new File("file.txt");

		sop("path:"+f.getPath());
		sop("abspath:"+f.getAbsolutePath());
		sop("parent:"+f.getParent());
                                             //该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
				             //如果相对路径中有上一层目录那么该目录就是返回结果。

	}
	
	public static void method_3()throws IOException
	{
		File f = new File("d:\\java1223\\day20\\file2.txt");

		//f.createNewFile();

		//f.mkdir();


		//记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
		//通过exists判断。
		sop("dir:"+f.isDirectory());
		sop("file:"+f.isFile());

		sop(f.isAbsolute());
	}


	public static void method_2()
	{
		File f = new File("file.txt");

		//sop("exists:"+f.exists());

		//sop("execute:"+f.canExecute());

		//创建文件夹
		File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

		sop("mkdir:"+dir.mkdirs());
	}
	

	public static void method_1()throws IOException
	{
		File f = new File("file.txt");
                                    //sop("create:"+f.createNewFile());
		//sop("delete:"+f.delete());



		
	}







	//创建File对象
	public static void consMethod()
	{
		//将a.txt封装成file对象。可以将已有的和为出现的文件或者文件夹封装成对象。
		File f1 = new File("a.txt");

		
		File f2 = new File("c:\\abc","b.txt");


		File d = new File("c:\\abc");
		File f3 = new File(d,"c.txt");

		sop("f1:"+f1);
		sop("f2:"+f2);
		sop("f3:"+f3);

		File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");


	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}


递归

  函数自己调用自己。
  注意:递归时一定要明确结束条件。
  应用场景:
      • 当某一功能要重复使用时。
  练习:
      • 列出一个文件夹下所有的子文件夹以及子文件 

     

import java.io.*;

class  FileDemo2
{
	public static void main(String[] args) 
	{
		File dir = new File("c:\\");
		File[] files = dir.listFiles();

		for(File f : files)
		{
			System.out.println(f.getName()+"::"+f.length());
		}

		
	}

	public static void listDemo_2()
	{
		File dir = new File("d:\\java1223\\day18");

		String[] arr = dir.list(new FilenameFilter()
		{
			public boolean accept(File dir,String name)
			{

				//System.out.println("dir:"+dir+"....name::"+name);
				
				return name.endsWith(".bmp");

			}
		});


		System.out.println("len:"+arr.length);

		for(String name : arr)
		{
			System.out.println(name);
		}
	}

	public static void listDemo()
	{
		File f = new File("c:\\abc.txt");

		String[] names = f.list();//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
		for(String name : names)
		{
			System.out.println(name);
		}
	}
	public static void listRootsDemo()
	{
		File[] files = File.listRoots();

		for(File f : files)
		{
			System.out.println(f);
		}
	}
}

 

import java.io.*;

class FileDemo3 
{
	public static void main(String[] args) 
	{
		File dir = new File("d:\\testdir");

		System.out.println(dir.delete());
	}
	public static String getLevel(int level)
	{
		StringBuilder sb = new StringBuilder();
		sb.append("|--");
		for(int x=0; x<level; x++)
		{
			//sb.append("|--");
			sb.insert(0,"|  ");

		}
		return sb.toString();
	}
	public static void showDir(File dir,int level)
	{
		
		System.out.println(getLevel(level)+dir.getName());

		level++;
		File[] files = dir.listFiles();
		for(int x=0; x<files.length; x++)
		{
			if(files[x].isDirectory())
				showDir(files[x],level);
			else
				System.out.println(getLevel(level)+files[x]);
		}
	}

}




 思考:
      • 1,删除一个目录的过程是如何进行的?


删除原理:
在window中,删除目录从里面往外删除的。

既然是从里往外删除。就需要用到递归。



*/
import java.io.*;
class  RemoveDir
{
	public static void main(String[] args) 
	{
		
		File dir = new File("d:\\testdir");
		removeDir(dir);
	}

	public static void removeDir(File dir)
	{
		File[] files = dir.listFiles();
		
		for(int x=0; x<files.length; x++)
		{
			if(files[x].isDirectory())
				removeDir(files[x]);
			else
				System.out.println(files[x].toString()+":-file-:"+files[x].delete());
		}

		System.out.println(dir+"::dir::"+dir.delete());
	}

}


Properties与流的结合

     Properties是hashtable的子类。
     也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。

     是集合中和IO技术相结合的集合容器。

     该对象的特点:可以用于键值对形式的配置文件。

    那么在加载数据时,需要数据有固定格式:键=值。


练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。


          用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。很容易想到的是:计数器。
          可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。
          可是随着该应用程序的退出,该计数器也在内存中消失了。

         下一次在启动该程序,又重新开始从0计数。这样不是我们想要的。程序即使结束,该计数器的值也存在。
         下次程序启动在会先加载该计数器的值并加1后在重新存储起来。

          所以要建立一个配置文件。用于记录该软件的使用次数。

         该配置文件使用键值对的形式。
         这样便于阅读数据,并操作数据。

         键值对数据是map集合。
         数据是以文件形式存储,使用io技术。
         那么map+io -->properties.

         配置文件可以实现应用程序数据的共享。

import java.io.*;
import java.util.*;
class  RunCount
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = new Properties();

		File file = new File("count.ini");
		if(!file.exists())
			file.createNewFile();
		
		FileInputStream fis = new FileInputStream(file);

		prop.load(fis);
		

		int count = 0;
		String value = prop.getProperty("time");
		
		if(value!=null)
		{
			count = Integer.parseInt(value);
			if(count>=5)
			{
				System.out.println("您好,使用次数已到,拿钱!");
				return ;
			}

		}

		count++;

		prop.setProperty("time",count+"");

		FileOutputStream fos = new FileOutputStream(file);

		prop.store(fos,"");

		fos.close();
		fis.close();
		
	}
}




posted @ 2014-05-30 23:36  博客园杀手  阅读(180)  评论(0)    收藏  举报