LISTORY

안드로이드와 FTP - FTP 서버 연결 코드 본문

IT/안드로이드

안드로이드와 FTP - FTP 서버 연결 코드

LiStoryTeller 2017. 5. 22. 15:21


안녕하세요. 


오늘은 안드로이드에서 FTP 서버에 접근하는 방법에 대해 다루어보겠습니다.


안드로이드 자체적인 기능으로는 FTP를 구현할 수 없습니다.


라이브러리를 사용해야 FTP 통신을 할 수 있는데,


FTP 서버에 접근하기 위해 저는 Apache의 Commons Net을 사용했습니다.


해당 내용을 정리해 놓은 포스팅입니다.


안드로이드와 FTP - Apache Commons Net




일단, 안드로이드 스튜디오에 테스트를 위한 프로젝트를 생성하겠습니다.


저는 CommonsNet이라는 프로젝트를 생성했습니다.


프로젝트를 생성하고 Apache의 Commons Net 라이브러리를 프로젝트에 추가합니다.


안드로이드 스튜디오에 라이브러리를 추가하는 방법을 정리해놓은 포스팅입니다.


안드로이드 스튜디오에 라이브러리(jar 파일) 추가




이제 새로운 클래스 ConnectFTP 를 생성하여 FTP 서버와 통신하기 위한


코드를 추가하도록 하겠습니다.




  •  클래스 상단에 변수 생성

    private final String TAG = "Connect FTP";
    public FTPClient mFTPClient = null;


FTP 라이브러리를 추가하면 FTP 관련 변수를 생성할 수 있습니다.


안드로이드를 FTP Client로 사용하는 것이므로 FTPClient 변수를 생성시켜 줍니다.




  •  생성자 추가
    public ConnectFTP(){
        mFTPClient = new FTPClient();
    }


생성자에서 mFTPClient를 초기화시켜줍니다.




  •  FTP 서버와 연결
    public boolean ftpConnect(String host, String username, String password, int port) {
        boolean result = false;
        try{
            mFTPClient.connect(host, port);

            if(FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
                result = mFTPClient.login(username, password);
                mFTPClient.enterLocalPassiveMode();
            }
        }catch (Exception e){
            Log.d(TAG, "Couldn't connect to host");
        }
        return result;
    }


