阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第16章:字节流与字符流:课时79:综合实战:文件拷贝

在操作系统里面有一个copy命令,这个命令的主要功能是可以实现文件的拷贝处理,现在要求模拟这个命令,通过初始化参数输入拷贝的源文件路径与拷贝的目标路径实现文件的拷贝处理。

需求分析:
需要实现文件的拷贝操作,那么这种拷贝就有可能拷贝各种类型的文件,所以肯定使用字节流;
在进行拷贝的时候有可能需要考虑到大文件的拷贝问题;

实现方案:
方案一:
使用InputStream将全部要拷贝的内容直接读取到程序里面,而后一次性的输出到目标文件。
如果现在拷贝的文件很大,基本上程序就死了;
(存在 do…while问题,一般不使用)

package cn.mldn.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

class FileUtil { // 定义一个文件操作的工具类
	private File srcFile ; // 源文件路径
	private File desFile ; // 目标文件路径
	public FileUtil(String src,String des) {
		this(new File(src),new File(des));
	}
	public FileUtil(File srcFile,File desFile) {
		this.srcFile = srcFile;
		this.desFile = desFile;
	}
	public boolean copy() throws Exception { // 文件拷贝处理
		if (!this.srcFile.exists()) { // 源文件必须存在!
			System.out.println("拷贝的源文件不存在!");
			return false ; // 拷贝失败
		}
		if (!this.desFile.getParentFile().exists()) {
			this.desFile.getParentFile().mkdirs(); // 创建父目录
		}
		byte data [] = new byte[1024] ; // 开辟一个拷贝的缓冲区
		InputStream input = null ;
		OutputStream output = null ;
		try {
			input = new FileInputStream(this.srcFile);
			output = new FileOutputStream(this.desFile);
			int len = 0;
			do {
				len = input.read(data) ; // 拷贝的内容都在data数组
				if (len != -1) {
					output.write(data,0,len);
				}
			} while (len != -1);
			return true ;
		} catch (Exception e) {
			throw e ;
		} finally {
			if (input != null) {
				input.close();	
			}
			if (output != null) {
				output.close();				
			}
		}
	}
}
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
    	if (args.length != 2) { // 程序执行出错
    		System.out.println("命令执行错误,执行结构,java JavaAPIDemo 拷贝源文件路径拷贝目标文件路径");
    		System.exit(1);
    	}
    	long start = System.currentTimeMillis();
    	FileUtil fu = new FileUtil(args[0],args[1]);
    	System.out.println(fu.copy() ? "文件拷贝成功" : "文件拷贝失败!");
    	long end = System.currentTimeMillis();
    	System.out.println("拷贝完成的时间:" + (end - start));
    }
}

方案二:
采用部分拷贝,读取一部分输出一部分数据,如果现在要采用第二种做法,核心的操作方法:
InputStream:public int read(byte[] b) throws IOException;
OutputStream:public void write(byte[] b, int off, int len) throws IOException。

范例:实现文件拷贝处理

package cn.mldn.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

