JavaSE高级部分之IO流

java.io.File

文件和目录路径名的抽象表示形式。

构造方法

  • public File(String pathname):里面当前文件夹/文件的路径 (推荐方式)
  • public File(String parent,String child):parent的字符串路径名和child的字符串路径名构造一个File
  • public File(File parent,String child):参数1:需要描述parent的字符串路径名和子文件字符串路径名:构造一个File
public class FileDemo {
	
	public static void main(String[] args) {
		//描述:D盘下的demo文件夹:D:\demo\a.txt
		//public File(String pathname):里面当前文件夹/文件的路径
		File  file = new File("d:\\demo\\a.txt") ;
		System.out.println(file);//e:\demo\a.txt
		
		System.out.println("------------------------------");
		//描述:d盘下的demo文件夹中的a.txt文件
//		public File(String parent,String child)
		File file2 = new File("d:\\demo\\a.txt") ;
		System.out.println(file2);//E:\demo\a.txt
		
		System.out.println("------------------------------");
		
		//描述:d盘下的demo文件夹中的a.txt文件
		//public File(File parent,String child):
		File file3 = new File("D:\\demo") ;
		File file4 = new File(file3,"a.txt") ;
		System.out.println(file4);//D:\demo\a.txt
		
	}
}

File类的创建功能

  • public boolean createNewFile()throws IOException:创建文件

  • public boolean mkdir():创建目录(文件夹):如果存在该文件夹,返回值false

  • public boolean mkdirs():

  • 创建目录(文件夹):创建多级目录,如果父目录不存在,会自动创建!

  • 如果描述文件或者文件夹没有指定盘符,相对路径:默认是当前项目路径下

public class FileDemo2 {
	
	public static void main(String[] args) throws IOException {
		//需要在D盘下的text目录下创建一个a.txt文件
		//1)描述这个路径:File
	
		File file = new File("d:\\test\\a.txt") ;
		//创建文件
		//public boolean createNewFile()throws IOException
		System.out.println("createNewFile():"+file.createNewFile());
		//如果要在test目录下创建a.txt文件:File只是在描述路径:那么test目录必须存在!
		
		// public boolean mkdir()
		//d盘下:创建一个test文件夹
		File file2 = new File("d:\\test") ;
		System.out.println("mkdir():"+file2.mkdir());
		
		System.out.println("------------------------------------");
		
		//public boolean mkdirs():
		File file3 = new File("d:\\aaa\\bbb\\ccc\\ddd") ;
		System.out.println(file3.mkdirs());
		
		//创建一个文件:b.txt
		File file4 = new File("b.txt") ; //所处的相对路径:在当前项目下创建文件
		System.out.println(file4.createNewFile());
		
		File file5 = new File("aaa\\bbb\\ccc\\ddd") ;
		System.out.println(file5.mkdirs());
		
	}
}

File类的删除功能

public boolean delete():删除目录/文件,

  • 如果删除的是目录,那么前提条件:目录必须为空
public class FileDemo3 {
	
	public static void main(String[] args) {
		
		//删除当前项目下的b.txt文件
		//描述b.txt文件
		File file = new File("b.txt") ;
		//System.out.println(file);
		
		//public boolean delete()
		System.out.println("delete():"+file.delete());
		System.out.println("---------------------------------");
		
		//删除当前项目aaa这个目录
		File file2 = new File("aaa\\bbb\\ccc\\ddd") ;
		System.out.println(file2.delete());
		
		//删除demo文件夹
		//File file3 = new File("demo\\a.txt") ;
		//System.out.println(file3.delete());
		File file4 = new File("demo") ;
		System.out.println(file4.delete());
		
	}
}

重命名功能

针对某个文件操作

  • public boolean renameTo(File dest):
 * 需求:将当前项目下的a.jpg --- b.jpg  
 * 情况1:
 * 		当前文件的路径和该名后的路径相同,仅仅是改名字
 * 情况2:
 * 		当前文件的路径名和该后面的路径名不相同,剪切并重命名
public class FileDemo4 {
	
	public static void main(String[] args) {
		
		//描述下当前项目下的a.jpg
		//情况1:当前文件的路径和该名后的路径相同,仅仅是改名字
		/*
		File file = new File("a.jpg") ;
		
		//public boolean renameTo(File dest):
		File file2 = new File("b.jpg") ;
		System.out.println("renameTo():"+file.renameTo(file2)) ;
		*/
		
		//情况2:当前文件的路径名和该后面的路径名不相同,剪切并重命名
		File file = new File("b.jpg");
		//该名后的路径
		File file2 = new File("d:\\mm.jpg") ;
		//調用方法
		System.out.println("renameTo():"+file.renameTo(file2));
	}
}

File的判断功能

public boolean isFile():判断是否是文件

  • public boolean isDirectory():判断是否是文件夹(目录)
  • public boolean canRead():判断是否可读
  • public boolean canWrite():判断是否可写
  • public boolean exists():判断所file表示的文件/目录是否存在
  • public boolean isAbsolute():判断是否是绝对路径
  • public boolean isHidden():判断是否是隐藏文件
public class FileDemo5 {
	
	public static void main(String[] args) {
		File  file = new File("a.txt") ;
		
		System.out.println("isFile():"+file.isFile());
		System.out.println("isDirectory():"+file.isDirectory());
		System.out.println("canRead():"+file.canRead());
		System.out.println("canWrite():"+file.canWrite());
		System.out.println("exists():"+file.exists());
		System.out.println("isAbsolute()():"+file.isAbsolute());
		System.out.println("isHidden():"+file.isHidden());
	}
}

File类的获取功能

基本获取功能

  • public String getAbsolutePath():获取绝对路径名
  • public String getPath():当前文件所表示的路径
  • public long length():获取文件长度
  • public long lastModified():获取当前文件最后一次修改的时间(long:毫秒值)
public class FileDemo6 {
	
	public static void main(String[] args) {
		
		File file = new File("a.txt") ;
		//public String getAbsolutePath()
		System.out.println("getAbso():"+file.getAbsolutePath());//D:\JavaEE2008_workspace\day26\a.txt
		
		//public String getPath()
		System.out.println("getPath():"+file.getPath());//a.txt
		System.out.println("length():"+file.length());
		
		System.out.println("lastModified():"+file.lastModified());
		//1604284636537
		
		//long-----Date:日期格式java.util.Date
		long time = 1604284636537L ;
		Date date = new Date(time) ;
		
		//Date----String:字符串文本格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
		//格式化操作
		String dateStr = sdf.format(date) ;
		System.out.println(dateStr);//2020-11-02 10:37:16
		
	}
}

高级获取功能

