文件操作

/**
 * 注意事项
 * 
 * 1.通过该文件操作类读取指定文件内容时,由于是按默认编码UTF-8格式读取,若读取的文件编码格式不同,会有乱码问题
 * 2.通过本类方法创建的文件,并进行写-读操作,不会造成内容乱码
 *
 * @param <T>
 */
public class FileOperate<T> {
	
	private String charsetName = "UTF-8";
	
	private final int CACHE_LENGTH = 1024;
	
	private FileFilter filter;
	
	public void setCharsetName(String charsetName) {
		this.charsetName = charsetName;
	}

	/**
	 * 加载指定文件类型
	 * @param suffixs	格式:[".txt",".png",".jpg"]
	 */
	public void setFilter(final String[] suffixs) {
		FileFilter filter = new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				boolean flag = true;
				String fileName = pathname.getName().toLowerCase();
				for (String suffix : suffixs) {
					if(!fileName.endsWith(suffix)){
	                    flag = false;
	                }
				}
				return flag;
			}
			
		};
		this.filter = filter;
	}
	
	public void createFolder(String path) throws FileNotFoundException {
		File file = create(path);
		/**
		 * 作用是创建文件夹,如果当前路径中包含的父目录不存在时,也会自动根据需要创建。
		 */
		if(!file.exists() && !file.mkdirs()){
			throw new FileNotFoundException("文件夹创建失败");
		}
	}
	
	/**
	 * 创建新的文件,如果有重名,则删除原有的
	 * @param path
	 * @param fileName
	 * @return
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public File createNewFile(String path, String fileName) throws IOException, FileNotFoundException {
		createFolder(path);
		File file = create(path + fileName);
		if(file.exists()) {
			Scanner sc = new Scanner(System.in);
			System.out.println("复制的文件已存在,是否进行覆盖 y/n ?");
			if("y".equals(sc.nextLine())) {
				file.delete();
			}
		}
		file.createNewFile();
		return file;
	}
	/**
	 * 下列几个方法由于使用了泛型,未做检查的转换
	 * @param file
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<File> loadAllFileInFolder(File file) throws ClassCastException {
		List<File> files = new ArrayList<File>();
		if(file.isDirectory()) {
			File[] fs = file.listFiles();
			files = (List<File>) convertArrayToList((T[]) fs);
		}
		return files;
	}
	
	@SuppressWarnings("unchecked")
	public List<File> loadAllFileInFolderFilter(File file) throws ClassCastException, NullPointerException {
		if(filter instanceof FileFilter) {
			List<File> files = new ArrayList<File>();
			if(file.isDirectory()) {
				File[] fs = file.listFiles(filter);
				files = (List<File>) convertArrayToList((T[]) fs);
			}
			return files;
		}
		throw new NullPointerException("过滤对象没有初始化");
	}
	
	@SuppressWarnings("unchecked")
	public List<String> loadAllFileNameInFolder(File file) throws ClassCastException {
		List<String> names = new ArrayList<String>();
		if(file.isDirectory()) {
			String[] ns = file.list();
			names = (List<String>) convertArrayToList((T[]) ns);
		}
		return names;
	}
	/**
	 * 结束
	 */
	
	public void deleteFile(File file) throws FileLockInterruptionException, FileNotFoundException {
		if(file.exists()) {
			if(file.delete()) {
				return;
			}
			throw new FileLockInterruptionException();
		}
		throw new FileNotFoundException();
	}
	
	public void deleteFolder(File file) throws FileLockInterruptionException, FileNotFoundException {
		List<File> files = loadAllFileInFolder(file);
		for (int i = 0, len = files.size(); i < len; i++) {
			File f = files.get(i);
			if(f.isFile()) {
				deleteFile(f);
			} else {
				deleteFolder(f);
			}
		}
		deleteFile(file);
	}
	
	/**
	 * 按字节读取(单个字节读取方式)
	 * @param file
	 * @return
	 * @throws IOException
	 * @throws ContextNotEmptyException
	 */
	public String readFileContentBySingleByte(File file) throws IOException, ContextNotEmptyException {
		//声明一个1kb大小的储存空间来存放读到的内容。注意如果内容长度超过该空间最大长度,只会保留最后一次读取的内容
		byte[] tdata = new byte[CACHE_LENGTH], data = new byte[0];
		FileInputStream in = new FileInputStream(file);
		int index = 0, tempbyte;
		//只要有内容,则一定会进入循环
        while ((tempbyte = in.read()) != -1) {
        	/**
        	 * 这里为了能够在内容超出长度时不造成数据丢失,采用了动态扩容方法来增加长度
        	 * 
        	 * 注意:数组的扩容是一件很耗时的工作,特别是在内容很多的情况下,如何合理分配初始化空间大小
        	 * ,以及扩充的大小需要多多考虑
        	 * 
        	 * 由于长度是1+的方式增长,所以不可能根据tempbyte来进行数组扩充
        	 * 现在的策略是,当index与当前长度一样时,以当前长度添加翻倍来扩充
        	 */
        	if(tdata.length == index){
        		tdata = Arrays.copyOf(tdata, 2 * tdata.length);
        	}
        	tdata[index] = (byte) tempbyte;
        	index++;
        }
        in.close();
        if(index == 0) {
        	throw new ContextNotEmptyException("文件中没有要读取的内容");
        }
        //截取有效长度的数据
        data = Arrays.copyOf(data, index);
        System.arraycopy(tdata, 0, data, 0, index);
        return new String(data);
	}
	
	/**
	 * 按字节读取(一定长度字节读取方式)
	 * @param file
	 * @return
	 * @throws IOException
	 * @throws ContextNotEmptyException
	 */
	public String readFileContentByMultiByte(File file) throws IOException, ContextNotEmptyException {
		byte[] tempData = new byte[CACHE_LENGTH], data = new byte[0];
		FileInputStream in = new FileInputStream(file);
		int len;
        while ((len = in.read(tempData)) != -1) {
        	/**
        	 * 如果没有进入,则说明已经读取完毕;
        	 * 进入了表示还没读完,说明数组长度不够,需要扩容,
        	 * 所以先记录原来数组长度,然后扩容,再从新的位置开始。
        	 * 若还没读完,继续循环直到读完
        	 */
        	data = Arrays.copyOf(data, data.length + len);
        	
        	System.arraycopy(tempData, 0, data, data.length - len, len);
        }
        in.close();
        if(data.length == 0) {
        	throw new ContextNotEmptyException("文件中没有要读取的内容");
        }
        return new String(data);
	}
	
	/**
	 * 按字符读取
	 * @param file
	 * @return
	 * @throws IOException
	 * @throws ContextNotEmptyException
	 */
	public String readFileContentByCharacter(File file) throws IOException, ContextNotEmptyException {
		char[] tempChars = new char[CACHE_LENGTH], chars = new char[0];
        Reader reader = new InputStreamReader(new FileInputStream(file), charsetName);
        int len;
        // 读入多个字符到字符数组中,charread为一次读取字符数
        while ((len = reader.read(tempChars)) != -1) {
        	chars = Arrays.copyOf(chars, chars.length + len);
        	System.arraycopy(tempChars, 0, chars, chars.length - tempchar, len);
        }
        reader.close();
        if(chars.length == 0) {
        	throw new ContextNotEmptyException("文件中没有要读取的内容");
        }
        return new String(chars);
	}
	
	/**
	 * 按行读取
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public String readFileContentByRow(File file) throws IOException {
		InputStreamReader read = new InputStreamReader(new FileInputStream(file), charsetName); 
		BufferedReader reader = new BufferedReader(read);
		String tempString = null;
		StringBuffer s = new StringBuffer();
        // 一次读入一行,直到读入null为文件结束
        while ((tempString = reader.readLine()) != null) {
            s.append(tempString + "\r\n");
        }
        reader.close();
        read.close();
        return s.toString();
	}
	
	/**
	 * 复制文件到目标路径下
	 * @param folderPath	文件夹路径(要复制到的目标位置)
	 * @param OldFile		文件对象(被复制)
	 * @throws Exception
	 */
	public void copyFileContentToTargetFile(String folderPath, File OldFile) throws IOException, FileNotFoundException {
		String path = folderPath + OldFile.getName();
		createNewFile(folderPath, OldFile.getName());
		//读
		FileInputStream in = new FileInputStream(OldFile);
		//写
		FileOutputStream os = new FileOutputStream(path);
		
		byte[] data = new byte[CACHE_LENGTH];
		int len;
		while ((len = in.read(data)) != -1) {
			os.write(data, 0, len);
		}
		os.close();
		in.close();
	}
	
	/**
	 * 复制文件夹下所有内容到目标路径下
	 * @param folderPath	文件夹路径(要复制到的目标位置)
	 * @param folder		文件夹对象(被复制)
	 * @throws Exception
	 */
	public void copyFolderToTargetPath(String folderPath, File folder) throws IOException, FileNotFoundException {
		List<File> files = loadAllFileInFolder(folder);
		if(!files.isEmpty()) {
			for (File OldFile : files) {
				if(OldFile.isFile()){
					copyFileContentToTargetFile(folderPath, OldFile);
				} else if(OldFile.isDirectory()) {
					String filePath = folderPath + OldFile.getName();
					copyFolderToTargetPath(filePath + "/", OldFile);
				}
			}
		}
	}
	
	public void writeContent(File file, String content) throws IOException, UnsupportedEncodingException {
		/**
		 * 若为true,表示内容添加到末尾
		 */
		OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file, false), charsetName);
		BufferedWriter writer = new BufferedWriter(write);
        writer.write(content);
        writer.close();
        write.close();
	}
	
	public void appendContent(File file, String content) throws IOException, UnsupportedEncodingException {
		OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file, true), charsetName);
		BufferedWriter writer = new BufferedWriter(write);
        writer.write(content);
        writer.close();
        write.close();
	}
	
	public void modifyFileName(File file, String newName) throws Exception {
		String path = file.getParent() + "/" + newName;
		File newFile = create(path);
		if(!file.renameTo(newFile)) {
			throw new Exception("error info: file name update failure\npath: " + path);
		}
	}
	
	private List<T> convertArrayToList(T[] arrys) {
		List<T> os = new ArrayList<T>();
		if(arrys instanceof Object) {
			for (int i = 0, len = arrys.length; i < len; i++) {
				os.add(arrys[i]);
			}
		}
		return os;
		
	}
	
	/**
	 * 创建文件对象
	 * @param path	可以是文件夹路径,也可以是文件路径
	 * case C:/test/
	 * case C:/test/1.txt
	 * 
	 * @return
	 * @throws FileNotFoundException
	 */
	private File create(String path) throws FileNotFoundException {
		File file = new File(path);
		return file;
	}
	
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值