class FileUtil { // 定义一个文件操作的工具类
	private File srcFile ; // 源文件路径
	private File desFile ; // 目标文件路径
	public FileUtil(String src,String des) {
		this(new File(src),new File(des));
	}
	public FileUtil(File srcFile,File desFile) {
		this.srcFile = srcFile;
		this.desFile = desFile;
	}
	public boolean copy() throws Exception { // 文件拷贝处理
		if (!this.srcFile.exists()) { // 源文件必须存在!
			System.out.println("拷贝的源文件不存在!");
			return false ; // 拷贝失败
		}
		if (!this.desFile.getParentFile().exists()) {
			this.desFile.getParentFile().mkdirs(); // 创建父目录
		}
		byte data [] = new byte[1024] ; // 开辟一个拷贝的缓冲区
		InputStream input = null ;
		OutputStream output = null ;
		try {
			input = new FileInputStream(this.srcFile);
			output = new FileOutputStream(this.desFile);
			int len = 0;
			// 1。读取数据到数组之中,随后返回读取的个数、len = input.read(data)
			// 2。判断个数是否是-1,如果 不是则进行写入、len = input.read(data) != -1
			while ((len = input.read(data)) != -1) {
				output.write(data,0,len);
			}
			return true ;
		} catch (Exception e) {
			throw e ;
		} finally {
			if (input != null) {
				input.close();	
			}
			if (output != null) {
				output.close();				
			}
		}
	}
}
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
    	if (args.length != 2) { // 程序执行出错
    		System.out.println("命令执行错误,执行结构,java JavaAPIDemo 拷贝源文件路径拷贝目标文件路径");
    		System.exit(1);
    	}
    	long start = System.currentTimeMillis();
    	FileUtil fu = new FileUtil(args[0],args[1]);
    	System.out.println(fu.copy() ? "文件拷贝成功" : "文件拷贝失败!");
    	long end = System.currentTimeMillis();
    	System.out.println("拷贝完成的时间:" + (end - start));
    }
}

但是需要注意的是,以上的做法是属于文件拷贝的最原始实现,而从JDK1.9开始InputStream和Reader类中都追加有数据转存的处理操作方法:
InputStream:public long transferTo(OutputStream out) throws IOException;
Reader:public long transferTo(Writer out) throws IOException;

范例:使用转存的方式处理

package cn.mldn.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

class FileUtil { // 定义一个文件操作的工具类
	private File srcFile ; // 源文件路径
	private File desFile ; // 目标文件路径
	public FileUtil(String src,String des) {
		this(new File(src),new File(des));
	}
	public FileUtil(File srcFile,File desFile) {
		this.srcFile = srcFile;
		this.desFile = desFile;
	}
	public boolean copy() throws Exception { // 文件拷贝处理
		if (!this.srcFile.exists()) { // 源文件必须存在!
			System.out.println("拷贝的源文件不存在!");
			return false ; // 拷贝失败
		}
		if (!this.desFile.getParentFile().exists()) {
			this.desFile.getParentFile().mkdirs(); // 创建父目录
		}
		InputStream input = null ;
		OutputStream output = null ;
		try {
			input = new FileInputStream(this.srcFile);
			output = new FileOutputStream(this.desFile);
			input.transferTo(output);
			return true ;
		} catch (Exception e) {
			throw e ;
		} finally {
			if (input != null) {
				input.close();	
			}
			if (output != null) {
				output.close();				
			}
		}
	}
}
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
    	if (args.length != 2) { // 程序执行出错
    		System.out.println("命令执行错误,执行结构,java JavaAPIDemo 拷贝源文件路径拷贝目标文件路径");
    		System.exit(1);
    	}
    	long start = System.currentTimeMillis();
    	FileUtil fu = new FileUtil(args[0],args[1]);
    	System.out.println(fu.copy() ? "文件拷贝成功" : "文件拷贝失败!");
    	long end = System.currentTimeMillis();
    	System.out.println("拷贝完成的时间:" + (end - start));
    }
}

此时千万要注意程序的运行版本问题。那么如果说现在对此程序要求进一步扩展,可以实现一个文件目录的拷贝呢?一旦进行了文件目录的拷贝还需要拷贝所有的子目录中的文件。

范例:文件夹拷贝

package cn.mldn.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