public File[] listFiles():获取的是某个盘符下/目录File数组(目录中的文件)

  • public String[] list():获取某个盘符/目录的下的所有文件以及目录的字符串数组
  • 需求:
  • 获取当前d盘下的所有的以".jpg"结尾的文件!
  • 分析:
  • 1)描述下d盘符 d:\
  • File类描述
  • 2)获取当前盘符下所有的文件/文件夹所表示字符串数组/目录下的文件的File数组
  • 3)判断如果当前字符串数组或者File数组不为空,遍历获取到每一个文件/目录
  • 4)判断当前file是否是表示的文件
  • 再次判断是否以".jpg"结尾---->String --> endsWith(".jpg")
  • 5)输出即可!
 public class FileTest {
	
	public static void main(String[] args) {
		
		//描述下d盘符			d:\\	
		File file = new File("d:\\") ;
		//System.out.println(file);
		
		//public File[] listFiles()
		File[] fileArray = file.listFiles() ;
		//防止空指针
		if(fileArray!=null) {
			//遍历
			for(File f:fileArray) {
				//System.out.println(f);
				//判断f对象是否描述的文件
				if(f.isFile()) {
					//是文件
					//还需要判断:当前文件是否以.jpg结尾
					if(f.getName().endsWith(".jpg")) {
						//是以.jpg结尾
						//输出
						System.out.println(f.getName());
					}
				}
				
			}
		}
	}
}

高级获取功能

  • public File[] listFiles()
  • 需求:
  • 获取当前d盘下的所有的以".jpg"结尾的文件!
  • 分析:
  • 1)描述下d盘符 d:\
  • File类描述
  • 2)获取当前盘符下所有的文件/文件夹所表示字符串数组/目录下的文件的File数组
  • 3)判断如果当前字符串数组或者File数组不为空,遍历获取到每一个文件/目录
  • 4)判断当前file是否是表示的文件
  • 再次判断是否以".jpg"结尾---->String --> endsWith(".jpg")
  • 5)输出即可!
    使用public File[] listFiles()能够实现功能,但是比较麻烦,提供了一下这个方法:
  • public String[] list()
  • public String[] list(FilenameFilter filter)
  • public File[] listFiles(FilenameFilter filter)
  • 在调用这个方法的时候,列表已经获取到了
  • FilenameFilter:文件名称过滤器
  • 抽象方法:
  • boolean accept(File dir,String name):是否将文件添加到文件列表中
  • 返回值为true:添加到指定文件列表中;
  • 方法业务:根据具体的情况判断
  • “所有的以”.jpg"结尾的文件!"
  • dir表示是否文件
  • name是否"已.jpg结尾"
public class FileTest2 {
	
	public static void main(String[] args) {
		
		
		//描述一下D盘
		File file = new File("D:\\") ;
		
		//public File[] listFiles(FilenameFilter filter):高级功能:获取file表示的目录中文件的File数组
			//参数为:文件名称过滤器
		File[] fileArray = file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				//return false;
				//业务:
				/**
				 * "所有的以".jpg"结尾的文件!"
 *  					dir表示是否文件
 *  					name是否"以.jpg结尾"
				 */
				/*
				 File file = new File(dir,name) ;
				boolean flag1 = file.isFile() ; //true:是文件
				boolean flag2 = name.endsWith(".jpg") ;//true:文件名称是以.jpg结尾
				//System.out.println(name);
				return flag1 && flag2 ;
				*/
				//一步走:
				return new File(dir,name).isFile() && name.endsWith(".jpg") ;
			}
		}) ;
		
		//遍历File数组
		if(fileArray!=null) {
			for(File f:fileArray) {
				System.out.println(f.getName());
			}
		}
	
	}
}

方法递归

  • 就是方法本身调用方法一种现象!
  • Math.max(10,Math.max(40,70)) ; 方法嵌套方法
 举例:	
 * 	伪代码
 * 		public void show(int n){ //10
 * 			//出口条件(方法结束条件)
 * 			if(n<0){
 * 
 * 				
 * 				System.exit(0) ;//Java虚拟机终止了
 * 			}
 * 			System.out.println(n) ;
 * 			show(n--)  ;
 * 		}
 * 

递归

  • 1)必须定义一个方法:方法调用方法
  • 2)满足一定的规律
  • 3)方法必须有出口条件(结束条件)—>否则:就是死递归!
    注意事项:
  • 构造方法不存在递归!

举例:

public class DiGuiDemo {
	
	/*
	public DiGuiDemo() {
		DiGuiDemo();
	}
	*/
}
/**
 * 求5的阶乘
 * 1)for循环思想
 * 	n!= n*(n-1)!
 * 			....
 * 				...
 * 
 * 2)递归的思想:
 * 	1)定义一个方法:方法还需要调用本身
 * 	2)有一定规律
 * 	3)出口条件
 *
 */
public class DiGuiTest {
	
	public static void main(String[] args) {
		
		//求阶乘实现
		//定义最终结果变量
		int jc = 1 ;
		for(int x = 1 ; x <= 5 ; x ++) {
			jc *= x ;
		}
		System.out.println("5的阶乘是:"+jc);
		System.out.println("5的阶乘是:"+getJc(5));
	}

	//获取最终结果
	private static int getJc(int n) {//5
		//出口条件
		if(n==1) {	// 5 * 4 * 3 * 2 * 1 ...
			return 1 ;
		}else {
			return  n*getJc(n-1) ;  //5 * getJc(5-1) 
					
		}
		/**
		 * 递归的思想:
		 * 分解法:
		 * 		5!
		 * 		5 * 4 !
		 * 			4 * 3 !
		 * 				3 * 2 !
		 * 					2 * 1!		1!==1
		 * 			
		 * 
		 */
	}
}
/*
	需求:如果有一对兔子,从第三个月起产生一对兔子,小兔子经过第三个月后有产生一对兔子,
* 	假如兔子都不死,最终第二十个月有多少对兔子?
* 
* 规律:
* 		1)第一个月:1对
* 		    第二个月:1对
* 		   第三个月:2对
* 		  第四个月: 3对
* 		   第五个月:5对
* 		  第六个月:8对
* 		  ...
* 		2)第一个月和第二个月兔子对数都是1
* 		 从第三个月开始,每个月兔子的对数等于前两个月兔子对数之和
* 
* 解析
* 	方式1:利用数组
* 		arr[1] arr[0]都是已知的	(角标值表示第几个月)
* 		从第三个月开始,角标2开始,遍历数组  int[] arr = new int[20] ;
*   	arr[x] = arr[x-1]+arr[x-2];
*   
*   方式2:变量的变化
*   	将相邻两个月分别表示a,b
*   第一个月,    第二个月
*   		a = 1 ,b =1 
*   第二个月,	第三个月
*   		a = 1,b = 2
*   第三个月		第四个月
*   	a = 2,b = 3
*   第四个月,第五个月
*   	a= 3,b = 5 
*   ....
*   下一次的a是上一次的b,下一次的b是上一次的a+b
*   
* */ 
public class Test2 {
	
