黑马程序员——Java基础——IO流(三)

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

package cn.fuxi._08io;
/**
 * File类
 * 获取C盘目录下的隐藏文件.
 */
import java.io.*;
public class _01FileListDemo {
	public static void main(String[] args) {
		listDemo();
	}
	public static void listDemo(){
		File dir = new File("C:\\");
		File[] files = dir.listFiles(new FilterByHidden());
		for(File f:files){
			System.out.println(f);
		}
	}
}
class FilterByHidden implements FilenameFilter{
	public boolean accept(File dir,String name){
		return dir.isHidden();
	}
}
输出结果:
C:\$360Section
C:\$Recycle.Bin
C:\360Rec
C:\360SANDBOX
C:\a
C:\a26be26c93d927093af1c1
C:\Alimama
C:\Boot
C:\bootfont.bin
C:\bootmgr
C:\BOOTNXT
C:\BOOTSECT.BAK
C:\Documents and Settings
C:\end
C:\hiberfil.sys
C:\Intel
C:\IoDemoCopyText
C:\Linkin Park.jpg
C:\pagefile.sys
C:\PerfLogs
C:\Program Files
C:\Program Files (x86)
C:\ProgramData
C:\Recovery
C:\swapfile.sys
C:\System Volume Information
C:\Users
C:\Whenwhere I belong.avi
C:\Whenwhere I belong.txt
C:\Windows

package cn.fuxi._08io;
/**
 * 递归
 * 函数自身直接或者间接的调用到了自身.
 * 一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关.这时可以用递归来解决问题
 * 
 * P.S.
 * 1.递归一定明确条件,否则容易栈溢出.
 * 2.注意一下递归的次数.
 * 
 * 需求:对指定目录经行所有内容的列出(包含子目录中的内容),也可以理解为深度遍历
 */
import java.io.*;
public class _02FileRecursiveDemo1 {
	public static void main(String[] args) {
		File dir = new File("D:\\develop\\workspace\\fuxi4\\src");
		int level = 0;//目录层级
		listAll(dir,level);
	}
	public static void listAll(File dir ,int level){
		System.out.println(getSpace(level)+"dir:"+dir.getAbsolutePath());//getSpace()打印出更直观的效果,或者直接用level取代该方法用数字表示也可以
		level++;
		File[] files = dir.listFiles();//获取完整路径名
		//基本for循环,或者增强for循环二选一~
		/*
	  	for(int x = 0 ;x < files.length;x++){
			if(files[x].isDirectory()){
				listAll(files[x],level);
			}
		}
		*/
		//增强for循环
		for(File ff:files){
			if(ff.isDirectory()){
				listAll(ff,level);
			}
		}
	}
	public static String getSpace(int level){
		StringBuilder sb = new StringBuilder();//创建容器接收字符串输出效果
		sb.append("|--");
		for(int x = 0;x< level; x++){
			sb.append("|");//输出时每多一道"|"代表多一级子类目录
		}
		return sb.toString();
	}
}
输出结果:
|--dir:D:\develop\workspace\fuxi4\src
|--|dir:D:\develop\workspace\fuxi4\src\cn
|--||dir:D:\develop\workspace\fuxi4\src\cn\fuxi
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_01system
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_02runtime
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_03math
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_04date
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_05calendar
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_06io
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_07io
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_08io
|--|||dir:D:\develop\workspace\fuxi4\src\cn\fuxi\_09ioother

package cn.fuxi._08io;
/**
 * 需求:利用递归求任意正整数的十以内进制值
 */
public class _03FileRecursiveDemo2 {
	public static void main(String[] args) {
		int x = 10;
		int radix = 8;
		toBinary(x,radix);
	}
	public static void toBinary(int x,int radix){
		if(x>0){//如果x是大于0的
			toBinary(x/radix,radix);//递归调用本函数,参数除以进制数
			System.out.print(x%radix);//输出除以进制数余下的数
		}
	}
}
输出结果:
12
package cn.fuxi._08io;
/**
 * 需求:利用递归求任意数到任意数的和
 */
public class _04FileRecursiveDemo3 {
	public static void main(String[] args) {
		int a = 19;
		int b = 298;
		System.out.println(getSum(a,b));
	}
	public static int getSum(int a,int b){
		if(a==b){//用在初始值a和b就相同时,还有最终a或b增长到一样大时
			return a;//或return b;
		}else if(a<b){//a<b的话,递归a到b的和
			return a+getSum(a+1,b);
		}else{//a>b的话,递归b到a的和
			return b+getSum(a,b+1);
		}
	}
}
输出结果:
44380