class FileUtil { // 定义一个文件操作的工具类
	private File srcFile ; // 源文件路径
	private File desFile ; // 目标文件路径
	public FileUtil(String src,String des) {
		this(new File(src),new File(des));
	}
	public FileUtil(File srcFile,File desFile) {
		this.srcFile = srcFile;
		this.desFile = desFile;
	}
	public boolean copyDir() throws Exception {
		try {
			this.copyImpl(this.srcFile) ;
			return true ;
		} catch (Exception e) {
			return false ;
		}
	}
	private void copyImpl(File file) throws Exception { // 递归操作
		if (file.isDirectory()) { // 是目录
			File results [] = file.listFiles(); // 列出全部目录组成
			if (results != null) {
				for (int x = 0; x < results.length; x++) {
					copyImpl(results[x]);
				}
			}
		} else { // 是文件
			String newFilePath = file.getPath().replace(this.srcFile.getPath() + File.separator,"");
			File newFile = new File(this.desFile,newFilePath); // 拷贝的目标路径
			this.copyFileImpl(file, newFile) ;
		}
	}
	private boolean copyFileImpl(File srcFile,File desFile) throws Exception {
		if (!desFile.getParentFile().exists()) {
			desFile.getParentFile().mkdirs(); // 创建父目录
		}
		InputStream input = null ;
		OutputStream output = null ;
		try {
			input = new FileInputStream(srcFile);
			output = new FileOutputStream(desFile);
			input.transferTo(output);
			return true ;
		} catch (Exception e) {
			throw e ;
		} finally {
			if (input != null) {
				input.close();	
			}
			if (output != null) {
				output.close();				
			}
		}
	}
	public boolean copy() throws Exception { // 文件拷贝处理
		if (!this.srcFile.exists()) { // 源文件必须存在!
			System.out.println("拷贝的源文件不存在!");
			return false ; // 拷贝失败
		}
		return this.copyFileImpl(this.srcFile, this.desFile) ;
	}
}
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
    	if (args.length != 2) { // 程序执行出错
    		System.out.println("命令执行错误,执行结构,java JavaAPIDemo 拷贝源文件路径拷贝目标文件路径");
    		System.exit(1);
    	}
    	long start = System.currentTimeMillis();
    	FileUtil fu = new FileUtil(args[0],args[1]);
    	if (new File(args[0]).isFile()) {
    		System.out.println(fu.copy() ? "文件拷贝成功" : "文件拷贝失败!");
    	}else {
    		System.out.println(fu.copyDir() ? "文件夹拷贝成功" : "文件夹拷贝失败!");
    	}
    	long end = System.currentTimeMillis();
    	System.out.println("拷贝完成的时间:" + (end - start));
    }
}

本程序是IO操作的核心代码,本程序可以理解,整个的IO处理机制就非常容易理解了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SHA-1是一种单向哈希函数,可以将任意长度的数据转换成160位的哈希值。在密码加密中,我们通常将用户输入的密码进行SHA-1哈希值计算,然后将计算出的哈希值存储到数据库中,以保证用户密码的安全性。 以下是一个使用Java语言实现SHA-1密码加密的示例代码: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Sha1PasswordEncryption { public static void main(String[] args) { String password = "123456"; String hashedPassword = sha1(password); System.out.println("原始密码:" + password); System.out.println("加密后密码:" + hashedPassword); } public static String sha1(String input) { try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); byte[] inputBytes = input.getBytes(); byte[] hashedBytes = messageDigest.digest(inputBytes); StringBuilder hashedStringBuilder = new StringBuilder(); for (byte hashedByte : hashedBytes) { hashedStringBuilder.append(Integer.toString((hashedByte & 0xff) + 0x100, 16).substring(1)); } return hashedStringBuilder.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } } ``` 在上述代码中,我们首先定义了一个字符串类型的原始密码password,然后调用sha1方法将其进行SHA-1哈希值计算。在sha1方法中,我们首先获取SHA-1的MessageDigest实例,然后将输入字符串input转换成字节数组inputBytes,通过调用digest方法对inputBytes进行哈希值计算得到字节数组hashedBytes,最后将hashedBytes转换成十六进制字符串hashedStringBuilder并返回。最终输出加密后的密码hashedPassword。 需要注意的是,在真实的应用场景中,我们通常会对哈希值进行加盐处理以增加密码的安全性。同时,SHA-1已经被证明存在一定的安全漏洞,因此在实际应用中建议使用更加安全的哈希算法,例如SHA-256、SHA-512等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值