	public static void main(String[] args) {
		//方式1:数组的方式
		//创建一个数组,动态初始化
		int[] arr = new int[20] ; 
		
		//0-19:20个月
		//第一个月
		//第二个月都是1
		arr[0] = 1 ;
		arr[1] = 1 ;
		
		//从第三个月开始,角标2开始,遍历数组 
		for(int x = 2 ; x < arr.length ; x ++) {
//			每个月兔子的对数等于前两个月兔子对数之和
			arr[x] = arr[x-1] + arr[x-2] ;
		}
		
		System.out.println("第二十个月兔子的对数:"+arr[19]);
		System.out.println("----------------------------------");
		/**
		 * 方式2:变量的变化
			*   	将相邻两个月分别表示a,b
			*   第一个月,    第二个月
			*   		a = 1 ,b =1 
			*   第二个月,	第三个月
			*   		a = 1,b = 2
			*   第三个月		第四个月
			*   	a = 2,b = 3
			*   第四个月,第五个月
			*   	a= 3,b = 5 
			*   ....
			*   下一次的a是上一次的b,下一次的b是上一次的a+b
		 */
		//定义两个变量:a,b来表示相邻两个月的数据
		int a = 1 ;
		int b = 1 ;
		//前两个月已经存在值了
		//18个月
		for(int x = 0 ; x <18 ; x ++) {
			//使用中间变量的方式
			//使用temp变量记录一下的a
			int temp = a ;
			a = b ;
			b = temp + a ;
		}
		System.out.println("第二十个月兔子的对数是:"+b);
		System.out.println("-------------------------");
		//递归的思想
		/**
		 * 定义变量n: 表示第几个月
		 * 		当前n==1或者n==2 都是1对兔子 出口条件(结束条件)
		 * 		
		 * 如果不是第一个月或者第二个月:从第三个月开始
		 * 		方法名(n-1)+方法名(n-2)
		 * 
		 * 
		 */
		System.out.println("第二十个月兔子的对数是:"+getRabNum(20));
		
	}

	//n表示的第几个月
	private static int getRabNum(int n) {
		//出口 条件
		if(n==1|| n==2) {
			//第一个月或者第二个月的兔子对数都是1
			return 1 ;
		}else {
//		如果不是第一个月或者第二个月:从第三个月开始,每个月兔子对数等于前两个月之和
			return getRabNum(n-1) + getRabNum(n-2) ;
		}
	}
}
/**
 * 需求
 * 		需要删除带内容的目录
 * 		删除当前项目下:demo文件夹
 * 
 * 分析:
 * 		1)描述下当前demo文件夹:File file = new File("demo") ;
 * 		2)定义一个方法:delete(file) 递归删除的方法(删除目录)
 * 			2.1)高级获取功能:获取当前file所表示的文件以及文件夹的File数组[]
 * 			2.2)判断当前File数组不为空
 * 					判断当前file是否是文件夹 isDirectory()
 * 						是文件夹,回到2)步继续调用
 * 
 * 					不是文件夹,是文件
 * 						直接删除:调用delete()删除(查看删除的是
 * 那个文件:获取文件名称)
 * 						
 *				2.3)删除文件夹:调用delete()删除当前空目录
 *
 */
public class Test3 {
	
	public static void main(String[] args) {
		
		//1)使用File 描述当前项目下的demo文件夹
		File srcFile = new File("demo") ;
		
		//2)定义一个删除目录的方法
		delete(srcFile) ;
	}
	
	private static void delete(File srcFolder) {
		//获取srcFolder文件夹下面的所有文件以及文件夹的File数组
		File[] fileArray = srcFolder.listFiles() ;
		if(fileArray!= null) {
			//遍历
			for(File file :fileArray) {
				//获取到每一个file对象,判断当前是否是文件夹
				if(file.isDirectory()) {
					//回到2)进行递归删除
					delete(file);//aaa  bbb ccc
				}else {
					//不是文件夹,直接删除
					System.out.println(file.getName()+"---"+file.delete());
				}
			}
			//删除目录
			System.out.println(srcFolder.getName()+"---"+srcFolder.delete());
		}
		
	}
}

IO流

在设备之间进行数据传输的操作!
按流的方向划分:

  • 输入流

  • 输出流
    按流的类型划分

  • 字节流

  • 字节输入流:InputStream

  • 字节输出流:OutputStream

  • 字符流

  • 字符输入流:Reader

  • 字符输出流:Writer

  • 字符流是在字节输入流之后出现的,解决了中文乱码问题!

  • 一般情况:针对某个文本文件进行读写复制操作: 优先采用字符流 (使用记事本打开并且能读懂!)

字节流

  • 字节输入流:InputStream

  • 字节输出流:OutputStream

  • 两个抽象类,不能直接实例化,提供了一些具体的子类

  • XXXInputStream

  • XXXOutputStream

  • 都是字节输入流和字节输出流的子类

需求:需要在当前项目下输出文件:fos.txt文件,并同时输出内容:"hello,OutputStream"

  • FileOuputStream:针对文件操作:文件输出流(文件字节输出流)
  • public FileOutputStream(String name):
  • public FileOutputStream(File file)
  • 推荐使用第一种:直接跟当前的具体路径!

使用步骤

  • 1)创建OutputStream字节输出流对象,同时指向某个文件路径
  • 2)写数据:给文件中写入内容
  • 3)关闭相关的系统资源
public class FileOutputStreamDemo {
	
	public static void main(String[] args) throws IOException {
		
		//1)创建OutputStream字节输出流对象,同时指向某个文件路径
//		OutputStream out = new FileOutputStream("fos.txt") ;//抽象类多态方式
		
		//创建输出流对象---->调用系统资源:在本地的项目下创建具体文件fos.txt
		//流对象---指向文件地址
		FileOutputStream fos = new FileOutputStream("fos.txt") ;
		
		
		
		//2)写入内容
		//通过流对象给文件写入内容(写入的字节数组)
		fos.write("hello,outputStream".getBytes());
		
		//3)释放资源
		//将输出流对象的系统资源释放掉!
		fos.close();
	}
}

字节输出流写数据的功能

  • void write(byte[] b) :给指定的文件写入字节数组
  • void write(byte[] b, int off, int len) :写入字节数组的一部分
  • abstract void write(int b) :写入一个字节
public class FileOutputStreamDemo2 {
	
	public static void main(String[] args) throws IOException {
		
		//创建一个文件字节输出流对象
		FileOutputStream fos = new FileOutputStream("fos2.txt") ;
		
		// void write(int b) :写入一个字节
		//写入97:字节---保存的时候,在ASII码表中找当前字节对应的整数值
		//fos.write(97);
		
		//void write(byte[] b) :给指定的文件写入字节数组 
		//创建字节数组,静态初始化
		byte[] bytes = {97,98,99,100,101} ;
		//fos.write(bytes);
		
		//void write(byte[] b, int off, int len) :写入字节数组的一部分
		fos.write(bytes, 1, 2);
		
		//关闭资源
		fos.close();
	}
}

异常的处理方式

  • throws
  • try…catch…finally:开发汇中,使用这种格式
  • IO流中:字节输出流中加入异常操作
public class FileOutputStreamDemo3 {