FTPClient의 connect를 사용하여 클라이언트와 서버를 연결합니다.





  • FTP 서버와 연결 끊기
    public boolean ftpDisconnect() {
        boolean result = false;
        try {
            mFTPClient.logout();
            mFTPClient.disconnect();
            result = true;
        } catch (Exception e) {
            Log.d(TAG, "Failed to disconnect with server");
        }
        return result;
    }





  • 현재 작업 경로 가져오기
       public String ftpGetDirectory(){
        String directory = null;
        try{
            directory = mFTPClient.printWorkingDirectory();
        } catch (Exception e){
            Log.d(TAG, "Couldn't get current directory");
        }
        return directory;
    }




  • 작업 경로 수정
    public boolean ftpChangeDirctory(String directory) {
        try{
            mFTPClient.changeWorkingDirectory(directory);
            return true;
        }catch (Exception e){
            Log.d(TAG, "Couldn't change the directory");
        }
        return false;
    }




  • directory 내 파일 리스트 가져오기
    public String[] ftpGetFileList(String directory) {
        String[] fileList = null;
        int i = 0;
        try {
            FTPFile[] ftpFiles = mFTPClient.listFiles(directory);
            fileList = new String[ftpFiles.length];
            for(FTPFile file : ftpFiles) {
                String fileName = file.getName();

                if (file.isFile()) {
                    fileList[i] = "(File) " + fileName;
                } else {
                    fileList[i] = "(Directory) " + fileName;
                }

                i++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileList;
    }




  • 새로운 directory 생성 및 삭제
    public boolean ftpCreateDirectory(String directory) {
        boolean result = false;
        try {
            result =  mFTPClient.makeDirectory(directory);
        } catch (Exception e){
            Log.d(TAG, "Couldn't make the directory");
        }
        return result;
    }

    public boolean ftpDeleteDirectory(String directory) {
        boolean result = false;
        try {
            result = mFTPClient.removeDirectory(directory);
        } catch (Exception e) {
            Log.d(TAG, "Couldn't remove directory");
        }
        return result;
    }




  • 파일 삭제
    public boolean ftpDeleteFile(String file) {
        boolean result = false;
        try{
            result = mFTPClient.deleteFile(file);
        } catch (Exception e) {
            Log.d(TAG, "Couldn't remove the file");
        }
        return result;
    }




  • 파일 이름 변경
    public boolean ftpRenameFile(String from, String to) {
        boolean result = false;
        try {
            result = mFTPClient.rename(from, to);
        } catch (Exception e) {
            Log.d(TAG, "Couldn't rename file");
        }
        return result;
    }




  • 파일 다운로드
    public boolean ftpDownloadFile(String srcFilePath, String desFilePath) {
        boolean result = false;
        try{
            mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
            mFTPClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
            
            FileOutputStream fos = new FileOutputStream(desFilePath);
            result = mFTPClient.retrieveFile(srcFilePath, fos);
            fos.close();
        } catch (Exception e){
            Log.d(TAG, "Download failed");
        }
        return result;
    }


파일을 다운로드 하기 전에, 파일 형식과 전송 모드를 지정해줘야 합니다.


지정해 주지 않을 시, 파일이 손상되어 올 수 있습니다.




  • FTP 서버에 파일 업로드
    public boolean ftpUploadFile(String srcFilePath, String desFileName, String desDirectory) {
        boolean result = false;
        try {
            FileInputStream fis = new FileInputStream(srcFilePath);
            if(ftpChangeDirctory(desDirectory)) {
                result = mFTPClient.storeFile(desFileName, fis);
            }
            fis.close();
        } catch(Exception e){
            Log.d(TAG, "Couldn't upload the file");
        }
        return result;
    }





이제 코드에서 해당 함수들을 사용해보도록 하겠습니다.




  • FTPConnect 선언

    private ConnectFTP ConnectFTP;



  • onCreate에 초기화

        ConnectFTP = new ConnectFTP();;



  • FTP와 연결하는 Thread 생성 및 FTP 서버와 Connect

        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean status = false;
                status = ConnectFTP.ftpConnect("192.168.6.188", "user1", "wlgk2168", 21);
                if(status == true) {
                    Log.d(TAG, "Connection Success");
                }
                else {
                    Log.d(TAG, "Connection failed");
                }

                ...
            }
        }).start();



  • 현재 경로 가져오기

      new Thread(new Runnable() {
            public void run() {
                ...
                String currentPath = ConnectFTP.ftpGetDirectory();
                ...
            }
        }).start();



  • 파일 다운로드

      new Thread(new Runnable() {
            public void run() {
                ...
                String newFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FTPTest";
                File file = new File(newFilePath);
                file.mkdirs();
                newFilePath += "/image2.jpg";
                try {
                    file = new File(newFilePath);
                    file.createNewFile();
                }catch (Exception e){}

                ConnectFTP.ftpDownloadFile(currentPath + "image2.jpg", newFilePath);
                ...
            }
        }).start();


해당 코드를 실행하기 위해선 서버에 image2.jpg 파일이 존재해야 합니다.



  • 연결 끊기

      new Thread(new Runnable() {
            public void run() {
                ...
                boolean result = ConnectFTP.ftpDisconnect();
                if(result == true)
                    Log.d(TAG, "DisConnection Success");
                else
                    Log.d(TAG, "DisConnection Success");
            }
        }).start();




마지막으로, Manifest파일에 permission을 줍니다.



  • Manifest에 추가

    uses-permission android:name="android.permission.INTERNET"
    uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"





이제 프로젝트를 실행하면 logcat을 통해 FTP 서버와의 통신 여부를 확인할 수 있고,


지정된 경로에 image2가 정상적으로 저장되었는 지 확인할 수 있습니다.

















Comments