package cn.fuxi._08io;
/**
 * 需求:删除一个带内容的目录.
 * 原理:必须从里往外删,需要进行深度遍历.
 */
import java.io.*;
public class _05FileRecursiveDemo4 {
	public static void main(String[] args) {
		File dir = new File("D:\\develop\\workspace\\fuxi4\\a");
		removeDir(dir);
	}
	public static void removeDir(File dir){//记住是先删内层
		File[] files = dir.listFiles();//注意:list()和listFiles()的区别,list()是文件内的文件的【字符串文件名】,listFiles()是文件内的文件的【完整路径名】.
		for(File ff: files ){//先增强for循环,取到每个子文件的路径,由内往外删除
			if(ff.isDirectory()){//是文件目录吗?
				removeDir(ff);//是的话就递归进入循环
			}else{//不是目录的话就打印并删除(内层)
				System.out.println(ff +":"+ff.delete());
			}
		}//跳出循环,外层不是目录的话就打印并删除
		System.out.println(dir+":"+dir.delete());
	}	
}
输出结果:
D:\develop\workspace\fuxi4\a\aa\bb:true
D:\develop\workspace\fuxi4\a\aa:true
D:\develop\workspace\fuxi4\a\新建文件夹\aa\bb:true
D:\develop\workspace\fuxi4\a\新建文件夹\aa:true
D:\develop\workspace\fuxi4\a\新建文件夹:true
D:\develop\workspace\fuxi4\a:true

package cn.fuxi._08io;
/*
 * Properties
 * 特点:
 * 1.该集合中的键和值都是字符串类型.
 * 2.集合中的数据可以保存到流中,或者从流中获取.
 * 3.通常该集合用于操作以键值对形式存在的配置文件.
 * Properties集合的存和取
 */
import java.util.*;
public class _06PropertiesDemo {
	public static void main(String[] args){
		propertiesDemo();
	}
	public static void propertiesDemo(){
		//创建一个Properties集合
		Properties prop = new Properties();
		//存储元素
		prop.setProperty("zhangsan", "10");//调用 Hashtable的方法 put。
		prop.setProperty("lisi", "20");
		prop.setProperty("wangwu", "30");
		prop.setProperty("zhaoliu", "40");
		//修改元素
		prop.setProperty("wangwu", "26");
		//取出所有元素
		Set<String> names = prop.stringPropertyNames();//返回此属性列表中的键集,其中该键及其对应值是字符串
		for(String name:names){
			String value = prop.getProperty(name);//用指定的键在此属性列表中搜索值。
			System.out.println(name+":"+value);
		}
	}
	
	
}
输出结果:
zhangsan:10
lisi:20
wangwu:26
zhaoliu:40

package cn.fuxi._08io;
/**
 * Properties集合和流对象相结合的功能
 */
import java.util.*;
public class _07PropertiesDemo2 {
	public static void main(String[] args) {
		propertiesDemo();
	}
	public static void propertiesDemo(){
		Properties prop = new Properties();
		prop.setProperty("zhangsan","10");
		prop.setProperty("lisi","20");
		prop.setProperty("wangwu", "30");
		prop.setProperty("zhaoliu", "40");
		prop.list(System.out);//将属性列表输出到指定的输出流。
	}
}
输出结果:
-- listing properties --
zhangsan=10
lisi=20
wangwu=30
zhaoliu=40

package cn.fuxi._08io;
import java.io.*;
import java.util.*;
public class _08PropertiesDemo3 {
	public static void main(String[] args) throws IOException {
		propertiesDemo();
	}
	public static void propertiesDemo() throws IOException{
		Properties prop = new Properties();
		prop.setProperty("zhangsan","10");
		prop.setProperty("lisi","20");
		prop.setProperty("wangwu", "30");
		prop.setProperty("zhaoliu","40");
		//想要将这些集合中的字符串键值信息持久化存储的文件中
		FileOutputStream fos = new FileOutputStream("info.txt");
		prop.store(fos,"name+age");//使用 load(InputStream) 将此 Properties 表中的属性列表(键和元素对)写入输出流。
		//需要关闭输出流
		fos.close();
	}
}
输出结果:



package cn.fuxi._08io;
import java.io.*;
import java.util.*;