	public static void main(String[] args) {
		
		//在当前项目下:输出fos3.txt文件
//		方式1:分别进行try...catch
		/*
		FileOutputStream fos = null ;
		try {
			 fos = new FileOutputStream("fos3.txt") ;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		//写数据
		try {
			fos.write("hello,io,i'm coming...".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//关闭资源
		if(fos!=null) {
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		*/
		
		//方式2:try...catch...catch...finally...
		//创建字节输出流对象
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream("fos3.txt");
			//写数据
			fos.write("hello,io!i'm coming...".getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//释放资源
			//如果当前流对象不为null,才能够关闭
			if(fos!=null) {
				//关闭资源
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}				
			}	
		}	
	}
} 

文件字节输出流: FileOutputStream

构造方法

  • public FileOutputStream(String name, boolean append):
  • 创建输出流对象,并指向文件,将文件内容写入到末尾:第二个参数为:true:写入末尾
  • 如何进行换行,写一个内容,换一行!
  • windows操作系统:
  • 换行符号:\r\n
 public class FileOutputStreamDemo4 {
	
	public static void main(String[] args) throws IOException {
		
		//public FileOutputStream(String name,  boolean append):
		//末尾追加内容
		FileOutputStream fos = new FileOutputStream("fos4.txt", true) ;
		
		//写入数据
		for(int x = 0 ; x <10 ; x ++) {
			fos.write(("hello"+x).getBytes());
			
			//写入一个换行符号
			fos.write("\r\n".getBytes());
		}
		
		//关闭资源
		fos.close();
	}
}

读写复制操作

在d盘下有一个FileInputStreamDemo.java文件的内容

  • 复制到当前项目路径下:Copy.java文件中
  • 分析:
  • 1)封装d盘的文件FileInputStreamDemo.java —源文件
  •  使用输入流读取FileInputStreamDemo.java文件的内容
    
  • 2)封装目标文件:当前项目下:Copy.java
  •  使用文件字节输出流写数据,将上面的内容复制进来!
    
  • 3)两种方式
  •  	要么1)一次读取一个字节
    
  •  	要么2)一次读取一个字节数组
    
  • 复制图片文件/视频文件…
public class CopyFileDemo {
	
	public static void main(String[] args) throws IOException {
		
		//封装d盘的文件FileInputStreamDemo.java ---源文件
		//创建字节文件输入流对象
		FileInputStream fis = new FileInputStream("d:\\FileInputStreamDemo.java") ;
		
		//封装目标文件:当前项目下:Copy.java 
		FileOutputStream fos = new FileOutputStream("Copy.java") ;
		
		/*
		//读写复制操作
		//方式1):1次读取一个字节
		int by = 0 ;
		while((by=fis.read())!=-1) {
			//读一个字节,写一个字节到fos流对象中
			fos.write(by);
		}
		*/
		
		//方式2:一次读取一个字节数组
		//定义一个数组
		byte[] bytes = new byte[1024] ;
		int len = 0 ;
		while((len=fis.read(bytes))!=-1) {
			//写一个字节数组:从0开始,写入实际字节数
			fos.write(bytes, 0, len);
		}
		
		//释放资源
		fos.close();
		fis.close();
	}
}

在d盘:一个mp4文件—将复制到当前项目下:copy.mp4文件中

public class CopyMp4Demo {
	
	public static void main(String[] args) throws IOException {
		//开始时间
		long start = System.currentTimeMillis() ;
		
		method("D:\\a.mp4","Copy.mp4") ;
		//结束时间
		long end = System.currentTimeMillis() ;
		System.out.println("共耗时:"+(end-start)+"毫秒");
	}
	
	//方式1:一次读取一个字节
	//方式2:一次读取一个字节数组
	private static void method(String srcFile, String destFile) throws IOException {
		
		//封装源文件
		FileInputStream fis = new FileInputStream(srcFile) ;
		//封装目标文件
		FileOutputStream fos = new FileOutputStream(destFile) ;
		
		/*
		//读写操作
		int by = 0 ;
		while((by=fis.read())!=-1) {
			//写
			fos.write(by);
		}*/
		
		//一次读取一个字节数组
		byte[] bytes = new byte[1024] ;//缓冲区
		int len = 0 ;
		while((len=fis.read(bytes))!=-1) {
			fos.write(bytes, 0, len);
		}
		
		
		//释放资源
		fos.close();
		fis.close();
	}
}

文件字节输入流:FileInputStream

构造方法

  • public FileInputStream(String name)throws FileNotFoundException

读数据

  • public abstract int read():一次读取一个字节
  • public int read(byte[] b) throws IOException:一次读取一个字节数组

使用步骤

  • 1)创建FileInputStream对象:指向哪个文件
  • 2)读数据 :public abstract int read():读取一个字节,展示结果
  • 3)关闭资源
public class FileInputStreamDemo {
	
	public static void main(String[] args) throws IOException {
		//创建FileInputStream对象
//		FileInputStream fis = new FileInputStream("fis.txt") ;
		FileInputStream fis = new FileInputStream("DiGuiTest.java") ;
		
		//public abstract int read():一次读取一个字节
		/*
		//第一次读
		int by = fis.read() ;
		System.out.println(by);//97--a
		System.out.println((char)by);
		
		//第二次读取
		by = fis.read() ;
		System.out.println(by);//98--b
		System.out.println((char)by);
		
		
		//第三次读取
		by = fis.read() ;
		System.out.println(by);
		System.out.println((char)by);
		
		//第四次读取
		by = fis.read();
		System.out.println(by);
		System.out.println((char) by);

		// 第五次读取
		by = fis.read();
		System.out.println(by);
		System.out.println((char) by);
		
		//第六次读取
		by = fis.read() ;
		System.out.println(by);//-1
		System.out.println((char)by);
		*/
		
		//上面代码:重复度很高,使用循环:while循环
		//结束条件:-1 :当前read():返回值为-1:流对象读取已经到达文件末尾
		/*
		int by = fis.read() ;
		while(by!=-1) {
			System.out.print((char)by);
			by = fis.read() ;
		}
		*/
		
		//最终版代码:上面优化
		//获取,赋值,判断可以写在一块
		//定义一个字节
		int by = 0 ;
		while((by=fis.read())!=-1) {
			//数据没有读取完毕
			System.out.print((char)by);  //强制转换:造成中文乱码:中文存储的问题
					//一个中文:gbk格式:一个中文两个字节,而且第一个字节是负数!
		}
		
		
		//关闭资源
		fis.close();
	}
}

public int read(byte[] b) throws IOException:一次读取一个字节数组
返回值:描述的是实际读取的字节数

public class FileInputStreamDemo2 {

