feat: 원격 FTP 서버 파일 다운로드 기능 구현

This commit is contained in:
2026-01-05 01:12:11 +09:00
parent 93c92cb1ff
commit 4f0fd95220
3 changed files with 41 additions and 6 deletions

3
.gitignore vendored
View File

@@ -29,3 +29,6 @@ captures/
# Google Services (safety) # Google Services (safety)
/app/google-services.json /app/google-services.json
# temp
/.temp

View File

@@ -5,6 +5,7 @@ import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.net.ftp.FTPReply;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
public class FTPClientHelper { public class FTPClientHelper {
@@ -23,6 +24,7 @@ public class FTPClientHelper {
return false; return false;
} }
ftpClient.enterLocalPassiveMode(); ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
return true; return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -43,13 +45,9 @@ public class FTPClientHelper {
public FTPFile[] listFiles(String path) { public FTPFile[] listFiles(String path) {
try { try {
// First, try to change the working directory.
if (ftpClient.changeWorkingDirectory(path)) { if (ftpClient.changeWorkingDirectory(path)) {
// If successful, list files in the new directory.
return ftpClient.listFiles(); return ftpClient.listFiles();
} else { } else {
// If changing directory fails, it might be a file path, not a directory.
// Or the path is invalid. For now, we return null for simplicity.
return null; return null;
} }
} catch (IOException e) { } catch (IOException e) {
@@ -57,4 +55,14 @@ public class FTPClientHelper {
return null; return null;
} }
} }
public boolean downloadFile(String remoteFileName, OutputStream out) {
try {
// retrieveFile works on the current working directory.
return ftpClient.retrieveFile(remoteFileName, out);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
} }

View File

@@ -28,6 +28,9 @@ import androidx.recyclerview.widget.RecyclerView;
import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFile;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -118,6 +121,28 @@ public class MainActivity extends AppCompatActivity implements FileAdapter.OnIte
}).start(); }).start();
} }
private void downloadAndOpenFile(FileItem item) {
runOnUiThread(() -> Toast.makeText(this, "Downloading " + item.getName(), Toast.LENGTH_SHORT).show());
new Thread(() -> {
File localFile = new File(getCacheDir(), item.getName());
try (OutputStream out = new FileOutputStream(localFile)) {
boolean success = ftpHelper.downloadFile(item.getName(), out);
runOnUiThread(() -> {
if (success) {
Toast.makeText(this, "Download complete", Toast.LENGTH_SHORT).show();
openFile(localFile);
} else {
Toast.makeText(this, "Download failed", Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.printStackTrace();
runOnUiThread(() -> Toast.makeText(this, "Download failed: " + e.getMessage(), Toast.LENGTH_SHORT).show());
}
}).start();
}
// --- Local Storage Methods --- // --- Local Storage Methods ---
private void loadFiles(File directory) { private void loadFiles(File directory) {
this.currentDirectory = directory; this.currentDirectory = directory;
@@ -143,8 +168,7 @@ public class MainActivity extends AppCompatActivity implements FileAdapter.OnIte
if (item.isDirectory()) { if (item.isDirectory()) {
loadFtpFiles(item.getPath()); loadFtpFiles(item.getPath());
} else { } else {
// TODO: Implement file download/open for FTP downloadAndOpenFile(item);
Toast.makeText(this, "Opening remote files is not implemented yet.", Toast.LENGTH_SHORT).show();
} }
} else { } else {
File file = new File(item.getPath()); File file = new File(item.getPath());