0%

利用java复制文件或目录,要么使用递归的方法,要么使用walkFileTree的方法。大家可以比较一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package gy.finolo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

import static java.nio.file.FileVisitResult.CONTINUE;

public class CopyUtils {

public static void copy2Directory(Path inPath, Path outDirPath) throws IOException {

// 确保输出目录存在, 如果inPath是File的话, 这里就执行一次, 所以不用写到copyFile2Diretory()方法里
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}

if (Files.isDirectory(inPath)) {
copyFilesInDirectory2Directory(inPath, outDirPath);
} else {
copyFile2Directory(inPath, outDirPath);
}


}

private static void copyFilesInDirectory2Directory(Path inDirPath, Path outDirPath) throws IOException {
DirectoryStream<Path> paths = Files.newDirectoryStream(inDirPath);
for (Path path : paths) {

if (Files.isDirectory(path)) {
Path subOutDirPath = outDirPath.resolve(inDirPath.relativize(path));
// 确保输出目录存在
if (!Files.exists(subOutDirPath)) {
Files.createDirectories(subOutDirPath);
}
copyFilesInDirectory2Directory(path, subOutDirPath);
} else {
Path subOutDirPath = outDirPath.resolve(inDirPath.relativize(path.getParent()));
copyFile2Directory(path, subOutDirPath);
}
}
}

private static void copyFile2Directory(Path inFilePath, Path outDirPath) throws IOException {
Path fileName = inFilePath.getFileName();
Path outFilePath = outDirPath.resolve(fileName);

int bufSize = 8 * 1024;
byte[] buffer = new byte[bufSize];
int len;

try (InputStream is = Files.newInputStream(inFilePath);
OutputStream os = Files.newOutputStream(outFilePath, StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE,
StandardOpenOption.CREATE)) {
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
}
}

/**
* 注意: visitFile方法中, 每次需要做一个if (inPath.equals(file))的判断,
* 如果inPath是文件, 那返回为true, 如果inPath为目录, 那永远返回false
* 我是为了统计, 才在里面加了一个判断, 在实际运用中, 有了这个判断效率就不高了。
* @param inPath
* @param outDirPath
* @throws IOException
*/
public static void copy2DirectoryV2(Path inPath, Path outDirPath) throws IOException {
// 确保输出目录存在
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}

Files.walkFileTree(inPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
System.out.println("processing DIR: " + dir);
Path subOutDirPath = outDirPath.resolve(inPath.relativize(dir));

if (!Files.exists(subOutDirPath)) {
Files.createDirectories(subOutDirPath);
}
return CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
System.out.println("processing FILE: " + file);
Path outPath;
if (inPath.equals(file)) {
// 说明source是一个文件, 只需要单独复制一个文件即可
outPath = outDirPath.resolve(file.getFileName());
} else {
outPath = outDirPath.resolve(inPath.relativize(file));
}
Files.copy(file, outPath);
return CONTINUE;
}
});
}

public static void main(String[] args) {

Path inPath = Paths.get("/usr/local");
Path outDirPath = Paths.get("/opt");

try {
// CopyUtils.copy2Directory(inPath, outDirPath);
CopyUtils.copy2DirectoryV2(inPath, outDirPath);
} catch (IOException e) {
e.printStackTrace();
}

}
}

使用Apache Commons Net,从FTP服务器上下载文件。

需要使用的依赖:

1
2
3
4
5
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>

有几点需要注意的:

设置编码需要在connect之前。
设置ftp模式需要在connect之后。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package gy.finolo;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class FTPUtils {

private static Logger log = LoggerFactory.getLogger(FTPUtils.class);

public static FTPClient loginFTP(String hostname, int port, String username, String password) throws IOException {

FTPClient ftpClient = new FTPClient();
// 中文文件读取支持, 必须在connect之前设置
ftpClient.setControlEncoding("UTF-8");

ftpClient.connect(hostname, port);
// 被动模式设置, 必须在connect之后
ftpClient.enterLocalPassiveMode();

ftpClient.login(username, password);
// 设置文件类型为二进制, 若不设置, 压缩文件可能失败
// ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
log.info("ftp connection succeed");
} else {
String message = "ftp server connection error: " + ftpClient.getReplyString();
log.error(message);
throw new IOException(message);
}

return ftpClient;
}

public static void downloadFromFTP(FTPClient ftpClient, String ftpFile, String outDir) throws IOException {
// 在这个方法里把该转的路径都转为Path
boolean isDirectory = ftpClient.changeWorkingDirectory(ftpFile);
Path outDirPath = Paths.get(outDir);
if (isDirectory) {
downloadFTPDirectory2Directory(ftpClient, ftpFile, outDirPath);
} else {
downloadFTPFile2Directory(ftpClient, ftpFile, outDirPath);
}
}

// downlaod directory from ftp to directory (outDir)
private static void downloadFTPDirectory2Directory(FTPClient ftpClient, String ftpFileDir, Path outDirPath) throws IOException {
// 保证输出文件夹要存在
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}

FTPFile[] ftpFiles = ftpClient.listFiles(ftpFileDir);
for (FTPFile file: ftpFiles) {
if (file.isFile()) {
// ftp file full path
Path ftpFileFullPath = Paths.get(ftpFileDir).resolve(file.getName());
downloadFTPFile2Directory(ftpClient, ftpFileFullPath.toString(), outDirPath);
// download files under the directory to the outDir
} else {
String dirName = file.getName();
Path subOutDirPath = outDirPath.resolve(dirName);
Path subFtpDirPath = Paths.get(ftpFileDir).resolve(dirName);
downloadFTPDirectory2Directory(ftpClient, subFtpDirPath.toString(), subOutDirPath);
}
}
}

// download ftp file (ftpFile) to directory (outDir)
private static void downloadFTPFile2Directory(FTPClient ftpClient, String ftpFile, Path outDirPath) throws IOException {
// 保证输出文件夹要存在
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}
// ftpFile is full path
try (InputStream is = ftpClient.retrieveFileStream(ftpFile)) {
if (is != null) {
Path ftpFileNamePath = Paths.get(ftpFile).getFileName();
Path outPath = outDirPath.resolve(ftpFileNamePath);

int bufSize = 8 * 1024;
byte[] buffer = new byte[bufSize];
int len;

try (OutputStream os = Files.newOutputStream(outPath, StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {

while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
}
}
}
ftpClient.completePendingCommand();
}

public static void main(String[] args) throws IOException {
String hostname = "192.168.1.2";
int port = 21;
String username = "ftpuser";
String password = "ftppass";

FTPClient ftpClient;
try {
ftpClient = FTPUtils.loginFTP(hostname, port, username, password);
downloadFromFTP(ftpClient, ".", "./dir");
// log out and disconnect from the server
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}

}
}

批量递归删除当前目录下,以.class为后缀的文件。

1
find . -name '*.class' -type f -print -exec rm -rf {} \;

.表示从当前目录开始递归查找

-name '*.class'根据名称来查找,查找指定目录下以.class结尾的文件

-type f查找的类型为文件

-print输出查找到的文件全路径名

-exec后面写要执行的命令。