	public static void main(String[] args) throws IOException {
		
		//创建一个字节文件输入流对象
//		FileInputStream fis = new FileInputStream("fis2.txt") ;
		FileInputStream fis = new FileInputStream("DiGuiTest.java") ;
		
		//读取数据
		//public int read(byte[] b)
		
		/*
		//定一个字节数组
		byte[] bytes = new byte[5] ;
		
		//第一次读取
		int len = fis.read(bytes) ;//返回实际读取的字节数
		System.out.println(len);
		System.out.println(new String(bytes));//将字节数组--String
		
		//第二次读取
		len = fis.read(bytes) ;
		System.out.println(len);
		System.out.println(new String(bytes));
		
		//第三次读取
		len = fis.read(bytes) ;
		System.out.println(len);
		System.out.println(new String(bytes));
		
		//四次读取
		len = fis.read(bytes) ;
		System.out.println(len);
		System.out.println(new String(bytes));
		
		//五次读取
		len = fis.read(bytes);
		System.out.println(len);
		System.out.println(new String(bytes));
		*/
		
		//一般情况:定义字节数组的时候:
		//一次读取一个字节数组的最终版代码
		//长度:是1024或者1024的整数倍
		byte[] bytes = new byte[1024] ;
		
		//赋值,判断
		//定义一个实际读取的字节数
		int len = 0 ;
		while((len=fis.read(bytes))!=-1) {
			//没有读完,继续读取
		//	System.out.println(new String(bytes));
			//public String(byte bytes[], int offset, int length)
			System.out.println(new String(bytes, 0, len)); 
			//每次从0开始,读取实际字节数		
		}
		//关闭资源
		fis.close();
	}
}

对应中文存储:第一个字节一定是负数,第二个字节可以是负数,整数…

 public class StringDemo {
	
	public static void main(String[] args) {
		
		//String s = "中国" ;  //平台:GBK格式:一个中文对应两个字节
		String s = "我爱你" ;
		//String s = "abc" ;
		//将它转换成字节数组
		byte[] bytes = s.getBytes() ;
		//System.out.println(bytes);
		
		//将数组---String:能到里面存储字节数 
		System.out.println( Arrays.toString(bytes)) ;
		//[-42, -48, -71, -6]
		//[-50, -46, -80, -82, -60, -29]
	}
}

BufferedInputStream

BufferedInputStream extends InputStream:字节缓冲输入流
构造方法

  • BufferedInputStream(InputStream in)
public class BufferedInputStreamDemo {
	
	public static void main(String[] args) throws IOException {
		
		//创建一个BufferedInputStream流对象
		BufferedInputStream bis = 
				new BufferedInputStream(new FileInputStream("bos.txt"))  ;
		/**
		 * class BufferedInputStream{
		 * 	  private static int DEFAULT_BUFFER_SIZE = 8192;
		 * 		
		 * public BufferedInputStream(InputStream in){
		 * 		this(in,DEFAULT_BUFFER_SIZE) ;
		 * }
		 * public BufferedInputStream(InputStream in, int size){
		 * 	..
		 * }
		 * }
		 */
				
		//一次读取一个字节
		/*
		int by = 0 ;
		while((by=bis.read())!=-1) {
			//展示在控制台上
			System.out.print((char)by);
		}
		*/
		//一次读取一个字节数组
		byte[] bytes = new byte[1024] ;
		int len = 0 ;
		while((len=bis.read(bytes))!=-1) {
			System.out.println(new String(bytes,0,len));
		}
		
		//释放资源
		bis.close();
		
	}
}

BufferedOutputStream

BufferedOutputStream extends OutputStream:字节缓冲输出流

  • 构造方法
  • public BufferedOutputStream(OutputStream out)
  • 创建一个缓冲输出流对象,默认缓冲区大小
  • 目前:当前缓冲流只是在流中提供了byte[] 缓冲区,默认足够大,一般通过带一个参的构造方法创建!
  • 只是提供缓冲区,具体文件读写复制操作还是需要用底层流(InputStream/OutputStream)
public class BufferedOutputStreamDemo {
	
	public static void main(String[] args) throws IOException {
		
		//public BufferedOutputStream(OutputStream out)
		BufferedOutputStream bos =
				new BufferedOutputStream(new FileOutputStream("bos.txt")) ;
		/**
		 *  this(out, 8192);  第二个参数:缓冲大小8192
		 */
		
		//写数据
		bos.write("hello,bufferedOutputStream!".getBytes());
		
		//释放资源
		bos.close();
	}
}

举例:

四种方式对文件进行读写复制操作

 *将当前项目下 BufferedInputStreamDemo.java文件复制到项目下的Copy.java文件中
 *	FileInputStream/FileOutputStream:一次读取一个字节  共耗时44毫秒
 *	FileInputStream/FileOutputStream:一次读取一个字节数组 
 *高效的字节流
 *	BufferedInputStrea/BufferedOutputStream:一次读取一个字节
 *	BufferedInputStrea/BufferedOutputStream:一次读取一个字节数组
 *复制视频文件
 */
public class CopyFile {
	
	public static void main(String[] args)  throws IOException{
		
		long start = System.currentTimeMillis() ;
		
//		method1("BufferedInputStreamDemo.java","Copy.java") ;
		method2("BufferedInputStreamDemo.java","Copy.java") ;
		
		
		long end = System.currentTimeMillis() ;
		
		System.out.println("共耗时"+(end-start)+"毫秒") ;
	}
	
//	FileInputStream/FileOutputStream:一次读取一个字节数组
	private static void method2(String srcFile, String destFile) throws IOException {
		//封装源文件和目的地文件
		FileInputStream fis = new FileInputStream(srcFile) ;
		FileOutputStream fos = new FileOutputStream(destFile) ;
		
		byte[] buf = new byte[1024] ;
		int len = 0 ;
		while((len=fis.read(buf))!=-1) {
			fos.write(buf, 0, len);
		}
		
		//释放资源
		fis.close();
		fos.close();
		
	}

	//FileInputStream/FileOutputStream:一次读取一个字节
	private static void method1(String srcFile, String destFile) throws IOException {
		//封装源文件和目的地文件
		FileInputStream fis = new FileInputStream(srcFile) ;
		FileOutputStream fos = new FileOutputStream(destFile) ;
		
		int by = 0 ;
		while((by=fis.read())!=-1) {
			fos.write(by);
		}
		
		//释放资源
		fis.close();
		fos.close();
		
	}
}

编码和解码

  • 编码:就将能够看懂的内容-----转换 “看不懂的内容”
  • String byte[]
  • 解码: 将看不懂的内容----------转换 “能看懂的内容”
  • byte[] String
  • 举例:
  • “今天老地方” ----- > 字节数组 :编码
  • 编码格式:
  • big-5:大五码 (繁写字体)
  • gbk:中国的中文编码表:一个中文对应两个字节
  • gbk-2312:中国的中文编码表:一个中文对应两个字节:对上面 的编码扩展
  • iso-8859-1:拉丁文码表
  • utf-8:一个中文对应三个字节码
  • JS:日本中的编码格式
  • utf-8/gbk
  • 编码和解码的过程必须保证格式统一:否则出现乱码!
 public class StringDemo {
	
	public static void main(String[] args) throws UnsupportedEncodingException {
		
		//创建一个字符串
		String s = "你好" ;
		//String---->Byte[]   getBytes():里面空参:平台默认编码集:gbk
		//getBytes("utf-8");编码格式:utf-8
		//byte[] bytes = s.getBytes() ;//默认gbk:一个中文对应两个字节

		byte[] bytes = s.getBytes("utf-8") ;
		//使用Arrays将数组---字符串
		System.out.println(Arrays.toString(bytes));
		//[-60, -29, -70, -61]
		//[-28, -67, -96, -27, -91, -67]:utf-8:一个中文对应三个字节数
		System.out.println("-----------------------------");
		
		//解码
		//byte[]---String :构造方法
//		String(byte[] bytes):默认平台字符集解码
		//String(byte[] bytes,Charset c):使用指定的字符集进行解码
		String str = new String(bytes) ; //默认gbk解码     浣犲ソ(编码utf-8)
		//String str = new String(bytes,"utf-8") ;//???乱码
		System.out.println(str);//你好
	}
}