public class _09PropertiesDemo4 {
	public static void main(String[] args) throws Exception {
		propertiesDemo();
	}
	public static void propertiesDemo() throws Exception{
		Properties prop = new Properties();
		//集合中的数据来自于一个文件.
		//注意:必须要保证该文件中的数据是键值对.
		//需要使用到读取流
		FileInputStream fis = new FileInputStream("info.txt");
		//使用load方法
		prop.load(fis);
		prop.list(System.out);
		test();
		myLoad();
	}
	//对已有的配置文件中的信息进行修改.
	//读取这个文件.并将这个文件中的键值数据存储到集合中.再通过集合对数据经行修改.
	//在通过流将修改后的数据存储到文件中
	public static void test() throws IOException{
		File file = new File("info.txt");
		if(!file.exists()){
			file.createNewFile();
		}
		FileReader fr = new FileReader("info.txt");
		//创建集合存储配置信息.
		Properties prop = new Properties();
		prop.load(fr);
		prop.setProperty("wangwu", "36");
		prop.setProperty("zhangsan", "27");
		FileWriter fw = new FileWriter(file);
		prop.store(fw, "lalala");
		fr.close();
	}
	//模拟一下load方法
	public static void myLoad() throws Exception{
		Properties prop = new Properties();
		BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
		String line = null;
		while((line = bufr.readLine())!=null){
			if(line.startsWith("#")){
				continue;
			}
			String[] arr = line.split("=");
			prop.setProperty(arr[0], arr[1]);
		}
		prop.list(System.out);
		bufr.close();
	}

}
输出结果:
-- listing properties --
zhangsan=10
lisi=20
zhaoliu=40
wangwu=30
-- listing properties --
zhangsan=27
lisi=20
wangwu=36
zhaoliu=40


package cn.fuxi._08io;
/**
 * 需求:
 * 		获取一个应用程序运行的次数,如果超过5此,给出使用次数已到,
 * 		请注册的提示,并不要再运行程序.
 * 思路:	1.应该有计数器
 * 		每次程序启动都需要计数异常,并且是在原有的次数上进行计数.
 * 		2.计数器就是一个变量,突然冒出一想法,程序启动时进行计数,计数器必须
 * 		存在于内存,并进行运算.
 * 		可是程序一结束,计数器消失了,那么再次启动该程序,计数器又重新被初始化了.
 * 		而我们需要多次启动同一个应用程序,使用的是同一个计数器.
 * 		这就需要计数器的生命周期变长,从内存存储到硬盘文件中.
 * 		3.如何使用这个计数器呢?
 * 		首先,程序启动时,应该先读取这个用于记录计数器信息的配置文件.
 * 		获取上一次计数器次数,并进行使用次数的判断.
 * 		起床,对该次数进行自增,并自增后的次数重写存储到配置文件中.
 * 		4.文件中的信息该如何经行存储并体现?
 * 		直接存储次数数值可以,但是不明确该数据的含义,所以起名字变得重要.
 * 		这就有了名字和值的对应,所以可以使用键值对.
 * 		既要用集合Map中的内容,又要用IO中的内容,所以用Properties.
 */
import java.io.*;
import java.util.*;

public class _10PropertiesTest {
	public static void main(String[] args) throws IOException{
		getAppCount();
	}
	public static void getAppCount() throws IOException{
		//将配置文件封装成对象
		File confile = new File("count.properties");
		if(!confile.exists()){
			confile.createNewFile();
		}
		FileInputStream fis = new FileInputStream(confile);
		Properties prop = new Properties();
		prop.load(fis);
		//从集合中通过键获取次数.
		String value = prop.getProperty("time");
		//定义计数器,记录获取到的次数
		int count =0;
		if(value!=null){
			count = Integer.parseInt(value);
		}
		if(count>=5){
			throw new RuntimeException("使用次数已到,请注册!");
		}
		count++;
		//将改变后的次数重写存储到集合中.
		prop.setProperty("time", count+"");
		FileOutputStream fos = new FileOutputStream(confile);
		prop.store(fos, "");
		fos.close();
		fis.close();
	}
}
输出结果:
Exception in thread "main" java.lang.RuntimeException: 使用次数已到,请注册!
at cn.fuxi._08io._10PropertiesTest.getAppCount(_10PropertiesTest.java:46)
at cn.fuxi._08io._10PropertiesTest.main(_10PropertiesTest.java:27)


package cn.fuxi._08io;
/**
 * 需求:获取指定目录下,指定扩展名的文件(包含子目录中的),并将这些文件的绝对路径写入
 * 到一个文本文件中.
 *		简单说:就是建立一个指定扩展名的文件的列表.
 * 思路:	1.必须进行深度遍历.
 * 		2.要在遍历的过程中进行过滤,将符合条件的内容都存储到容器中.
 * 		3.对容器中的内容进行遍历并且将绝对路径写入到文件中.
 */
