十一、IO流

十一、IO流
        


    1)文件的读写(字符流) 适用于 txt doc wps
    ①.FileWriter文件写
    ②.FileReader文件读
    ③.BufferedWriter+FileWriter 缓冲区的出现提高了对流的操作效率。原理:其实就是将数组进行封装(StringBuilder缓存)。
    ④.BufferedReader+FileReader 缓冲区的出现提高了对流的操作效率。原理:其实就是将数组进行封装(StringBuilder缓存)。

    2)文件的读写(字节流) 适用于 图片、声音、影像等文件。 
            ①.FileInputStream文件的读
            ②.FileOutputStream文件的写

    3)文件的读写(转换流)
            ①.InputStreamReader 用于文件字节与缓存字符的更好转换 文件读 
            ②.OutputStreamWriter 用于文件字节与缓存字符的更好转换 文件写

    FileUtils工具类:
package net.itaem.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import javax.servlet.http.HttpServletRequest;

/**
 * 
 * @Description:文件操作工具类 
 * 						       文件的增删
 * 						   1.文件以及文件目录的级联创建
 * 						   2.文件目录的级联创建
 * 						   3.文件的删除(限制,有子文件则删除失败)
 * 						   4.文件的级联删除(级联,把子文件一起删除) 
 * 						       
 * 						       文件的读写(字符流)  适用于 txt doc wps
 * 						   1.FileWriter文件写
 * 						   2.FileReader文件读
 * 						   3.BufferedWriter+FileWriter文件写
 * 						   4.BufferedReader+FileReader文件读
 * 
 * 						       文件的读写(字节流)   适用于 图片、声音、影像等文件。
 * 						   1.FileInputStream文件的读
 * 						   2.FileOutputStream文件的写
 * 							
 * 						       文件的读写(转换流)
 * 						   1.InputStreamReader文件读
 * 						   2.OutputStreamWriter文件写
 * 
 * 						       工具方法
 * 						   1.文件的复制 (使用BufferedInputStream与BufferedOutputStream)
 * 						   2.键盘内容读取(使用InputStreamReader)
 * 						   3.检查正确文件路径
 * 						   4.判断正确的文件编码(已在FileEncodes设置的编码)
 * 						   5.获取程序当前路径
 * 						   6.显示文件剩余的大小
 * @operate:
 * @author sen
 * @date 2014-3-12
 */
public class FileUtils {
	
	/**
	 * 实现具有防御型单例
	 */
	private static final FileUtils fileUtils = new FileUtils() ;
		
	/**
	 * 私有构造函数防止多次实例化
	 */
	private FileUtils(){
		if(fileUtils==null){
			
		}else{
			//被反射攻击了
			throw new RuntimeException("FileUtils被反射攻击了") ;
		}
	}
	
	/**
	 * 设置文件可设置的编码类型
	 */
	private static final String[] fileEncodes = 
		{"UTF-8","GBK","GB2312","ISO-8859-1","ASCII","Unicode"} ;
	
	

	/**
	 * @description 创建文件
	 * @param filePath
	 *            文件路径
	 * @return 创建成功为ture 创建失败为false
	 * @author sen
	 */
	public static boolean createFile(String filePath) throws IOException {
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}

		File file = new File(filePath);