OutputStreamWriter:字符输出流(字符流通向字节流的桥梁):转换流

构造方法

  • public OutputStreamWriter(OutputStream out):gbk格式 使用默认字符集进行编码的字符输出流
  • public OutputStreamWriter(OutputStream out, Charset cs)
  • 使用指定的字符集构造出一个字符输出流
  • 成员方法
  • public void write(int c):写入单个字符
  • public void write(char[] cbuf):写入字符数组
  • public abstract void write(char[] cbuf,int off,int len) 写入字符数组的一部分
  • public void write(String str):写入字符串内容
  • public void write(String str,int off,int len):写入字符串一部分
  • flush()和close()
  • 一个刷新流:将缓冲的数据刷新出来(中文:默认gbk格式:一个中文对两个字节),流刷新之后还可以
  • 继续写入数据;
  • close()方法:将跟该流相关的系统资源释放掉,
  • 不再指向当前操作的文件,关闭之后不能再写入数据否则出现IOException
 public class OutputStreamWriterDemo {
	
	public static void main(String[] args) throws IOException{
		
		//	public OutputStreamWriter(OutputStream out, Charset cs)
		/*
		OutputStreamWriter osw = new OutputStreamWriter
				(new FileOutputStream("osw.txt"), "utf-8") ;//编码格式:utf-8
		*/
		//public OutputStreamWriter(OutputStream out)
		OutputStreamWriter osw = new OutputStreamWriter
				(new FileOutputStream("osw.txt"));
		//写入数据
		//public void write(int c)
		//osw.write('a');
		//osw.write('b');
	
//		public void write(char[] cbuf):写入字符数组
		char[] chs = {'我','爱','高','圆','圆'};
//		osw.write(chs);
		//public abstract void write(char[] cbuf,int off,int len)
		//osw.write(chs, 1, 4);
//		public void write(String str)
		osw.write("今天老地方见");
	
		//关闭之前:先去刷新流
		osw.flush();
		
		//释放资源
		osw.close();
		
		//osw.write('c');// Stream closed:流已经关闭
	}
}

InputStreamReader:字符输入流 (字符流通向字节流的桥梁)字符转换输入流

构造方法:

  • public InputStreamReader(InputStream in):使用默认字符集进行解码(gbk格式)
  • public InputStreamReader(InputStream in, String charsetName)
  • 使用指定的字符集进行解码
  • 成员方法:
  • 读的功能
  • public int read():读单个字符
  • public int read(char[] cbuf):读字符数据
  • public int read(char[] cbuf,int offset,int len)读字符数组的一部分
public class InputStreamReaderDemo {
	
	public static void main(String[] args) throws IOException{
		
		//创建字符转换输入流对象
		/*InputStreamReader isr = new InputStreamReader(
				new FileInputStream("osw.txt"), "utf-8") ;*/
		
		InputStreamReader isr = new InputStreamReader(
				new FileInputStream("osw.txt")) ;//默认gbk格式
		
		//OutputStreamWriter:编码---gbk格式
		//InputStreamReader:解码---utf-8格式
		
		//将osw.txt文件内容展示在控制台上
		//一次读取一个字符
		//public int read():读单个字符
		/*
		int ch = 0 ; 
		while((ch=isr.read())!=-1) {
			//展示在控制台上
			System.out.print((char)ch);
		}
		*/
		//一次读取一个字符数组
		char[] chs = new char[1024] ;
		int len = 0 ;//实际字符数
		while((len=isr.read(chs))!=-1) {
			System.out.println(new String(chs,0,len));
		}
		
		//关闭资源
		isr.close();
		
		
	}
}

为了简化字符流读写复制操作:

  • 提供了字符转换输入流和字符转换输出流的便捷类
  • FileReader/FileWriter —继承InputStreamReader/OutputStreamWriter
  • FileReader(String pathname)
  • FileWriter(String pathname)
public class FileReader_andFileWriter_Demo {
	
	public static void main(String[] args) throws IOException {
		
		//封装源文件:OutputStreamWriterDemo.java
		FileReader fr = new FileReader("OutputStreamWriterDemo.java") ;
		//封装目的文件:当前项目下:Demo.javas
		FileWriter fw = new FileWriter("Demo.java") ;
		
		//一次读取一个字符数组
		char[] chs = new char[1024] ;
		int len = 0 ;
		while((len=fr.read(chs))!=-1) {
			//写
			fw.write(chs, 0, len);
			//刷新
			fw.flush();
		}
		
		//释放资源
		fw.close();
		fr.close();
	}
}

BufferedWriter:字符缓冲输出流

dWriter:字符缓冲输出流

  • 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
  • public BufferedWriter(Writer out):构造一个缓冲输出流,默认缓冲区大小
  • 成员方法
  • 特有功能
  • public void newLine():写入行的分隔符(换行)
public class BufferedWriterDemo {

	public static void main(String[] args) throws IOException {
		
		//创建一个缓冲输出流对象
		BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
		/**
		 * private static int defaultCharBufferSize = 8192;
		 *  public BufferedWriter(Writer out) {
        			this(out, defaultCharBufferSize);
    		}
		 */
		//写数据:
		bw.write("hello");
		//bw.write("\r\n");
		//特有功能
		bw.newLine();
		bw.write("world");
		bw.newLine();
		bw.write("Java");
		bw.newLine();
		
		//刷新
		bw.flush();
		
		//关闭资源
		bw.close();
	}
}

BufferedReader:字符缓冲输入流

构造方法

  • BufferedReader(Reader r):构造一个字符缓冲输入流提供默认缓冲区大小
  • 特有功能:
  • public String readLine():一次读取一行内容,当读取到\n(换行了),就终止!
    *Scanner(InputStream in)
    *BufferedReader(Reader r):可以作为键盘录入(使用流的方式)
public class BufferedReaderDemo {
	
