一、保存本地
io.File
这个比较常用
二、保存数据库
读取文件的byte数据,把ext,size,bytedata都保存到数据库
数据库在存储文件数据时,有两种格式:
一种是以字节存储的,二进制数据。
另一种是以字符形式存储的,如图片的base64。
数据库要存储二进制数据,其数据库的列的属性必须是二进制类型的,如MySQL中,类型为BINARY和VARBNARY的列以二进制形式存储数据。
因为二进制一般都是字节数组,所以,要使用动态的SQL语句,要执行动态的SQL语句,必须使用PerparedStatement,
它的setBytes方法给未确定部分赋字节数组值。然后调用executeUpdate方法遍完成二进制数据的写入。同样道理,要从数据库中读取二进制数据的时候,
遍历结果集调用ResultSet的getBytes方法。获得字节数组(也就是二进制数组)。
二进制数组一般存储比较大的数据,如图片,影视文件。
如果数据库列属性是Blob的,获得结果集后调用ResultSet的getBlob方法,获得Blob数据,一个java.sql.Blob对象。Blob类的getBinaryStream方法获得Blob数据的字节输入流。便可以读取Blob数据。
mssql sqlserver常见数据类型如下:
bit:整型,数据范围[0,1,null],用于存取布尔值
tinyint:整型,数据范围[0~256)
smallint:整型,数据范围[-215~215)
int:整型,数据范围[-231~231)
decimal:精确数值型 ,例:decimal(10,2); //共10位,小数点右2位
numeric:与decimal类似
smallmoney:货币型
money:货币型
float:浮点型,近似数值型
real:近似数值型
Smalldatetime:日期时间型,表示从1900年1月1日到2079年6月6日间的日期和时间,精确到分钟
datetime:日期时间型,从1753年1月1日到9999年12月31日间所有的日期和时间数据, 精确到三百分之一秒或3.33毫秒
cursor:特殊数据型,包含一个对游标的引用。用在存储过程中,创建表时不能用
timestamp:特殊数据型,系统自动的数据类型,不可以操作,当行记录被操作时,此值都会发生变化,每个数据表只允许一个此列存在
Uniqueidentifier:特殊数据型,全局唯一标识符,GUID
char:字符型,存储指定长度的定长非统一编码型的数据,必须指定列宽,列宽最大为8000 个字符
varchar:字符型,存储非统一编码型字符数据,数据类型为变长,要指定该列的最大长度,存储的长度不是列长,而是数据的长度
text:字符型,存储大量的非统一编码型字符数据
nchar:统一编码字符型,存储定长统一编码字符型数据,能存储4000种字符,统一编码用双字节结构来存储每个字符
nvarchar:统一编码字符型,用作变长的统一编码字符型数据
ntext:统一编码字符型,用来存储大量的统一编码字符型数据
binary:二进制数据类型,存储可达8000 字节长的定长的二进制数据
varbinary:二进制数据类型,用来存储可达8000 字节长的变长的二进制数据
image:二进制数据类型,用来存储变长的二进制数据
可以分析出
mssql sqlserver可存储二进制数据的数据类型为:
binary varcbinary image
三、远程服务器
设置共享服务器
开启来宾模式guest,给guest设置密码123;
cmd命令:
net user guest /active true
net user guest 123
共享一个文件夹,右键>属性>共享>共享(s),添加guest,给予'读/写'权限,点击共享;
问题:
如果不想开启guest,而用administrator或者其他用户连接共享文件夹,以上方式一般就不可以,
解决方法:
运行gpedit.msc,打开本地组策略编辑器;
计算机配置>Windows设置>安全设置>本地策略>安全选项>网络访问:本地账户的共享和安全模型;
选"经典 - 对本地用户进行身份验证,不改变其本来身份",就可以了.
为了使Windows 主机间的资源能够共享,微软于1980年开发了SMB(Server Message Block)通信协议,并通过SMB通信协议,使网络上各台主机之间能够共享文件、打印机等资源。目前类似这种资源共享的通信协议还有NFS、Appletalk、Netware等。
微软的“网上邻居(就是Windows 上利用SMB通信协议实现资源共享的程序)”一经推出,便广受用户的好评,大家突然觉得原来要在网上共享资源尽是那么简单,有鉴于此,便有一些Linux 爱好者开始在Linux 主机上实现SMB通信协议,后来这个实现了SMB功能的软件既被称为 Samba ,它使得Windows 主机和Linux主机之间实现了资源共享。
Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成。
SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务
由于Windows共享是基于NetBios协议,是基于Ethernet的广播协议,在没有透明网桥的情况下(如VPN)是不能跨网段使用的。它主要用于unix和windows系统进行文件和打印机共享
FTP
FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件
区别
ftp只能下载后修改,然后上传覆盖。smb是在线修改的。
smb只能在Windows之间共享
samba可以在Linux和Windows之间共享
1、SmbFile
引入
<dependency> <groupId>org.samba.jcifs</groupId> <artifactId>jcifs</artifactId> </dependency>
链接
// smb://guest:123@192.168.0.106/qwe/test.txt
// 协议 帐号 密码@ IP地址 共享文件夹和路径
// ps:非加密共享文件夹:smb://192.168.0.106/qwe/test.txt
SmbFile f = new SmbFile("smb://guest:123@192.168.0.106/qwe/test.txt");
读取(拿到输入流,其他操作基本和file差不多)
InputStream is = null;
if (fileName.startsWith("smb:")) {
SmbFile file = new SmbFile(fileName);
if (!file.exists()) {
return;
}
is = file.getInputStream();
}
输出
SmbFile file = new SmbFile(fileName);
OutputStream outs = new SmbFileOutputStream(file, true);
outs.write(arg.getData());
删除
if (fileName.startsWith("smb:")) {
SmbFile file = new SmbFile(fileName);
if(file.exists()){
file.delete();
}
}
重命名
SmbFile file = new SmbFile(srcFileName);
if (file.exists()) {
file.renameTo(new SmbFile(descFileName));
}
构建文件夹
SmbFile file = new SmbFile(filePath);
if (!file.exists()) {
file.mkdirs();
}
上传文件
SmbFile file = new SmbFile(ftpFileName);
if (!file.exists()) {
file.createNewFile();
}
OutputStream outs = new SmbFileOutputStream(file, true);
Files.copy(path, outs);
2、ftp
引入
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> </dependency>
链接
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ResourceBundle;
/**
* Created by Administrator on 2018/8/29 0029.
* FTP 工具类
*/
public class FTPUtil {
/**
* 连接 FTP 服务器
*
* @param addr FTP 服务器 IP 地址
* @param port FTP 服务器端口号
* @param username 登录用户名
* @param password 登录密码
* @return
* @throws Exception
*/
public static FTPClient connectFtpServer(String addr, int port, String username, String password, String controlEncoding) {
FTPClient ftpClient = new FTPClient();
try {
/**设置文件传输的编码*/
ftpClient.setControlEncoding(controlEncoding);
/**连接 FTP 服务器
* 如果连接失败,则此时抛出异常,如ftp服务器服务关闭时,抛出异常:
* java.net.ConnectException: Connection refused: connect*/
ftpClient.connect(addr, port);
/**登录 FTP 服务器
* 1)如果传入的账号为空,则使用匿名登录,此时账号使用 "Anonymous",密码为空即可*/
if (StringUtils.isBlank(username)) {
ftpClient.login("Anonymous", "");
} else {
ftpClient.login(username, password);
}
/** 设置传输的文件类型
* BINARY_FILE_TYPE:二进制文件类型
* ASCII_FILE_TYPE:ASCII传输方式,这是默认的方式
* ....
*/
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
/**
* 确认应答状态码是否正确完成响应
* 凡是 2开头的 isPositiveCompletion 都会返回 true,因为它底层判断是:
* return (reply >= 200 && reply < 300);
*/
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
/**
* 如果 FTP 服务器响应错误 中断传输、断开连接
* abort:中断文件正在进行的文件传输,成功时返回 true,否则返回 false
* disconnect:断开与服务器的连接,并恢复默认参数值
*/
ftpClient.abort();
ftpClient.disconnect();
} else {
}
} catch (IOException e) {
e.printStackTrace();
System.out.println(">>>>>FTP服务器连接登录失败,请检查连接参数是否正确,或者网络是否通畅*********");
}
return ftpClient;
}
/**
* 使用完毕,应该及时关闭连接
* 终止 ftp 传输
* 断开 ftp 连接
*
* @param ftpClient
* @return
*/
public static FTPClient closeFTPConnect(FTPClient ftpClient) {
try {
if (ftpClient != null && ftpClient.isConnected()) {
ftpClient.abort();
ftpClient.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
return ftpClient;
}
public static void main(String[] args) throws Exception {
System.out.println("-----------------------应用启动------------------------");
FTPClient ftpClient = FTPUtil.connectFtpServer("192.168.1.20", 21, "ftpChina", "ftpChina123456", "gbk");
System.out.println("FTP 连接是否成功:" + ftpClient.isConnected());
System.out.println("FTP 连接是否有效:" + ftpClient.isAvailable());
closeFTPConnect(ftpClient);
System.out.println("-----------------------应用关闭------------------------");
}
}
单文件下载
1、FTP 客户端从 FTP 服务器下载文件,必须确保 FTP 服务器给登录用户提供了"读取"权限
/**
* 下载 FTP 服务器上指定的单个文件,而且本地存放的文件相对部分路径 会与 FTP 服务器结构保持一致
*
* @param ftpClient :连接成功有效的 FTP客户端连接
* @param absoluteLocalDirectory :本地存储文件的绝对路径,如 E:\gxg\ftpDownload
* @param relativeRemotePath :ftpFile 文件在服务器所在的绝对路径,此方法强制路径使用右斜杠"\",如 "\video\2018.mp4"
* @return
*/
public static void downloadSingleFile(FTPClient ftpClient, String absoluteLocalDirectory, String relativeRemotePath) {
/**如果 FTP 连接已经关闭,或者连接无效,则直接返回*/
if (!ftpClient.isConnected() || !ftpClient.isAvailable()) {
System.out.println(">>>>>FTP服务器连接已经关闭或者连接无效*********");
return;
}
if (StringUtils.isBlank(absoluteLocalDirectory) || StringUtils.isBlank(relativeRemotePath)) {
System.out.println(">>>>>下载时遇到本地存储路径或者ftp服务器文件路径为空,放弃...*********");
return;
}
try {
/**没有对应路径时,FTPFile[] 大小为0,不会为null*/
FTPFile[] ftpFiles = ftpClient.listFiles(relativeRemotePath);
FTPFile ftpFile = null;
if (ftpFiles.length >= 1) {
ftpFile = ftpFiles[0];
}
if (ftpFile != null && ftpFile.isFile()) {
/** ftpFile.getName():获取的是文件名称,如 123.mp4
* 必须保证文件存放的父目录必须存在,否则 retrieveFile 保存文件时报错
*/
File localFile = new File(absoluteLocalDirectory, relativeRemotePath);
if (!localFile.getParentFile().exists()) {
localFile.getParentFile().mkdirs();
}
OutputStream outputStream = new FileOutputStream(localFile);
String workDir = relativeRemotePath.substring(0, relativeRemotePath.lastIndexOf("\\"));
if (StringUtils.isBlank(workDir)) {
workDir = "/";
}
/**文件下载前,FTPClient工作目录必须切换到文件所在的目录,否则下载失败
* "/" 表示用户根目录*/
ftpClient.changeWorkingDirectory(workDir);
/**下载指定的 FTP 文件 到本地
* 1)注意只能是文件,不能直接下载整个目录
* 2)如果文件本地已经存在,默认会重新下载
* 3)下载文件之前,ftpClient 工作目录必须是下载文件所在的目录
* 4)下载成功返回 true,失败返回 false
*/
ftpClient.retrieveFile(ftpFile.getName(), outputStream);
outputStream.flush();
outputStream.close();
System.out.println(">>>>>FTP服务器文件下载完毕*********" + ftpFile.getName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
System.out.println("-----------------------应用启动------------------------");
FTPClient ftpClient = FTPUtil.connectFtpServer("192.168.1.20", 21, "ftpChina", "ftpChina123456", "gbk");
downloadSingleFile(ftpClient, "E:\\gxg\\ftpDownload", "\\1.png");
downloadSingleFile(ftpClient, "E:\\gxg\\ftpDownload", "\\xml\\schedule.xml");
closeFTPConnect(ftpClient);
System.out.println("-----------------------应用关闭------------------------");
}
文件目录下载
1、下载整个目录,包括所有子孙目录下的文件,实质也是遍历目录下的文件逐个下载,然后调用上面下载单个文件的方法进行下载
/**
* 遍历 FTP 服务器指定目录下的所有文件(包含子孙文件)
*
* @param ftpClient :连接成功有效的 FTP客户端连接
* @param remotePath :查询的 FTP 服务器目录,如果文件,则视为无效,使用绝对路径,如"/"、"/video"、"\\"、"\\video"
* @param relativePathList :返回查询结果,其中为服务器目录下的文件相对路径,如:\1.png、\docs\overview-tree.html 等
* @return
*/
public static List<String> loopServerPath(FTPClient ftpClient, String remotePath, List<String> relativePathList) {
/**如果 FTP 连接已经关闭,或者连接无效,则直接返回*/
if (!ftpClient.isConnected() || !ftpClient.isAvailable()) {
System.out.println("ftp 连接已经关闭或者连接无效......");
return relativePathList;
}
try {
/**转移到FTP服务器根目录下的指定子目录
* 1)"/":表示用户的根目录,为空时表示不变更
* 2)参数必须是目录,当是文件时改变路径无效
* */
ftpClient.changeWorkingDirectory(remotePath);
/** listFiles:获取FtpClient连接的当前下的一级文件列表(包括子目录)
* 1)FTPFile[] ftpFiles = ftpClient.listFiles("/docs/info");
* 获取服务器指定目录下的子文件列表(包括子目录),以 FTP 登录用户的根目录为基准,与 FTPClient 当前连接目录无关
* 2)FTPFile[] ftpFiles = ftpClient.listFiles("/docs/info/springmvc.txt");
* 获取服务器指定文件,此时如果文件存在时,则 FTPFile[] 大小为 1,就是此文件
* */
FTPFile[] ftpFiles = ftpClient.listFiles();
if (ftpFiles != null && ftpFiles.length > 0) {
for (FTPFile ftpFile : ftpFiles) {
if (ftpFile.isFile()) {
String relativeRemotePath = remotePath + "\\" + ftpFile.getName();
relativePathList.add(relativeRemotePath);
} else {
loopServerPath(ftpClient, remotePath + "\\" + ftpFile.getName(), relativePathList);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return relativePathList;
}
public static void main(String[] args) throws Exception {
System.out.println("-----------------------应用启动------------------------");
FTPClient ftpClient = FTPUtil.connectFtpServer("192.168.1.20", 21, "ftpChina", "ftpChina123456", "gbk");
List<String> relativePathList = new ArrayList<>();
relativePathList = loopServerPath(ftpClient, "\\video", relativePathList);
for (String relativePath : relativePathList) {
System.out.println("准备下载的服务器文件:" + relativePath);
downloadSingleFile(ftpClient, "E:\\gxg\\ftpDownload", relativePath);
}
/* downloadSingleFile(ftpClient, "E:\\gxg\\ftpDownload", "\\1.png");
downloadSingleFile(ftpClient, "E:\\gxg\\ftpDownload", "\\xml\\schedule.xml");*/
closeFTPConnect(ftpClient);
System.out.println("-----------------------应用关闭------------------------");
}
上传文件/目录
1、上传文件时可以直接使用 API 上传,上传目录时只能遍历文件逐个上传
/**
* 上传本地文件 或 目录 至 FTP 服务器----保持 FTP 服务器与本地 文件目录结构一致
*
* @param ftpClient 连接成功有效的 FTPClinet
* @param uploadFile 待上传的文件 或 文件夹(此时会遍历逐个上传)
* @throws Exception
*/
public static void uploadFiles(FTPClient ftpClient, File uploadFile) {
/**如果 FTP 连接已经关闭,或者连接无效,则直接返回*/
if (!ftpClient.isConnected() || !ftpClient.isAvailable()) {
System.out.println(">>>>>FTP服务器连接已经关闭或者连接无效*****放弃文件上传****");
return;
}
if (uploadFile == null || !uploadFile.exists()) {
System.out.println(">>>>>待上传文件为空或者文件不存在*****放弃文件上传****");
return;
}
try {
if (uploadFile.isDirectory()) {
/**如果被上传的是目录时
* makeDirectory:在 FTP 上创建目录(方法执行完,服务器就会创建好目录,如果目录本身已经存在,则不会再创建)
* 1)可以是相对路径,即不以"/"开头,相对的是 FTPClient 当前的工作路径,如 "video"、"视频" 等,会在当前工作目录进行新建目录
* 2)可以是绝对路径,即以"/"开头,与 FTPCLient 当前工作目录无关,如 "/images"、"/images/2018"
* 3)注意多级目录时,必须确保父目录存在,否则创建失败,
* 如 "video/201808"、"/images/2018" ,如果 父目录 video与images不存在,则创建失败
* */
ftpClient.makeDirectory(uploadFile.getName());
/**变更 FTPClient 工作目录到新目录
* 1)不以"/"开头表示相对路径,新目录以当前工作目录为基准,即当前工作目录下不存在此新目录时,变更失败
* 2)参数必须是目录,当是文件时改变路径无效*/
ftpClient.changeWorkingDirectory(uploadFile.getName());
File[] listFiles = uploadFile.listFiles();
for (int i = 0; i < listFiles.length; i++) {
File loopFile = listFiles[i];
if (loopFile.isDirectory()) {
/**如果有子目录,则迭代调用方法进行上传*/
uploadFiles(ftpClient, loopFile);
/**changeToParentDirectory:将 FTPClient 工作目录移到上一层
* 这一步细节很关键,子目录上传完成后,必须将工作目录返回上一层,否则容易导致文件上传后,目录不一致
* */
ftpClient.changeToParentDirectory();
} else {
/**如果目录中全是文件,则直接上传*/
FileInputStream input = new FileInputStream(loopFile);
ftpClient.storeFile(loopFile.getName(), input);
input.close();
System.out.println(">>>>>文件上传成功****" + loopFile.getPath());
}
}
} else {
/**如果被上传的是文件时*/
FileInputStream input = new FileInputStream(uploadFile);
/** storeFile:将本地文件上传到服务器
* 1)如果服务器已经存在此文件,则不会重新覆盖,即不会再重新上传
* 2)如果当前连接FTP服务器的用户没有写入的权限,则不会上传成功,但是也不会报错抛异常
* */
ftpClient.storeFile(uploadFile.getName(), input);
input.close();
System.out.println(">>>>>文件上传成功****" + uploadFile.getPath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
System.out.println("-----------------------应用启动------------------------");
FTPClient ftpClient = FTPUtil.connectFtpServer("192.168.1.20", 21, "ftpChina", "ftpChina123456", "gbk");
uploadFiles(ftpClient, new File("E:\\gxg\\datas"));
closeFTPConnect(ftpClient);
System.out.println("-----------------------应用关闭------------------------");
}
文件/目录同步
1、保持本地文件与 FTP 服务器文件内容一致,本地客户端以 FTP 服务器为准。
/**
* 同步本地目录与 FTP 服务器目录
* 1)约定:FTP 服务器有,而本地没有的,则下载下来;本地有,而ftp服务器没有的,则将本地多余的删除
* 2)始终确保本地与 ftp 服务器内容一致
* 2)让 FTP 服务器与 本地目录保持结构一致,如 服务器上是 /docs/overview-tree.html,则本地也是 localDir/docs/overview-tree.html
*
* @param ftpClient 连接成功有效的 FTPClinet
* @param localSyncFileDir :与 FTP 目录进行同步的本地目录
*/
public static void syncLocalDir(FTPClient ftpClient, String localSyncFileDir) throws IOException {
/**如果 FTP 连接已经关闭,或者连接无效,则直接返回*/
if (!ftpClient.isConnected() || !ftpClient.isAvailable() || StringUtils.isBlank(localSyncFileDir)) {
System.out.println(">>>>>FTP服务器连接已经关闭或者连接无效*********");
return;
}
/** 获取本地存储目录下的文件*/
Collection<File> fileCollection = FileWmxUtil.localListFiles(new File(localSyncFileDir));
System.out.println(">>>>>本地存储目录共有文件数量*********" + fileCollection.size());
/**获取 FTP 服务器下的相对路径*/
List<String> relativePathList = new ArrayList<>();
relativePathList = loopServerPath(ftpClient, "", relativePathList);
System.out.println(">>>>>FTP 服务器端共有文件数量*********" + relativePathList.size());
/**
* 遍历 本地存储目录下的文件
* 1)如果本地文件在 FTP 服务器上不存在,则删除它
* 2)如果本地文件在 FTP 服务器上存在,则比较两种大小
* 如果大小不一致,则重新下载
*/
for (File localFile : fileCollection) {
String localFilePath = localFile.getPath();
String localFileSuffi = localFilePath.replace(localSyncFileDir, "");
if (relativePathList.contains(localFileSuffi)) {
/**本地此文件在 FTP 服务器存在
* 1)比较大小,如果本地文件与服务器文件大小一致,则跳过
* 2)如果大小不一致,则删除本地文件,重新下载
* 3)最后都要删除relativePathList中的此元素,减轻后一次循环的压力*/
FTPFile[] ftpFiles = ftpClient.listFiles(localFileSuffi);
System.out.println(">>>>>本地文件 在 FTP 服务器已存在*********" + localFile.getPath());
if (ftpFiles.length >= 1 && localFile.length() != ftpFiles[0].getSize()) {
downloadSingleFile(ftpClient, localSyncFileDir, localFileSuffi);
System.out.println(">>>>>本地文件与 FTP 服务器文件大小不一致,重新下载*********" + localFile.getPath());
}
relativePathList.remove(localFileSuffi);
} else {
System.out.println(">>>>>本地文件在 FTP 服务器不存在,删除本地文件*********" + localFile.getPath());
/**本地此文件在 FTP 服务器不存在
* 1)删除本地文件
* 2)如果当前文件所在目录下文件已经为空,则将此父目录也一并删除*/
localFile.delete();
File parentFile = localFile.getParentFile();
while (parentFile.list().length == 0) {
parentFile.delete();
parentFile = parentFile.getParentFile();
}
}
}
for (int i = 0; i < relativePathList.size(); i++) {
System.out.println(">>>>> FTP 服务器存在新文件,准备下载*********" + relativePathList.get(i));
downloadSingleFile(ftpClient, localSyncFileDir, relativePathList.get(i));
}
}
public static void main(String[] args) throws Exception {
System.out.println("-----------------------应用启动------------------------");
FTPClient ftpClient = FTPUtil.connectFtpServer("192.168.1.20", 21, "ftpChina", "ftpChina123456", "gbk");
syncLocalDir(ftpClient,"E:\\gxg\\ftpDownload");
closeFTPConnect(ftpClient);
System.out.println("-----------------------应用关闭------------------------");
}
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
/**
* Created by Administrator on 2018/8/30 0030.
* 自定义文件工具类
*/
public class FileWmxUtil {
public static void main(String[] args) {
File fileDir = new File("E:\\gxg\\resources\\docs");
}
/**
* 遍历目录下的所有文件--方式1
*
* @param targetDir
*/
public static Collection<File> localListFiles(File targetDir) {
Collection<File> fileCollection = new ArrayList<>();
if (targetDir != null && targetDir.exists() && targetDir.isDirectory()) {
/**
* targetDir:不要为 null、不要是文件、不要不存在
* 第二个 文件过滤 参数如果为 FalseFileFilter.FALSE ,则不会查询任何文件
* 第三个 目录过滤 参数如果为 FalseFileFilter.FALSE , 则只获取目标文件夹下的一级文件,而不会迭代获取子文件夹下的文件
*/
fileCollection = FileUtils.listFiles(targetDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
}
return fileCollection;
}
}
删除文件/目录
1、如果登录账号拥有写的权限,则可以上传文件、修改文件、删除文件。
2、当是目录时会迭代进行删除
/**
* 删除服务器的文件
*
* @param ftpClient 连接成功且有效的 FTP客户端
* @param deleteFiles 待删除的文件或者目录,为目录时,会逐个删除,
* 路径必须是绝对路径,如 "/1.png"、"/video/3.mp4"、"/images/2018"
* "/" 表示用户根目录,则删除所有内容
*/
public static void deleteServerFiles(FTPClient ftpClient, String deleteFiles) {
/**如果 FTP 连接已经关闭,或者连接无效,则直接返回*/
if (!ftpClient.isConnected() || !ftpClient.isAvailable()) {
System.out.println(">>>>>FTP服务器连接已经关闭或者连接无效*****放弃文件上传****");
return;
}
try {
/** 尝试改变当前工作目录到 deleteFiles
* 1)changeWorkingDirectory:变更FTPClient当前工作目录,变更成功返回true,否则失败返回false
* 2)如果变更工作目录成功,则表示 deleteFiles 为服务器已经存在的目录
* 3)否则变更失败,则认为 deleteFiles 是文件,是文件时则直接删除
*/
boolean changeFlag = ftpClient.changeWorkingDirectory(deleteFiles);
if (changeFlag) {
/**当被删除的是目录时*/
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile ftpFile : ftpFiles) {
System.out.println("----------------::::" + ftpClient.printWorkingDirectory());
if (ftpFile.isFile()) {
boolean deleteFlag = ftpClient.deleteFile(ftpFile.getName());
if (deleteFlag) {
System.out.println(">>>>>删除服务器文件成功****" + ftpFile.getName());
} else {
System.out.println(">>>>>删除服务器文件失败****" + ftpFile.getName());
}
} else {
/**printWorkingDirectory:获取 FTPClient 客户端当前工作目录
* 然后开始迭代删除子目录
*/
String workingDirectory = ftpClient.printWorkingDirectory();
deleteServerFiles(ftpClient, workingDirectory + "/" + ftpFile.getName());
}
}
/**printWorkingDirectory:获取 FTPClient 客户端当前工作目录
* removeDirectory:删除FTP服务端的空目录,注意如果目录下存在子文件或者子目录,则删除失败
* 运行到这里表示目录下的内容已经删除完毕,此时再删除当前的为空的目录,同时将工作目录移动到上移层级
* */
String workingDirectory = ftpClient.printWorkingDirectory();
ftpClient.removeDirectory(workingDirectory);
ftpClient.changeToParentDirectory();
} else {
/**deleteFile:删除FTP服务器上的文件
* 1)只用于删除文件而不是目录,删除成功时,返回 true
* 2)删除目录时无效,方法返回 false
* 3)待删除文件不存在时,删除失败,返回 false
* */
boolean deleteFlag = ftpClient.deleteFile(deleteFiles);
if (deleteFlag) {
System.out.println(">>>>>删除服务器文件成功****" + deleteFiles);
} else {
System.out.println(">>>>>删除服务器文件失败****" + deleteFiles);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
System.out.println("-----------------------应用启动------------------------");
FTPClient ftpClient = FTPUtil.connectFtpServer("192.168.1.20", 21, "ftpChina", "ftpChina123456", "gbk");
deleteServerFiles(ftpClient,"/datas");
closeFTPConnect(ftpClient);
System.out.println("-----------------------应用关闭------------------------");
}