Java 列出文件、目录、子文件和;ftp服务器中无递归的子目录
我试图在ftp服务器中生成给定目录及其子目录的文件列表。 服务器工作正常,我已经成功地生成了当前目录的文件列表。当我试图列出子目录及其文件时,问题变得复杂起来。我被要求不要使用递归算法,所以我自己做了一些研究。我尝试过使用线程(对于找到的每个目录,启动一个新线程),但我无法保持连接的稳定和打开。关于如何正确地使用线程或其他替代方法,您有什么想法吗 编辑:下面是我的代码,当使用递归语句(代码的最后一行)时,它可以工作Java 列出文件、目录、子文件和;ftp服务器中无递归的子目录,java,ftp,java-threads,Java,Ftp,Java Threads,我试图在ftp服务器中生成给定目录及其子目录的文件列表。 服务器工作正常,我已经成功地生成了当前目录的文件列表。当我试图列出子目录及其文件时,问题变得复杂起来。我被要求不要使用递归算法,所以我自己做了一些研究。我尝试过使用线程(对于找到的每个目录,启动一个新线程),但我无法保持连接的稳定和打开。关于如何正确地使用线程或其他替代方法,您有什么想法吗 编辑:下面是我的代码,当使用递归语句(代码的最后一行)时,它可以工作 class TEST { public static sy
class TEST {
public static synchronized void main(String[] args) {
String server = args[0]; //server,path will be given as an arguements
String pass = "SOMEPASS";
String user = "SOMEUSER";
int port = 21;
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
showServerReply(ftpClient);
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.println("Connect failed");
return;
}
boolean success = ftpClient.login(user, pass);
showServerReply(ftpClient);
if (!success) {
System.out.println("Could not login to the server");
return;
}
/*START THE FILE LISTING HERE*/
} catch (IOException ex) {
System.out.println("Oops! Something wrong happened");
ex.printStackTrace();
} finally {
// logs out and disconnects from server
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static void showServerReply(FTPClient ftpClient) {
String[] replies = ftpClient.getReplyStrings();
if (replies != null && replies.length > 0) {
for (String aReply : replies) {
System.out.println("SERVER: " + aReply);
}
}
}
private static void scanDir(FTPClient client, String path) throws IOException {
FTPFile[] files = client.listFiles(path); // Search all the files in the current directory
for (int j = 0; j < files.length; j++) {
System.out.println(files[j].getName()); // Print the name of each files
}
FTPFile[] directories = client.listDirectories(path); // Search all the directories in the current directory
for (int i = 0; i < directories.length; i++) {
String dirPath = directories[i].getName();
System.out.println(dirPath); // Print the path of a sub-directory
scanDir(client,dirPath); // Call recursively the method to display the files in the sub-directory DONT WANT TO DO THAT...
}
}
}
类测试{
公共静态同步void main(字符串[]args){
字符串server=args[0];//服务器,路径将作为参数给定
字符串pass=“SOMEPASS”;
字符串user=“SOMEUSER”;
int端口=21;
FTPClient FTPClient=新的FTPClient();
试一试{
ftpClient.connect(服务器、端口);
showServerReply(ftpClient);
int replyCode=ftpClient.getReplyCode();
如果(!FTPReply.isPositiveCompletion(replyCode)){
System.out.println(“连接失败”);
返回;
}
布尔成功=ftpClient.login(用户,通过);
showServerReply(ftpClient);
如果(!成功){
System.out.println(“无法登录到服务器”);
返回;
}
/*从这里开始列出文件*/
}捕获(IOEX异常){
System.out.println(“哎呀!发生了什么错误”);
例如printStackTrace();
}最后{
//注销并断开与服务器的连接
试一试{
如果(ftpClient.isConnected()){
ftpClient.logout();
ftpClient.disconnect();
}
}捕获(IOEX异常){
例如printStackTrace();
}
}
}
私有静态void showServerReply(FTPClient FTPClient){
字符串[]答复=ftpClient.getReplyStrings();
如果(回复!=null&&replements.length>0){
for(字符串aReply:答复){
System.out.println(“服务器:+aReply”);
}
}
}
私有静态void scanDir(FTPClient客户端,字符串路径)引发IOException{
FTPFile[]files=client.listFiles(path);//搜索当前目录中的所有文件
对于(int j=0;j
好的,下面是一个如何非递归地处理它的示例,但是使用列表
请注意,这个示例是基于/访问本地文件系统的,但是可以很容易地为任何类型的层次/递归结构重写/扩展
package stackoverflow.nonrecursivefilesearch;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.stream.Stream;
public class NonRecursiveFileSearch {
public static void main(final String[] args) throws IOException {
final File searchDir = new File("D:\\test\\maven-test"); // set one
System.out.println("\nOld Java");
printDirs(listFiles_old(searchDir, true, true), "OLD: Depth first, include dirs");
printDirs(listFiles_old(searchDir, true, false), "OLD: Breadth first, include dirs");
printDirs(listFiles_old(searchDir, false, true), "OLD: Depth first, exclude dirs");
printDirs(listFiles_old(searchDir, false, false), "OLD: Breadth first, exclude dirs");
System.out.println("\nNew java.io with streams");
printDirs(listFiles_newIO(searchDir, true), "Java NIO, include dirs");
printDirs(listFiles_newIO(searchDir, false), "Java NIO, exclude dirs");
}
/**
* this is the way to 'manually' find files in hierarchial/recursive structures
*
* reminder: "Depth First" is not a real depth-first implementation
* real depth-first would iterate subdirs immediately.
* this implementation iterates breadth first, but descends into supdirs before it handles same-level directories
* advantage of this implementation is its speed, no need for additional lists etc.
*
* in case you want to exclude recursion traps made possible by symbolic or hard links, you could introduce a hashset/treeset with
* visited files (use filename strings retrieved with canonicalpath).
* in the loop, check if the current canonical filename string is contained in the hash/treeset
*/
static public ArrayList<File> listFiles_old(final File pDir, final boolean pIncludeDirectories, final boolean pDepthFirst) {
final ArrayList<File> found = new ArrayList<>();
final ArrayList<File> todo = new ArrayList<>();
todo.add(pDir);
while (todo.size() > 0) {
final int removeIndex = pDepthFirst ? todo.size() - 1 : 0;
final File currentDir = todo.remove(removeIndex);
if (currentDir == null || !currentDir.isDirectory()) continue;
final File[] files = currentDir.listFiles();
for (final File file : files) {
if (file.isDirectory()) {
if (pIncludeDirectories) found.add(file);
// additional directory filters go here
todo.add(file);
} else {
// additional file filters go here
found.add(file);
}
}
}
return found;
}
static private void printDirs(final ArrayList<File> pFiles, final String pTitle) {
System.out.println("====================== " + pTitle + " ======================");
for (int i = 0; i < pFiles.size(); i++) {
final File file = pFiles.get(i);
System.out.println(i + "\t" + file.getAbsolutePath());
}
System.out.println("============================================================");
}
/**
* this is the java.nio approach. this is NOT be a good solution for cases where you have to retrieve/handle files in your own code.
* this is only useful, if the any NIO class provides support. in this case, NIO class java.nio.file.Files helps handling local files.
* if NIO or your target system does not offer such helper methods, this way is harder to implement, as you have to set up the helper method yourself.
*/
static public Stream<Path> listFiles_newIO(final File pDir, final boolean pIncludeDirectories) throws IOException {
final Stream<Path> stream = Files.find(pDir.toPath(), 100,
(path, basicFileAttributes) -> {
final File file = path.toFile(); // conversion to File for easier access (f.e. isDirectory()), could also use NIO methods
return (pIncludeDirectories || !file.isDirectory() /* additional filters go here */ );
});
return stream;
}
static private void printDirs(final Stream<Path> pStream, final String pTitle) {
System.out.println("====================== " + pTitle + " ======================");
pStream.forEach(System.out::println);
System.out.println("============================================================");
}
}
package stackoverflow.nonrecursivefilesearch;
导入java.io.File;
导入java.io.IOException;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.util.ArrayList;
导入java.util.stream.stream;
公共类非递归文件搜索{
公共静态void main(最终字符串[]args)引发IOException{
final File searchDir=新文件(“D:\\test\\maven test”);//设置一个
System.out.println(“\nOld Java”);
printDirs(listFiles_old(searchDir,true,true),“old:Depth first,include dirs”);
printDirs(listFiles_old(searchDir,true,false),“old:width first,include dirs”);
printDirs(listFiles_old(searchDir,false,true),“old:Depth-first,exclude-dirs”);
printDirs(listFiles_old(searchDir,false,false),“old:width-first,exclude-dirs”);
System.out.println(“\nNew java.io with streams”);
printDirs(listFiles_newIO(searchDir,true),“javanio,include dirs”);
printDirs(listFiles_newIO(searchDir,false),“Java NIO,排除dirs”);
}
/**
*这是在层次/递归结构中“手动”查找文件的方法
*
*提醒:“深度优先”不是真正的深度优先实现
*真正的深度优先将立即迭代子曲面。
*这个实现首先迭代广度,但在处理同一级别的目录之前,它会下降到supdirs
*这种实现的优点是速度快,不需要额外的列表等。
*
*如果您想排除符号链接或硬链接可能造成的递归陷阱,您可以使用
*访问的文件(使用canonicalpath检索的文件名字符串)。
*在循环中,检查当前规范文件名字符串是否包含在hash/treeset中
*/
静态公共ArrayList listFiles_old(最终文件pDir、最终布尔PincludeDirectory、最终布尔pDepthFirst){
找到的最终ArrayList=新ArrayList();
最终ArrayList todo=新ArrayList();
todo.add(pDir);
while(todo.size()>0){
final int removeIndex=pDepthFirst?todo.size()-1:0;
最终文件currentDir=todo.remove(removeIndex);
如果(currentDir==null | |!currentDir.isDirectory())继续;
最终文件[]文件=currentDir.listFiles();
用于(最终文件:文件){
if(file.isDirectory()){
如果找到(PincludeDirectory)。添加(文件);