	public static void main(String[] args) throws IOException {
		
		//创建字符缓冲输入流对象
//		BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
		BufferedReader br = new BufferedReader(new FileReader("OutputStreamWriterDemo.java")) ;
		
		/**
		 * private static int defaultCharBufferSize = 8192;
		 *   public BufferedReader(Reader in) {
        		this(in, defaultCharBufferSize);
    		}
		 */
		
		//public String readLine():
		/*
		//第一次读取
		String line = br.readLine() ;
		System.out.println(line);
		
		//第二次读取
		line  = br.readLine() ;
		System.out.println(line);
		
		//第三次读取
		line = br.readLine() ;
		System.out.println(line);
		
		//第四次读取
		line =br.readLine() ;
		System.out.println(line); //返回null:文件读取完毕了
		*/
		//优化:while循环
		String line = null ;
		while((line=br.readLine())!=null) {
			//没有读完毕
			System.out.println(line);
		}
		
		//释放资源
		br.close();
		
	}
}

键盘录入

  • 1)Scanner(InputStream in)
  • 2)BufferedReader(Reader r):可以作为键盘录入(使用流的方式)
public class Demo {
	
	public static void main(String[] args) throws IOException {
		
		/*
		Scanner sc = new Scanner(System.in) ;
		
		System.out.println("请您输入String数据:");
		String str = sc.nextLine() ;
		System.out.println(str);
		*/
		
		//使用BufferedReader(Reader r):可以作为键盘录入
		/*
		//分步走
		InputStream in = System.in ;
		
		//创建Reader流对象
		Reader r = new InputStreamReader(in) ; //字符转换流:通向字节流的桥梁
		
		//创建BufferedReader流对象
		BufferedReader br = new BufferedReader(r) ;
		*/
		
		//一步走
		BufferedReader br = new BufferedReader(
				new InputStreamReader(System.in)) ;
		
		System.out.println("请您输入一个数据:"); //"100" 数字字符串
		//利用BufferedReader:的readLine()读取一行数据
		String line = br.readLine() ; 	//"100"
		//String---int: Integer.parseInt(String str)
		int num = Integer.parseInt(line) ;
		System.out.println("您录入的字符串是:"+num);
		
		
	}
}

使用BufferedReader/BufferedWriter:读写复制操作:文本文件复制

利用特有功能(一种新的方式)

  • 项目下的Demo.java—复制到D盘下:a.java文件中
  • 使用BufferedReader:字符缓冲输入流的readLine():一次读取一行
  • 使用BufferedWriter:newLine()可以实现换行
  • 总结针对文本文件的复制操作:
  • InputStreamReader/OutputStreamWriter:一次读取一个字符
  • InputStreamReader/OutputStreamWriter:一次读取一个字符数组
  • (同上)
  • FileReader/FileWriter一次读取一个字符
  • FileReader/FileWriter一次读取一个字符数组
  • BufferdReader/BufferedWriter:一次读取一个字符
  • BufferdReader/BufferedWriter:一次读取一个字符数组
  • BufferedReader/BufferedWriter:一次读取一行
public class Test {
	public static void main(String[] args) throws IOException {
		
		//封装源文件
		BufferedReader br = new BufferedReader(new FileReader("Demo.java")) ;
		//封装目标文件
		BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\a.java")) ;
		
		
		//读写
		String line = null ;
		while((line=br.readLine())!=null) {
			//读一行,bw写一行
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		
		//释放资源
		bw.close();
		br.close();
	}

}

PrintWriter:字符打印流 PrintStream:字节打印流

能够操作直接操作文件地址:String pathname的流有哪些?

  • 最基本的字节流
  • FileInputStream
  • FileOutputStream
  • FileReader
  • FileWriter
  • PrintWriter:能够操作文件(目标文件) – 字符输出流一种
  • 构造方法:
  • public PrintWriter(Writer out,boolean autoFlush):
  • 第二个参数为true:表示开启自动刷新功能
  • public PrintWriter(String fileName):可以操作具体文件路径
  • 成员方法:
  • public void println(XXX x):可以换行
public class PrintWriterDemo {
	
	public static void main(String[] args) throws IOException {
		//创建字符打印流对象
		PrintWriter pw = new PrintWriter("pw.txt") ;
		
		//打印数据并可以换行
		pw.println("hello");
		pw.println("world");
		pw.println("java");
		
		//刷新
		pw.flush();
		//关闭资源
		pw.close();
	}
}

文本文件的复制----优先采用BufferedReader/BufferedWriter

  • 图片文件/音频文件/视频文件----采用BufferdInputStrea/BufferedOutputStream
  • 文本文件的复制
  • 当前项目下:BufferedInputStreamDemo.java
  • 复制当前项目下:Test.java
  • 封装源文件:BufferedReader
  • 封装目标文件:PrintWriter
public class CopyFile {

	public static void main(String[] args) throws IOException {
		//封装源文件
		BufferedReader br = new BufferedReader
				(new FileReader("BufferedInputStreamDemo.java")) ;
		
		//封装目的地文件
		//public PrintWriter(Writer out, boolean autoFlush) 
		PrintWriter pw = new PrintWriter(new FileWriter("Test.java"),
				true) ;//启动自动刷新
		
		//复制
		String line = null ;
		while((line=br.readLine())!=null) {
			//打印数据
			pw.println(line);
		}
		
		//释放资源
		pw.close();
		br.close();
		
		
	}
}

内存操作流:操作临时数据

ByteArrayOutputStream:内存操作输出流

  • 构造方法:
  • public ByteArrayOutputStream(){}:构造一个默认的缓冲大小的输出流对象
  • 成员方法
  • public byte[] toByteArray():将内存操作输出流中流对象—数组格式
  • ByteArrayInputStream:内存操作输入流
  • 构造方法:
  • public ByteArrayInputStream(byte[] buf):使用指定的字节数组作为缓冲区,构造
  • 内存操作输入流
public class ByteArrayStreamDemo {
	
	private static
		ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
	
	public static void main(String[] args) throws IOException {
		write(baos) ;
		
		read() ;
	}
	
	//将内存操作流
	private static void read() throws IOException {
		//public ByteArrayInputStream(byte[] buf)
		//public byte[] toByteArray()
		byte[] bytes = baos.toByteArray() ;
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes) ;
		//读取数据
		//一次读取一个字节/一个字节数组
		int by = 0 ;
		while((by=bais.read())!=-1) {
			//展示
			System.out.print((char)by);
		}
		
		/**
		 *  public void close() throws IOException {
    		}
		 *    */
   
		//bais.close();
		
	}

	//创建内存操作输出流,写入临时数据
	private static void write(ByteArrayOutputStream baos) throws IOException {	
		
		//创建ByteArrayOutputStream
		
		
		//写入数据
		for(int x = 0 ; x < 10 ;  x ++) {
			baos.write(("hello"+x).getBytes());
			//字节流换行
			//写入\r\n
			baos.write("\r\n".getBytes());
		}
		//System.out.println(baos);
		
		//关闭资源
//		baos.close();临时变量---随着方法完毕就消失了
		/**	
		 * close没有作任何实现
		 * public void close() throws IOException {
    		}
		 */
	}
}

SequenceInputStream