import java.io.*;
import java.util.*;
public class _11IOTest {
	public static void main(String[] args) throws IOException {
		File dir = new File("D:\\develop\\workspace");//创建指定目录路径
		FilenameFilter filter = new FilenameFilter(){//创建过滤器,指定以".java"结尾的文件名
			public boolean accept(File dir,String name){
				return name.endsWith(".java");
			}
		};
		List<File> list = new ArrayList<File>();//创建Arraylist容器用来装过滤后的文件
		getFiles(dir,filter,list);//自定义一个方法寻找指定目录
		File destFile = new File(dir,"javalist.txt");//创建文件输出目录
		writeToFile(list,destFile);//将数据写入输出目录
	}
	/*对指定目录中的内容经行深度遍历,并按照指定过滤器经行过滤
	 * 将过滤后的内容存储到指定的容器list中.
	 * */
	public static void getFiles(File dir,FilenameFilter filter,List<File> list){
		File[] files = dir.listFiles();//创建文件路径数组
		for(File file:files){//遍历所有目录
			if(file.isDirectory()){//是目录吗?
				getFiles(file,filter,list);//进入目录再重复递归
			}else{
				//对遍历到的文件经行过滤器的过滤.将符合条件的File对象,存储到list集合中
				if(filter.accept(dir, file.getName())){//dir中包含指定名称吗?
					list.add(file);//包含的话就导入list中
				}
			}
		}
	}//写入到文件输入目录
	public static void writeToFile(List<File> list,File destFile) throws IOException{
		BufferedWriter bufw = null;//创建文件输入缓冲区
		try{
			bufw = new BufferedWriter(new FileWriter(destFile));//创建缓冲区
			for(File file:list){//遍历list中的文件路径
			bufw.write(file.getAbsolutePath());//写入file的绝对路径
			bufw.newLine();//每写一个换行一次
			bufw.flush();//刷新存入
			}
		}finally{
			if(bufw!=null)
				try{
					bufw.close();//关闭缓冲区
				}catch(IOException e){
					throw new RuntimeException("关闭失败");
				}
		}		
	}
}
输出结果:

package cn.fuxi._08io;
/**
 * 打印流
 * PrintWriter与PrintStream:可以直接操作输入流和文件
 * PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数值表现形式.
 * 与其他输出流不同,PrintStream永远不会抛出IOException
 * PrintStream打印的所有字符都使用平台的默认字符编码转换为字节.
 * 在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类.
 * 
 * PrintStream:
 * 1.提供了打印方法,可以对多种数据类型值经行打印,并保持数据的表示形式.
 * 2.它不抛IOException
 * 
 * 构造函数,接收三种类型的值:
 * 1.字符串路径
 * 2.File对象
 * 3.字节输出流
 */
import java.io.*;
public class _12PrintStreamDemo {
	public static void main(String[] args) throws Exception {
		PrintStream out  = new PrintStream("PrintStream.txt");
		//write(int i); 方法只写最低8位
		out.write(97);//a
		//print方法将97线变成字符串保持原样将数据打印到目的地
		out.print(97);//97
		out.close();
	}
}
输出结果:


package cn.fuxi._08io;
/**
 * PrintWriter:字符打印流
 * 构造函数参数:
 * 1.字符串路径
 * 2.File对象
 * 3.字符输出流
 * 4.字符输出流
 * 
 */
import java.io.*;

public class _13PrintWriterDemo {
	public static void main(String[] args) throws IOException {
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);
		String line = null;
		while((line = bufr.readLine())!=null){
			if("over".equals(line)){
				break;
			}
			pw.print(line.toUpperCase()+"\r\n");
			pw.flush();
		}
		pw.close();
		bufr.close();
		
		
	}
}
输出结果:
sss
SSS
qqq
QQQ
www
WWW
eeeee
EEEEE
over

package cn.fuxi._08io;
import java.io.*;
//写入到out.txt中
public class _14PrintWriterDemo2 {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter("out.txt");
		String line = null;
		while((line = br.readLine())!=null){
			if(line.equals("over")){
				break;
			}
			pw.println(line.toUpperCase());
			pw.flush();
		}
		pw.close();
		br.close();
		
	}

}
输入数据:
12345
上山打老虎
老虎不在家
打到小松鼠
over