		// 判断文件是否存在
		if (!file.exists()) {
			String dirPath = file.getParent(); // 获取文件的上一级
			File fileDir = new File(dirPath);
			if (!fileDir.exists()) { // 目录不存在的情况下
				fileDir.mkdirs();// 创建目录列表。
			}
			return file.createNewFile();// 创建文件
		}
		return false;
	}

	/**
	 * @description 创建文件夹
	 * @param fileFolderPath
	 *            文件夹路径
	 * @return 创建成功为true 创建失败为false
	 * @author sen
	 */
	public static boolean createFileFolder(String fileFolderPath) {
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(fileFolderPath)) {
			return false;
		}

		File file = new File(fileFolderPath);

		// 判断文件夹是否存在
		if (!file.exists()) { // 目录不存在的情况下
			return file.mkdirs(); // 创建目录列表。
		}
		return false;
	}

	/**
	 * @description 删除文件 注意:只能删除1级文件,不能实现级联删除
	 * @param filePath
	 * @return 删除成功为true 删除失败为false
	 * @author sen
	 */
	public static boolean deleteFileRestrict(String filePath) {
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}
		
		File file = new File(filePath);
		if(file.exists()){  //如果文件存在
			return file.delete();  //删除文件
		}
		return false;
	}

	/**
	 * 
	 * @description 删除文件目录 能够级联删除
	 * @param fileDirectoryPath
	 * @return 删除成功为true
	 * 		        删除失败为false
	 * @author sen
	 */
	public static boolean deleteFileCascade(String filePath) {
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return false ;
		}
		
		// 删除目录或文件,如果目录不为空返回false
		if (file.delete()) {

		} else {
			//取出文件目录的子文件或文件夹
			File[] fileChilds = file.listFiles();
			for(File f :fileChilds){
				//递归调用
				deleteFileCascade(f.getAbsolutePath()) ;
			}
			//删除父类文件夹
			file.delete() ;
		}
		return true ;
	}
	
	/**
	 * FileWriter,FileReader特点:   
	 *  1.用于处理文本文件;
	 *  2.该类中有默认的编码表; 
	 *  3.该类中有临时缓冲。
	 */
	/**
	 * @description 使用FileWriter进行文件的写      专门适用于纯文本  txt doc wps
	 * @throws IOException 
	 * @param  1.pattern标志位,选择写的模式
	 * 			 pattern=true代表文件往后追加,pattern=false代表文件覆写
	 * 		   2.filePath文件路径 
	 * 		   3.content文件内容
	 * @return 写入成功为true
	 * 		       写入失败为false
	 * 
	 * @author sen
	 */
	public static boolean writerFileByFileWriter(String filePath,String content,boolean pattern) throws IOException{
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return false ;
		}
		//实例化FileWriter
		FileWriter fileWriter = new FileWriter(file,pattern) ;
		//把内容写入文件
		fileWriter.write(content) ;
		//刷新文件内容
		fileWriter.flush() ;
		//关闭流通道
		fileWriter.close() ;
		return true ;
	}
	
	
	/**
	 * @description 使用FileReader进行文件的读      专门适用于纯文本  txt doc wps
	 * @param 1.filePath文件路径
	 * 		  2.pattern文件模式 
	 * 			 pattern=true代表  小文本上传
	 * 			 pattern=false代表   大文件上传
	 * @return 如果文件路径错误或者文件不存在 返回null
	 * 		        成功,则返回文件内容
	 * @author sen
	 * @throws IOException
	 */
	public static String readerFileByFileReader(String filePath) throws IOException{
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return null ;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return null ;
		}
		
		//内容存储
		StringBuilder builder = new StringBuilder() ;
		
		//实例化fileReader
		FileReader fileReader = new FileReader(filePath) ;
		//设定文件内容结束标志位
		int ch = 0 ;
		
		/*if(!pattern){
			
			 * 一次读取一个字符
			 * 缺点:由于次读取一个字符,而每个字符需要int转char转型
			 * 	大文件比耗费大量的执行时间和资源
			 
			while((ch=fileReader.read())!=-1){
				builder.append((char)ch);
			}
		}else{*/
			/*
			 * 一次读取多个字符(默认1024个)
			 * 优点:免去了转型消耗,以及减少了存储次数,提高了性能和效率
			 * 缺点:需要创建1024个char字符数组(1KB,1个英文字符1B,1个中文汉字字符2B),浪费了资源
			 */
			//缓存字符数组
			char[] charArray = new char[1024] ;  //1024B=1KB
			//读满或者读完则存放到bulider里面
			while((ch=fileReader.read(charArray))!=-1){
				builder.append(charArray, 0, ch) ;
			}
		//}
		//一次读取多个字符
		
		fileReader.close() ;
		return builder.toString() ;
	}

	/**
	 * BufferedWriter,BufferedReader特点:   比FileWriter更快   
	 *  缓冲区的出现提高了对流的操作效率。
	 *  原理:其实就是将数组进行封装(StringBuilder缓存)。
	 *  
	 *  1.在使用缓冲区对象时,要明确,缓冲的存在是为了增强流的功能而存, 
	 *       所以在建立缓冲区对象时,要先有流对象存在。 
	 *  2.其实缓冲内部就是在使用流对象的方法,
	 *       只不过加入了数组对数据进行了临时存储。
	 *  提高操作数据的效率。
	 *  
	 */
	
	/**
	 * @description 使用BufferedWriter进行文件的写      专门适用于纯文本  txt doc wps
	 * @throws IOException 
	 * @param  1.pattern标志位,选择写的模式
	 * 			 pattern=true代表文件往后追加,pattern=false代表文件覆写
	 * 		   2.filePath文件路径 
	 * 		   3.content文件内容
	 * @return 写入成功为true
	 * 		       写入失败为false
	 * 
	 * @author sen
	 */
	public static boolean writerFileByBufferedWriter(String filePath,String content,boolean pattern) throws IOException{
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return false ;
		}
		
		//实例化bufferedWriter(缓冲区对象)
		//	特有方法newLine() 跨平台换行符
		BufferedWriter bufferWriter = new BufferedWriter(new FileWriter(file,pattern)) ;
		//写入内容
		bufferWriter.write(content) ;
		//刷新文件内容
		bufferWriter.flush() ;
		//关闭通道
		bufferWriter.close() ;
		return true ;
	}
	
	/**
	 * @description 使用BufferedReader进行文件的写      专门适用于纯文本  txt doc wps
	 * @throws IOException 
	 * @param  1.pattern标志位,选择写的模式
	 * 			 pattern=true代表文件往后追加,pattern=false代表文件覆写
	 * 		   2.filePath文件路径 
	 * 		   3.content文件内容
	 * @return 写入成功为true
	 * 		       写入失败为false
	 * 
	 * @author sen
	 */
	public static String readerFileByBufferedReader(String filePath) throws IOException{
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return null;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {   
			return null ;
		}
		
		//内容存储
		StringBuilder builder = new StringBuilder() ;
		
		//读取缓冲区对象
		/*	特有方法 readLine() 一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。
		 *	原理:readerLine()实质也是调用read()方法,不过在read()(一次读取一个字符)上进行封装,
		 *		只有读取到换行符或者文件结束的时候才进行统一的返回,功能与read(Array)数组类似。
		 *	注意:按照行的形式取出数据,取出的每一行数据不包含回车符
		 */
		BufferedReader bufferReader = new BufferedReader(new FileReader(filePath)) ;
		//缓冲字符串
		String line = null ;
		
		//注意:按照行的形式取出数据,取出的每一行数据不包含回车符
		while((line=bufferReader.readLine())!=null){
			builder.append(line);
			builder.append("\r\n") ;    //手动添加换行符
		}
		//关闭缓冲区对象(内置关闭流对象)
		bufferReader.close() ;
		//内容返回
		return builder.toString() ;
	}
	
	
	
	/**
     * @description 使用FileInputStream进行文件的读。  用于读二进制文件,如图片、声音、影像等文件。
     * 				注意:本方法仅用于 小于1KB 的文件,故该方法仅用于学习使用
     * @param filePath文件路径
     * 
     * @return 成功byte[]
     * 		       失败null
	 * @throws IOException
	 * 
	 * @author sen
     */
    public static byte[] inputFileByFileInputStream(String filePath) throws IOException {
    	
    	// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return null;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return null;
		}
		//实例化FileInputStream
        FileInputStream fileInputStream = new FileInputStream(file);
        
        //获取文件大小
        int lenght = fileInputStream.available() ;
        //判断文件大小 大于1K
        /*if(lenght>1024){
        	return null ;
        }*/
        
    	//以字节为单位读取文件内容,一次读全部内容  默认为文件总大小
        //如果文件体积不是很大。  
      	//可以这样操作byte[] buf = new byte[fileInputStream.available()]。     
      	//但是这有一个弊端,就是文件过大,大小超出jvm的内容空间时,会内存溢出。
        
    	//缺点:注意缓存可能会爆掉
    	byte[] bytesRead = new byte[lenght];
    	//读入多个字节到字节数组中,byteread为一次读入的字节数
    	fileInputStream.read(bytesRead) ;
    	
        fileInputStream.close() ;
        return bytesRead;
    }

    /**
     * @description 使用FileOutputStream进行文件的读。  用于读二进制文件,如图片、声音、影像等文件。
     * 
     * @param String filePath文件路径
     * 		  byte[] content文件内容
     * @return 成功true
     * 		       失败false
	 * @throws IOException
	 * 
	 * @author sen
     */
    public static boolean outputFileByFileOutputStream(String filePath,byte[] content) throws IOException{
    	// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return false;
		}
		
		//实例化FileOutputStream文件流对象
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		//直接将数据写入到了目的地。
		fileOutputStream.write(content);
		//只关闭资源。
		fileOutputStream.close();
		
		return true ;
    }
	
    /**
     * @description 使用BufferedInputStream与BufferedOutputStream进行文件的复制
     * 
     * @param sourceFilePath源文件路径
     * 		  destinFilePath目标文件路径
     * 		  pattern模式  ①pattern=true大文件复制
     * 					 ②pattern=false小文件复制
     * @return 成功true
     * 		       失败false
	 * @throws IOException
	 * 
	 * @author sen
     */
    public static boolean copyFileByBufferedInputOutputStream(String sourceFilePath,
    		String destinFilePath,boolean pattern) throws IOException{
    	// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(sourceFilePath)
				||!FileUtils.checkFile(destinFilePath)) {
			return false;
		}
		
		//创建源文件
		File sourceFile = new File(sourceFilePath);
		//创建目标文件
		File destinFile = new File(destinFilePath) ;

		// 判断源文件或目录是否存在
		if (!sourceFile.exists()) {
			return false;
		}
		// 如果没有目标文件目录   则 创建
		// 获取目录
		File destinParentFile = destinFile.getParentFile() ;
		if(!destinParentFile.exists()){
			//创建目录
			destinParentFile.mkdirs() ;
		}
		
		//创建源文件输入流对象
    	BufferedInputStream bufis = new BufferedInputStream(new FileInputStream(sourceFilePath));
    	//创建目标文件输出流对象
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream(destinFilePath));
        
        //缓存对象
        int byteRead = 0;
        
        if(!pattern){
        	//一次读取一个字节
	        while((byteRead=bufis.read())!=-1){  
	        	bufos.write(byteRead);  
	        }
        }else{
        	//一次读取多个字节(1024个字节数=1024B)
        	byte[] tempBytes = new byte[1024] ;
        	while((byteRead=bufis.read(tempBytes))!=-1){  
	        	bufos.write(tempBytes, 0, byteRead) ;
	        }
        }
        //关闭输出流
        bufos.close();
        //关闭输入流
        bufis.close();
        
        return true ;
    }
    
    /**
     * InputStreamReader和OutStreamWriter的使用
     * 
     * 用处:1.用于文件字节与缓存字符的更好转换
     *     2.添加编码
     */
    
    /**
     * 
     * @description 使用InputStreamReader进行文件读   用于编码读取
     * @param 1.filePath文件路径
     *        2.encode文件编码
     * @return 成功true
     * 		       失败false
     * @throws IOException
     */
    public static String readerFileByBufferedReaderEncode(String filePath,String encode) throws IOException{
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return null ;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return null ;
		}
		
		//存储数据
		StringBuilder builder = new StringBuilder() ;
		
		//读取缓冲区对象
		BufferedReader bufferReader = new BufferedReader(
										new InputStreamReader(
											new FileInputStream(file),encode)) ;
		
		//缓冲字符串
		String line = null ;
		
		//注意:按照行的形式取出数据,取出的每一行数据不包含回车符
		while((line=bufferReader.readLine())!=null){
			builder.append(line);
			builder.append("\r\n") ;    //手动添加换行符
		}
		//关闭缓冲区对象(内置关闭流对象)
		bufferReader.close() ;
		
		//内容返回
		return builder.toString() ;
	}
    /**
     * 
     * @description 使用OutputStreamWriter进行文件写   用于编码存储
     * @param 1.filePath文件路径
     *        2.content文件内容
     *        3.pattern模式 pattern=true文件往后添加内容
     *        		      pattern=false文件覆写
     *        4.encode文件编码
     * @return 成功true
     * 		       失败false
     * @throws IOException
     */
    public static boolean writerFileByBufferedWriterEncode(String filePath,String content,
    		boolean pattern,String encode) throws IOException{
		// 判断是否是正确的文件路径
		if (!FileUtils.checkFile(filePath)) {
			return false;
		}
		
		File file = new File(filePath);

		// 判断文件或目录是否存在
		if (!file.exists()) {
			return false ;
		}
		
		//读取缓冲区对象
		BufferedWriter bufferWriter = new BufferedWriter(
										new OutputStreamWriter(
											new FileOutputStream(file,pattern),encode)) ;
		
		//写入内容
		bufferWriter.write(content) ;
		//刷新文件内容
		bufferWriter.flush() ;
		//关闭通道
		bufferWriter.close() ;
		
		return true ;
	}
    
    /**
     *
     * @description 键盘录入
     * @return 键盘输入的内容
     * @throws IOException 
     * 
     * @author sen
     */
    public static String readerSystemInByInputStreamReader() throws IOException{
    	
    	System.out.println("请输入信息,退出输入exit:");
    	//存储内容
    	StringBuilder builder = new StringBuilder() ;
    	//缓冲区对象
		BufferedReader bufferReader = new BufferedReader(new InputStreamReader(System.in)); 
		//缓冲字符串
		String line = null ;
		//注意:按照行的形式取出数据,取出的每一行数据不包含回车符
		while(!"exit".equals(line=bufferReader.readLine())){
			builder.append(line);
			builder.append("\r\n") ;    //手动添加换行符
		}
		//关闭缓冲区对象(内置关闭流对象)
		bufferReader.close() ;
		//内容返回
		return builder.toString() ;
    }
	
    
    
    
    
    
    

	/**
	 * 
	 * @description 检验文件路径是否正确
	 * @param filePath文件路径
	 * @return 正确文件路径true 不是文件路径false
	 * @author sen
	 */
	public static boolean checkFile(String filePath) {

		// 替换掉双斜杠
		// 把双斜杠\\替换为/
		if (filePath.contains("\\")) {
			filePath = filePath.replace("\\", File.separator);
		}

		/*
		 *  判断路径是否正确
		 *  只能检测 / 或 \(File.separator)文件分隔符
		 *  正则解析:
		 *  	1.[a-z|A-Z]:代表盘符  例如c:
		 *  	2.([\\\\|/]\\w+){0,} 代表0个或多个文件目录 例如/aaa/bbb 或 \aaa\bbb
		 *  	3.[\\\\|/]\\w*(.\\w*|) 代表文件名 例如/test.txt 或\test(小w代表字母或数字。大W代表非字母或数字)
		 */
		if (!filePath
				.matches("^[a-z|A-Z]:([\\\\|/]\\w+){0,}[\\\\|/]\\w*(.\\w*|)$")) {
			System.out.println("文件路径不正确!路径:"+filePath);
			return false;
		}
		return true;
	}
	
	
	/**
	 * 
	 * @description 判断是否是正确的编码值
	 * @param 在fileEncodes设置的编码值
	 * @return 成功true
	 * 		       失败false
	 * 
	 * @author sen
	 */
	public static boolean checkEncode(String encode){
		//替换掉对应的空字符
		encode = encode.replace(" ", "") ;
		
		//与fileEncodes设置的编码进行匹配
		for(String tempEncode:FileUtils.fileEncodes){
			//忽略大小进行匹配
			if(tempEncode.equalsIgnoreCase(encode)){
				return true ;
			}
		}
		return false ;
	}
	

	/**
	 * @description 获取程序当前路径
	 * @param request!=null(web路径)
	 * 		  request==null
	 * @return 程序路径
	 * @author sen
	 */
	public static String getProjectPath(HttpServletRequest request) {

		if(request!=null){
			return request.getSession().getServletContext().getRealPath("/") ; 
		}
		
		// 获取程序路径
		return System.getProperty("user.dir").replace("\\", File.separator)+File.separator;// user.dir指定了程序当前路径
	}
	
	/**
     * @description 显示输入流中还剩的字节数
	 * @throws IOException 
     * @author sen
     */
    @SuppressWarnings("unused")
	private static void showAvailableBytes(InputStream inputStream) throws IOException {
        System.out.println("当前字节输入流中的字节数为:" + inputStream.available());
    }

}<span style="font-family:微软雅黑;"><span style="font-size: 14px; line-height: 21px;">
</span></span>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值