The code copy is as follows:
package com.xyq.io.simply.core;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import com.xyq.io.enums.FileTypeMode;
import com.xyq.io.enums.OptionFile_TYPE;
import com.xyq.io.inf.NewNIoInf;
import com.xyq.io.util.FindFileUtil;
import com.xyq.io.util.MD5Util;
public class NewNIO implements NewNIoInf {
/***
* Copy or move files
*/
@Override
public boolean copeOrMoveFile(String src, String tar, OptionFile_TYPE type) {
return realCopeOrMoveFile(Paths.get(src), tar, type);
}
private boolean realCopeOrMoveFile(Path srcPath, String tar,
OptionFile_TYPE type) {
Path tarPath = null;
boolean copeSuccess = true;
// The original file must exist
if (srcPath.toFile().exists()) {
/***
* If the original path is slashed, then it is considered a folder
*/
if (isDir(tar))
tarPath = Paths.get(tar + File.separator
+ srcPath.toFile().getName());
else
tarPath = Paths.get(tar);
/***
* Then perform N times (can be used as parameters) copy operation (reconnection after error), whether to overwrite copy, copy attribute, copy operation cannot use the rollback option
*/
for (int i = 0; i < 3; i++) {
/***
* If the target file already exists
*/
if (tarPath.toFile().exists()) {
/***
* If you verify that the two folders are the same, you don’t need to copy under the copy option. The move option is to delete the original file.
*/
// Copy
if (OptionFile_TYPE.COPE.equals(type)) {
if (equalsFile(srcPath.toFile(), tarPath.toFile()))
return true;
else
copeSuccess = copeFile(srcPath, tarPath, true);
}
/***
* Move operation, be very careful here. Under normal circumstances, if the two files are the same,
* Then just delete the original file. However, if the two files are the same and the address is also
* If it is the same, then the original one cannot be deleted because it is the same file and cannot be deleted.
*/
else if (OptionFile_TYPE.MOVE.equals(type)) {
if (equalsFile(srcPath.toFile(), tarPath.toFile())) {
if (!srcPath.toFile().getAbsoluteFile())
.equals(tarPath.toFile().getAbsoluteFile()))
try {
Files.delete(srcPath);
/***
* The reason for pointing to true manually is that there may be a failure in previous deletion.
*/
if (!copeSuccess)
copeSuccess = true;
} catch (IOException e) {
copeSuccess = false;
}
// I don't return directly because there is an exception in the front, just do it here
else
return true;
} else
copeSuccess = moveFile(srcPath, tarPath);
}
}
/***
* When the target file does not exist, first determine whether the parent class folder can be created (the parent class folder exists or can be created), and then create it when it can be created.
*/
else {
File par = tarPath.getParent().toFile();
/***
* If the parent class folder does not exist and cannot be created, then there is no need to copy it
*/
if (!par.exists() && !par.mkdirs())
copeSuccess = false;
else if (OptionFile_TYPE.COPE.equals(type))
copeSuccess = copeFile(srcPath, tarPath, false);
else if (OptionFile_TYPE.MOVE.equals(type))
copeSuccess = moveFile(srcPath, tarPath);
}
// If the operation is successful, the loop will be jumped out
if (copeSuccess)
break;
}
} else
copeSuccess = false;
return copeSuccess;
}
/***
* Copy the file
*/
private boolean copeFile(Path srcPath, Path tarPath, boolean isExist) {
if (isExist)
try {
Files.copy(srcPath, tarPath,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
} catch (IOException e) {
return false;
}
else
try {
Files.copy(srcPath, tarPath, StandardCopyOption.COPY_ATTRIBUTES);
} catch (IOException e) {
return false;
}
return true;
}
/***
* Move files, no attribute options can be used
*
* @param srcPath
* @param tarPath
* @return
*/
private boolean moveFile(Path srcPath, Path tarPath) {
try {
Files.move(srcPath, tarPath, StandardCopyOption.ATOMIC_MOVE);
} catch (IOException e) {
return false;
}
return true;
}
/***
* Determine whether the path path is a folder
*
* @param path
* @return
*/
private boolean isDir(String path) {
char lastC = path.charAt(path.length() - 1);
if (lastC == '//' || lastC == '/')
return true;
return false;
}
/***
* This is to verify whether the two files are the same, it is just a simple verification, and it can be forced to use md5 for verification
*/
public boolean equalsFile(File src, File tar) {
// If the lengths of the two files are different, then the two files are definitely different
if (src.length() != tar.length())
return false;
if (!src.getName().equals(tar.getName())
|| src.lastModified() != tar.lastModified())
return MD5Util.EncoderFileByMd5(src).equals(
MD5Util.EncoderFileByMd5(tar));
return true;
}
/***
* Copy or move folders
*/
@Override
public void copeOrMoveDirectory(String src, final String tar, int tierSize,
final OptionFile_TYPE type) {
if (!new File(src).exists())
throw new RuntimeException("Original folder not found" + src);
final int rootPos = getRootPosition(new File(src), tierSize);
if (rootPos != -1) {
try {
Files.walkFileTree(Paths.get(src), new FileVisitor<Path>() {
String tarDirString = null;
/***
* Before arriving at the folder, write the target path first
*
* @param dir
* @param attrs
* @return
* @throws IOException
*/
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
tarDirString = dir.toFile().getAbsolutePath();
tarDirString = tar + tarDirString.substring(rootPos)
+ File.separator;
return FileVisitResult.CONTINUE;
}
/***
* After arriving at the file, copy or move it
*
* @param file
* @param attrs
* @return
* @throws IOException
*/
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
File f = file.toFile();
if (f.exists() && f.canRead() && !f.isHidden())
realCopeOrMoveFile(file, tarDirString, type);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file,
IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
/***
* After arriving at the folder
*
* @param dir
* @param excc
* @return
* @throws IOException
*/
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
} catch (Exception e) {
e.printStackTrace();
}
// If it is a cut operation and the cut is successful, then you need to delete all folders
if (OptionFile_TYPE.MOVE.equals(type) && isBlockDir(src))
delDir(src);
} else
throw new RuntimeException("Specify parent class folder hierarchy error~~~");
}
/***
* Get the location of the specified drive letter according to the specified level
*/
private int getRootPosition(File file, int tier) {
if (file != null) {
String path = file.getAbsolutePath();
int cc = 0;
for (int i = path.length() - 1; i >= 0; i--) {
if (path.charAt(i) == '//') {
cc++;
if (cc == tier + 1) {
cc = i;
return cc;
}
}
}
}
return -1;
}
/***
* Check if there are any files in this folder
*
* @param dirPath
* @return
*/
private boolean isBlockDir(String dirPath) {
File dir = new File(dirPath);
File[] dirList = dir.listFiles();
if (dirList == null || dirList.length == 0)
return true;
else {
// Find files
for (File f : dirList)
if (!f.isDirectory())
return false;
}
return true;
}
/***
* Delete empty folders
*
* @param dirPath
*/
private void delDir(String dirPath) {
File dir = new File(dirPath);
File[] dirList = dir.listFiles();
if (dirList == null || dirList.length == 0)
dir.delete();
else {
// Delete all files
for (File f : dirList)
if (f.isDirectory())
delDir(f.getAbsolutePath());
else
f.delete();
// Delete the folder after deleting all files in the current folder
dirList = dir.listFiles();
if (dirList.length == 0)
dir.delete();
}
}
/***
* Find relevant files based on file type
*/
@Override
public List<String> findFilesByType(String dir, String[] keys,
boolean isMatchCase) throws IOException {
List<String> list = new ArrayList<String>();
Files.walkFileTree(Paths.get(dir), new FindFileUtil(keys, isMatchCase,
list, FileTypeMode.TYPES));
return list;
}
/***
* Find relevant files based on file name
*/
@Override
public List<String> findFilesByName(String dir, String[] keys,
boolean isMatchCase) throws IOException {
List<String> list = new ArrayList<String>();
Files.walkFileTree(Paths.get(dir), new FindFileUtil(keys, isMatchCase,
list, FileTypeMode.NAMES));
return list;
}
public static void main(String[] args) throws IOException {
NewNIoInf inf = new NewNIO();
inf.copeOrMoveFile("e:/cc/dd/11.txt", "e:/XX/xxx/zzz/",
OptionFile_TYPE.COPE);
inf.copeOrMoveDirectory("e://BB//CC//DD", "e://",1, OptionFile_TYPE.MOVE);
System.out.println(inf.findFilesByName("D://workspace", new String[] { "txt" },
false).size());
}
}
--------------------------------
package com.xyq.io.enums;
/***
* File Type
* @author xyq
*
*/
public enum FileTypeMode {
TYPES,NAMES
}
---------------------------------
package com.xyq.io.enums;
/***
* Type of operation file
* @author xyq
*
*/
public enum OptionFile_TYPE {
COPE,MOVE;
}
--------------------------------------------------------------------------------------------------------------------------------
package com.xyq.io.inf;
import java.io.IOException;
import java.util.List;
import com.xyq.io.enums.OptionFile_TYPE;
public interface NewNIoInf {
/***
* Copy or move files
* @param src
* @param tar
* @return
*/
public boolean copeOrMoveFile(String src,String tar,OptionFile_TYPE type);
/***
* Copy or move folders
* @param src
* @param tar
* @param tierSize hierarchy, the path 0 after copying is just the current folder, +1 means adding a first-level parent class folder (but not copying the parent class content)
* @param type
*/
public void copeOrMoveDirectory(String src,String tar,int tierSize,OptionFile_TYPE type);
/**
* Find relevant file collections based on file type, separate them with commas when multiple types
*
* @param dir
* Table of contents
* @param keys
* File Type
* @param isMatchCase
* Whether it is case sensitive
* @return
* @throws IOException
*/
List<String> findFilesByType(String dir, String[] keys, boolean isMatchCase)
throws IOException;
/**
* Find relevant file collections based on file name, separate them with commas when multiple civil terms
*
* @param dir
* Table of contents
* @param keys
* File name
* @param isMatchCase
* Whether it is case sensitive
* @return
* @throws IOException
*/
List<String> findFilesByName(String dir, String[] keys, boolean isMatchCase)
throws IOException;
}
---------------------
package com.xyq.io.util;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import com.xyq.io.enums.FileTypeMode;
public class FindFileUtil extends SimpleFileVisitor<Path> {
/***
* Keyword list, whether to convert case, return result set
*/
private String[] keyArray = null;
private boolean isMatchCase;
private List<String> resultList;
private FileTypeMode mode;
public FindFileUtil(String[] keyArray, boolean isMatchCase,
List<String> resultList, FileTypeMode mode) {
this.keyArray = keyArray;
this.isMatchCase = isMatchCase;
this.resultList = resultList;
this.mode = mode;
}
@SuppressWarnings("unused")
private FindFileUtil() {
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
File f = file.toFile();
if (f.exists() && f.canRead() && !f.isHidden())
if (this.keyArray != null) {
for (String key : this.keyArray) {
if (!this.isMatchCase)
key = key.toLowerCase();
if (matchFile(file, this.mode, key, isMatchCase))
resultList.add(file.toString());
}
}
return FileVisitResult.CONTINUE;
}
/***
* File matching based on case and type or name
*
* @param file
* @param mode
* @param key
* @param isMatchCase
* @return
*/
private boolean matchFile(Path file, FileTypeMode mode, String key,
boolean isMatchCase) {
File f = file.toFile();
if (f.exists() && f.canRead() && !f.isHidden()
&& !"System Volume Information".equals(f.getName())) {
String fileName = null;
if (FileTypeMode.TYPES.equals(mode)) {
fileName = file.toString();
return isMatchCase? fileName.endsWith(key): fileName
.toLowerCase().endsWith(key);
} else if (FileTypeMode.NAMES.equals(mode)) {
fileName = file.toFile().getName();
return isMatchCase ? (fileName.indexOf(key) == -1 ? false
: true)
: (fileName.toLowerCase().indexOf(key) == -1 ? false
: true);
}
}
return false;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException excc)
throws IOException {
//If the error message contains X:/System Volume Information, this means the system's hidden disk and cannot be read
System.out.println(exc.getMessage());
return FileVisitResult.CONTINUE;
}
}
--------------------------------
package com.xyq.io.util;
import java.io.Closeable;
public class CloseIoUtil {
/***
* Close IO stream
*
* @param cls
*/
public static void closeAll(Closeable... cls) {
if (cls != null) {
for (Closeable cl : cls) {
try {
if (cl != null)
cl.close();
} catch (Exception e) {
} finally {
cl = null;
}
}
}
}
}
--------------------------------------------------------------------------------------------------------------------------------
package com.xyq.io.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
public class MD5Util {
/***
* Encrypted string
*
* @param str
* @return
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
*/
public static String EncoderStringByMd5(String str)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
// Determine the calculation method
MessageDigest md5 = MessageDigest.getInstance("MD5");
BASE64Encoder base64en = new BASE64Encoder();
// Encrypted string
String newsr = base64en.encode(md5.digest(str.getBytes("utf-8")));
return newsr;
}
/***
* Encrypted files
*
* @param file
* @return
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public static String EncoderFileByMd5(File file) {
String newsstr = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
// Determine the calculation method
MessageDigest md5 = MessageDigest.getInstance("MD5");
BASE64Encoder base64en = new BASE64Encoder();
byte[] buffer = new byte[1024];
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
int length = -1;
while ((length = bis.read(buffer)) != -1)
md5.update(buffer, 0, length);
// Encrypted string
newsstr = base64en.encode(md5.digest());
} catch (Exception e) {
e.printStackTrace();
} finally {
CloseIoUtil.closeAll(bis, fis);
}
return newsr;
}
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
System.out.println(EncoderStringByMd5("23"));
}
}