com.orion.net.ftp.client.instance.FtpInstance Maven / Gradle / Ivy
The newest version!
package com.orion.net.ftp.client.instance;
import com.orion.lang.constant.Const;
import com.orion.lang.define.StreamEntry;
import com.orion.lang.utils.Exceptions;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.io.Files1;
import com.orion.lang.utils.io.Streams;
import com.orion.lang.utils.time.Dates;
import com.orion.net.ftp.client.FtpFile;
import com.orion.net.ftp.client.FtpFileFilter;
import com.orion.net.ftp.client.config.FtpConfig;
import com.orion.net.ftp.client.pool.FtpClientPool;
import com.orion.net.ftp.client.transfer.FtpDownloader;
import com.orion.net.ftp.client.transfer.FtpUploader;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* FTP 操作实例
*
* @author Jiahang Li
* @version 1.0.0
* @since 2020/3/17 16:10
*/
@SuppressWarnings("ALL")
public class FtpInstance extends BaseFtpInstance {
public FtpInstance(FtpClientPool pool) {
super(pool);
}
public FtpInstance(FTPClient client, FtpConfig config) {
super(client, config);
}
@Override
public void change() {
try {
client.changeWorkingDirectory(this.serverCharset(config.getRemoteRootDir()));
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public void change(String dir) {
try {
if (!client.changeWorkingDirectory(this.serverCharset(config.getRemoteRootDir() + dir))) {
this.makeDirectories(dir);
client.changeWorkingDirectory(this.serverCharset(config.getRemoteRootDir() + dir));
}
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public String getWorkDirectory() {
try {
return client.printWorkingDirectory();
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public boolean isExist(String file) {
String parentPath = Files1.getParentPath(file);
List list = this.listFiles(parentPath, false, true);
for (FtpFile s : list) {
if (Files1.getFileName(s.getPath()).equals(Files1.getFileName(file.trim()))) {
return true;
}
}
return false;
}
@Override
public FtpFile getFile(String file) {
String parentPath = Files1.getParentPath(file);
List files = this.listFiles(parentPath, false, true);
for (FtpFile ftpFile : files) {
if (ftpFile.getName().equals(Files1.getFileName(file))) {
return ftpFile;
}
}
return null;
}
@Override
public long getSize(String file) {
FtpFile ftpFile = this.getFile(file);
if (ftpFile == null) {
return -1;
}
return ftpFile.getSize();
}
@Override
public long getModifyTime(String file) {
try {
// .e.g 213 20200202020202.000
String modificationTime = client.getModificationTime(file);
if (modificationTime == null) {
return -1;
}
String time = modificationTime.split(Const.SPACE)[1];
return Dates.parse(time, Dates.YMD_HMS2).getTime();
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public void setModifyTime(String file, Date time) {
try {
client.setModificationTime(file, Dates.format(time, Dates.YMD_HMS2));
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public void truncate(String file) throws IOException {
OutputStream out = null;
try {
out = client.storeFileStream(this.serverCharset(config.getRemoteRootDir() + file));
out.flush();
} catch (Exception e) {
throw Exceptions.ftp(e);
} finally {
Streams.close(out);
if (out != null) {
client.completePendingCommand();
}
}
}
@Override
public void remove(String file) {
FtpFile ftpFile = this.getFile(file);
if (ftpFile == null) {
return;
}
if (ftpFile.isDirectory()) {
this.removeDir(file);
} else {
this.removeFile(file);
}
}
@Override
public void removeFile(String file) {
try {
client.deleteFile(this.serverCharset(file));
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public void removeDir(String dir) {
try {
List list = this.listFiles(dir, false, true);
for (FtpFile s : list) {
String path = s.getPath();
if (s.isDirectory()) {
this.removeDir(path);
client.removeDirectory(this.serverCharset(Files1.getPath(config.getRemoteRootDir(), path)));
} else {
client.deleteFile(this.serverCharset(Files1.getPath(config.getRemoteRootDir(), path)));
}
}
client.changeWorkingDirectory(this.serverCharset(config.getRemoteRootDir() + Files1.getParentPath(dir)));
client.removeDirectory(this.serverCharset(Files1.getFileName(dir)));
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public void makeDirectories(String dir) {
try {
String[] dirs = Files1.getPath(dir).split(SEPARATOR);
String base = config.getRemoteRootDir();
for (String d : dirs) {
if (d == null || Strings.EMPTY.equals(d)) {
continue;
}
base = this.serverCharset(base + SEPARATOR + d);
if (!client.changeWorkingDirectory(base)) {
client.makeDirectory(base);
client.changeWorkingDirectory(base);
}
}
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
@Override
public void touch(String file) {
String fileName = Files1.getFileName(file);
String filePath = this.serverCharset(config.getRemoteRootDir() + file);
String parentPath = Files1.getParentPath(Files1.getPath(file));
this.makeDirectories(parentPath);
for (FtpFile s : this.listFiles(parentPath, false)) {
if (Files1.getFileName(s.getPath()).equals(fileName)) {
return;
}
}
this.change(parentPath);
try {
client.storeFile(this.serverCharset(filePath), new ByteArrayInputStream(new byte[]{}));
} catch (IOException e) {
throw Exceptions.ftp(e);
}
}
@Override
public void move(String source, String target) {
source = Files1.getPath(source);
target = Files1.getPath(target);
try {
if (target.charAt(0) == '/') {
// 绝对路径
target = Files1.getPath(config.getRemoteRootDir() + Files1.normalize(target));
} else {
// 相对路径
target = Files1.getPath(Files1.normalize(Files1.getPath(source + "/../" + target)));
}
this.change(Files1.getParentPath(source));
this.makeDirectories(Files1.getParentPath(target));
client.rename(source, target);
} catch (Exception e) {
throw Exceptions.ftp(e);
}
}
// -------------------- stream --------------------
@Override
public InputStream openInputStream(String file, long skip) throws IOException {
try {
client.setRestartOffset(skip);
InputStream in = client.retrieveFileStream(this.serverCharset(config.getRemoteRootDir() + file));
if (in == null) {
throw Exceptions.ftp("not found file " + file);
}
return in;
} catch (Exception e) {
throw Exceptions.io("cannot get file input stream " + file, e);
} finally {
client.setRestartOffset(0);
}
}
@Override
public OutputStream openOutputStream(String file, boolean append) throws IOException {
this.makeDirectories(Files1.getParentPath(file));
try {
if (append) {
return client.appendFileStream(this.serverCharset(config.getRemoteRootDir() + file));
} else {
return client.storeFileStream(this.serverCharset(config.getRemoteRootDir() + file));
}
} catch (Exception e) {
throw Exceptions.io("cannot get file out stream " + file, e);
}
}
// -------------------- read --------------------
@Override
public int read(String file, long skip, byte[] bs, int off, int len) throws IOException {
InputStream in = null;
try {
in = this.openInputStream(file, skip);
return in.read(bs, off, len);
} finally {
Streams.close(in);
client.setRestartOffset(0);
if (in != null) {
client.completePendingCommand();
}
}
}
// -------------------- transfer --------------------
@Override
protected long doTransfer(String path, OutputStream out, long skip, int size, boolean close) throws IOException {
long r = 0;
byte[] bs = new byte[bufferSize];
InputStream in = null;
try {
in = this.openInputStream(path, skip);
if (size != -1) {
boolean mod = size % bufferSize == 0;
long readTimes = size / bufferSize;
if (mod || readTimes == 0) {
readTimes++;
}
for (int i = 0; i < readTimes; i++) {
if (readTimes == 1) {
int read = in.read(bs, 0, size);
out.write(bs, 0, read);
r += read;
} else {
int read = in.read(bs, 0, bufferSize);
if (read != -1) {
out.write(bs, 0, read);
r += read;
} else {
break;
}
}
}
} else {
int read;
while ((read = in.read(bs, 0, bufferSize)) != -1) {
out.write(bs, 0, read);
r += read;
}
}
} finally {
Streams.close(in);
client.setRestartOffset(0);
if (in != null) {
client.completePendingCommand();
}
if (close) {
Streams.close(out);
}
}
return r;
}
// -------------------- write --------------------
@Override
protected void doWrite(String path, InputStream in, StreamEntry entry) throws IOException {
this.write(path, in, entry, false);
}
// -------------------- append --------------------
@Override
protected void doAppend(String path, InputStream in, StreamEntry entry) throws IOException {
this.write(path, in, entry, true);
}
private void write(String path, InputStream in, StreamEntry entry, boolean append) throws IOException {
OutputStream out = null;
try {
out = this.openOutputStream(path, append);
if (in != null) {
byte[] bs = new byte[bufferSize];
int read;
while ((read = in.read(bs)) != -1) {
out.write(bs, 0, read);
}
} else if (entry != null) {
out.write(entry.getBytes(), entry.getOff(), entry.getLen());
}
out.flush();
} finally {
Streams.close(out);
if (out != null) {
client.completePendingCommand();
}
}
}
// -------------------- upload --------------------
@Override
public void uploadFile(String remoteFile, InputStream in, boolean close) throws IOException {
BufferedInputStream buffer = null;
try {
String parentPath = Files1.getParentPath(remoteFile);
this.makeDirectories(parentPath);
client.storeFile(this.serverCharset(config.getRemoteRootDir() + remoteFile), buffer = new BufferedInputStream(in));
} finally {
if (close) {
Streams.close(in);
Streams.close(buffer);
}
}
}
@Override
public void uploadDir(String remoteDir, String localDir, boolean child) throws IOException {
localDir = Files1.getPath(localDir);
List dirs = Files1.listDirs(localDir, child);
List files = Files1.listFiles(localDir, child);
for (File dir : dirs) {
this.makeDirectories(Files1.getPath(remoteDir, dir.getAbsolutePath().substring(localDir.length())));
}
for (File file : files) {
String path = Files1.getPath(remoteDir, file.getAbsolutePath().substring(localDir.length()));
this.change(Files1.getParentPath(path));
this.uploadFile(path, file);
}
}
// -------------------- download --------------------
@Override
public void downloadFile(String remoteFile, OutputStream out, boolean close) throws IOException {
InputStream in = null;
try {
in = this.openInputStream(remoteFile);
Streams.transfer(in, out);
} finally {
if (close) {
Streams.close(out);
}
Streams.close(in);
client.setRestartOffset(0);
if (in != null) {
client.completePendingCommand();
}
}
}
@Override
public void downloadDir(String remoteDir, String localDir, boolean child) throws IOException {
remoteDir = Files1.getPath(remoteDir);
if (!child) {
List list = this.listFiles(remoteDir, false);
for (FtpFile s : list) {
this.downloadFile(s.getPath(), Files1.getPath(localDir, Files1.getFileName(s.getPath())));
}
} else {
List list = this.listDirs(remoteDir, true);
for (FtpFile s : list) {
Files1.mkdirs(Files1.getPath(localDir, s.getPath().substring(remoteDir.length())));
}
list = this.listFiles(remoteDir, true);
for (FtpFile s : list) {
this.downloadFile(s.getPath(), Files1.getPath(localDir, s.getPath().substring(remoteDir.length())));
}
}
}
// -------------------- big file --------------------
@Override
public FtpUploader upload(String remote, String local) {
return new FtpUploader(this, remote, local);
}
@Override
public FtpUploader upload(String remote, File local) {
return new FtpUploader(this, remote, local);
}
@Override
public FtpDownloader download(String remote, String local) {
return new FtpDownloader(this, remote, local);
}
@Override
public FtpDownloader download(String remote, File local) {
return new FtpDownloader(this, remote, local);
}
// -------------------- list --------------------
@Override
public List listFilesFilter(String path, FtpFileFilter filter, boolean child, boolean dir) {
String base = config.getRemoteRootDir();
List list = new ArrayList<>();
try {
FTPFile[] files = client.listFiles(this.serverCharset(Files1.getPath(base, path)));
for (FTPFile file : files) {
String fn = file.getName();
String t = Files1.getPath(path, fn);
boolean isDir = file.isDirectory();
if (!isDir || dir) {
FtpFile f = new FtpFile(t, file);
if (filter.test(f)) {
list.add(f);
}
}
if (isDir && child) {
list.addAll(this.listFilesFilter(t + SEPARATOR, filter, true, dir));
}
}
} catch (IOException e) {
throw Exceptions.ftp(e);
}
return list;
}
}