输出结果:

package cn.fuxi._08io;
/**
 * 序列流
 * SequenceInputStream:对多个流进行合并.
 * 需求:
 * 		将1.txt 2.txt 3.txt文件中的数据合并到一个文件中.
 */
import java.io.*;
import java.util.*;
public class _15SequenceInputStream {
	public static void main(String[] args) throws IOException {
		Vector<FileInputStream> v = new Vector<FileInputStream>();
		v.add(new FileInputStream("PrintStream.txt"));
		v.add(new FileInputStream("out.txt"));
		v.add(new FileInputStream("IoDemo.txt"));
		Enumeration<FileInputStream> en = v.elements();
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("4.txt");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = sis.read(buf))!=-1){
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
}
输出结果:

package cn.fuxi._08io;
/**
 * 使用ArrayList比Vector效率高.
 */
import java.util.*;
import java.io.*;

public class _16SequenceInputStream2 {
	public static void main(String[] args) throws IOException {
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		for(int x = 1;x<=3;x++){
			al.add(new FileInputStream(x + ".txt"));
		}
		final Iterator<FileInputStream> it = al.iterator();
		Enumeration<FileInputStream> en = Collections.enumeration(al);
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("4.txt");
		byte[] buf = new byte[1024];
		int len = 0 ;
		 while ((len = sis.read(buf))!=-1){
			 fos.write(buf,0,len);
		 }
		 fos.close();
		 sis.close();		
	}
}


package cn.fuxi._09ioother;
/**
 * 操作对象
 * ObjectInpuStream与ObjectOutputStream
 * P.S.
 * 被操作的对象要实现Serializable.
 * 类通过实现java.io.Serializable接口以启用序列化功能,Serializable只是一个标记接口.
 */
import java.io.*;
class Person implements Serializable{
	private static final long serialVersionUID = 521;
	private String name;
	private int age;
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return age;
	}
}


public class _01ObjectInputStream {
	public static void main(String[] args) throws Exception {
		readObj();
	}
	public static void readObj() throws Exception{
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
		Person p = (Person)ois.readObject();
		System.out.println(p.getName()+":"+p.getAge());
		ois.close();		
	}
}

package cn.fuxi._09ioother;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * 编码表
 * 由来:
 * 		计算机智能识别二进制数据,早期由来是电信号,未来方便应用计算机,让它可以识别各个国家
 * 的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表.
 * 
 * 常见的编码表:
 * 		ASCII:美国标准信息交换码,用一个字节的7位可以表示.
 * 		ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位表示.
 * 		GB2312:中国的中文码表.
 * 		GBK:中国的中文码表升级,融合了更多的中文文字符号.
 * 		Unicode:国际标准码,融合了多种文字.(所有的文字都用两个字节来表示,Java语言使用的就是Unicode)
 * 		UTF-8:最多用三个字节来表示一个字符.
 */

public class _02EncodeDemo {
	public static void main(String[] args) throws IOException {
		//字符串-->字节数组:编码
		//字符数组-->字符串:解码
		String str = "您好";
		//编码
		byte[] buf1 = str.getBytes("GBK");
		printBytes(buf1);
		byte[] buf2 = str.getBytes("UTF-8");
		printBytes(buf2);
		//解码
		String s1=  new String(buf1);
		System.out.println(s1);//您好
		String s2 = new String(buf1,"Unicode"); 
		System.out.println(s2);//??
		String s3 = new String(buf2,"UTF-8");
		System.out.println(s3);//您好
		String s4 = new String(buf2,"GBK");
		System.out.println(s4);//鎮ㄥソ
	}
	private static void printBytes(byte[] buf){
		for(byte b:buf){
			System.out.println(b+" ");
		}
	}
}
//原因分析:
/*
 * "您好"的GBK编码在UTF-8码中查不到对应的字符,用"?代替.
 * "?"在UTF-*中的编码为-17 -65 -67
 * 故即使使用UTF-8码表进行解码,获取的字节也不是您好的"GBK"编码后的字节.
 * 所以无法成功解码 
 * 
 * P.S.
 * "谢谢"的gbk编码在UTF-8码表中可以查到对应的字符,为"ππ".
 * 因此,使用UTF-8码表对"ππ"进行解码,获取的字节依然不是gbk编码后的字节
 * 所以无法成功解码
 */
输出结果:
-60 
-6 
-70 
-61 
-26 
-126 
-88 
-27 
-91 
-67 
您好
??
您好
鎮ㄥソ



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值