SequenceInputStream extends InputStream:字节输入流

  • 合并流:将两个或者两个以上的流对象合并到一个流中
    *构造方法
    *将两个基本输入流合并到当前SequenceInputStream流中
  • public SequenceInputStream(InputStream s1,InputStream s2)
public class SequenceStramDemo {
	
	public static void main(String[] args)  throws IOException{
		InputStream s1 = new FileInputStream("Demo.java") ;
		InputStream s2 = new FileInputStream("OutputStreamWriterDemo.java") ;
		
		//创建合并流对象
		SequenceInputStream sis = new SequenceInputStream(s1, s2) ;
		
		//封装目标文件
		FileOutputStream fos = new FileOutputStream("Copy.java") ;
		
		//读写复制
//		一次读取一个字节数组
		byte[] bytes = new byte[1024] ;
		int len = 0 ;
		while((len=sis.read(bytes))!=-1) {
			fos.write(bytes,0,len);
		}
		//关闭资源
		fos.close();
		sis.close();
		
	}
}

public SequenceInputStream(Enumeration<? extends InputStream> e)

两个以上的文件复制

  • 1)创建 Vector集合对象
  • 2)给添加多个InputStream对象
  • 3)Vector集合中:elements()---->Enumeration
  • 4)读写复制
  • 需求:
  • 将OutputStreamWriterDemo.java/Test.java/CopyFile.java
  • 三个文件复制到D:\CopyFileDemo.java
public class SequenceStreamDemo2 {
	
	public static void main(String[] args) throws IOException{
		
		//public SequenceInputStream(Enumeration<? extends InputStream> e)
		//创建Vector集合对象
		Vector<InputStream> v = new Vector<InputStream>() ;
		//创建三个InputStream对象
		InputStream s1 = new FileInputStream("OutputStreamWriterDemo.java") ;
		InputStream s2 = new FileInputStream("Test.java") ;
		InputStream s3 = new FileInputStream("Copy.java") ;
		//添加到集合中
		v.add(s1) ;
		v.add(s2) ;
		v.add(s3) ;
		
		//获取类似于迭代器elements()-----iterator()
		Enumeration<InputStream> en = v.elements() ;
		//创建合并流对象
		SequenceInputStream sis = new SequenceInputStream(en) ;
		
		//封装目标文件
		FileOutputStream fos = new FileOutputStream("d:\\CopyFileDemo.java") ;
		
		//一次读取一个字节数组
		byte[] bytes  = new byte[1024] ;
		int len = 0 ;
		while((len=sis.read(bytes))!=-1){
			//写
			fos.write(bytes, 0, len);
		}		
		//关闭
		fos.close();
		sis.close();
		
	}
}

ObjectOutputStream

public ObjectOutputStream(OutputStream out)

  • 序列化:需要将网络中的数据/一些对象转成 “流数据”
  • 成员方法:
  • public final void writeObject(Object obj):将指定的对象写入到序列化流中
  • ObjectInputStream
  • public ObjectInputStream(InputStream in)
  • 反序列化:将流数据----还原成Java对象/网络数据
  • public final Object readObject():将流数据—还原成对象
public class ObjectStreamDemo {
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		
		//序列化
//		write() ;
		
		//反序列化
		read() ;
	}
	
	//将流数据---还原成对象
	private static void read() throws IOException, ClassNotFoundException {
		//public ObjectInputStream(InputStream in)
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt")) ;
		//* public final Object readObject()
		Object obj	 = ois.readObject() ;
		System.out.println(obj);
		
		//关闭
		ois.close();
	}

	private static void write() throws IOException, IOException {
		//public ObjectOutputStream(OutputStream out)
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt")) ;
		
		
		//写数据
		Person p = new Person("张钰",23) ;
		//public final void writeObject(Object obj)
		oos.writeObject(p);
		
		//释放资源
		oos.close();
	}
}

Properties 类表示了一个持久的属性集 ,没有泛型(属性列表中的键和值都是String)
它继承自Hashtable<K,V> implements Map<K,V>
Map集合的遍历:

  • 通用的方式
  • keySet()---->Set
  • get(K key)---->V value
public class PropertiesDemo {
	
	public static void main(String[] args) {
		
		//Properties属性集合类中的基本遍历功能
		//创建属性集合类对象
		Properties prop = new Properties() ;
		
		//添加数据
		prop.put("it001", "马云") ;
		prop.put("it002", "刘强东") ;
		prop.put("it003", "罗永浩") ;
		prop.put("it004", "张冲") ;
		prop.put("it001", "张冲2") ;
		
		//遍历
		Set<Object> set = prop.keySet() ;
		for(Object obj :set) {
			//在通过键获取值
			Object value = prop.get(obj) ;
			System.out.println(obj+"---"+value);
		}
	}
}

Properites属性集合类的特有功能

  • public Object setProperty(String key, String value):添加键和值
  • public Set stringPropertyNames():获取属性列表中的所有的键的集合
  • public String getProperty(String key):通过键获取值
public class PropertiesDemo2 {

	public static void main(String[] args) {
		
		//创建属性集合类对象
		Properties 
		prop = new Properties() ;
		
		//* public Object setProperty(String key, String value):添加键和值
		prop.setProperty("杨玉环", "27") ;
		prop.setProperty("西施", "25") ;
		prop.setProperty("王昭君", "22") ;
		prop.setProperty("貂蝉", "20") ;
		System.out.println(prop);
		
		//获取所有的键的集合
		//public Set<String> stringPropertyNames()
		Set<String> set = prop.stringPropertyNames() ;
		for(String key:set) {
			//public String getProperty(String key)
			Object value = prop.get(key) ;
			System.out.println(key+"---"+value);
		}
		
	}
}

public void load(Reader reader):将一些配置文件中的数据加载到属性集合类中

  • public void store(Writer writer, String comments)
  • 将属性集合类中数据保存到指定的文件中
    *需求:
  • 在当前项目下user.txt文件 ,如果当前文件中lisi这个键,将它的值改为78,然后重新将值写入到user.txt文件(既要用到load(Reader r),
  • 还要用到store(Writer w,String comments))
public class PropertiesTest {
	
	public static void main(String[] args) throws IOException {
	//	myStore() ;
	
		myLoad() ;
	}
	
	//将某个文件中的内容加载到属性集合列表中
	private static void myLoad() throws IOException {
		//创建属性集合类对象
		Properties prop = new Properties() ;
		Reader r = new FileReader("user.txt") ;
		prop.load(r);
		
		//关闭资源
		r.close();
		System.out.println(prop);
	}

	//需要将属性列表中的数据保存到某个文件:当前项目下的name.txt中
	private static void myStore() throws IOException {
		//创建属性集合类对象
		Properties prop = new Properties() ;
		//添加数据
		prop.setProperty("张三", "30") ;
		prop.setProperty("李四", "40") ;
		prop.setProperty("王五", "50") ;
		
		//public void store(Writer writer, String comments)
		prop.store(new FileWriter("names.txt"), "name's list");
		
		System.out.println(prop);
		
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值