iLEDについて

Javaサンプル

Netbeans

Libre Office Basicマクロ

その他


Author of This Site:
M. Kom. (kom9kmail@gmail.com)
Spam対策のため@マークは全角になっていますから、メール送信時には半角にしてください。

Java ソースコード FTPgui.java

FTPクライアントを実装するJavaプログラミングの参考ソースコード。

FTPサーバーURL、ユーザ名、パスワードを入力後、「接続」jButtonConnectボタンによりサーバーに接続する。
「一覧」ボタンjButtonNLSTでサーバー内のファイル一覧表示、
「PWD」ボタンjButtonPWDで現在のディレクトリ表示、
「CWD」ボタンjButtonCWDで、CWD移動先ディレクトリjTextCWD内に指定されているディレクトリへ移動、
親ディレクトリに戻るときは、「..」を指定すればよい。
「送信」ボタンjButtonSendで、FileChooserダイアログが表示され、選択したファイルをサーバーに送信する。
「受信」ボタンjButtonReceiveで「受信ファイル名」jTextReceiveFileに指定されたサーバー内のファイルをこちらへ受信。
「切断」ボタンjButtonDisconでFTPサーバーとの接続を切断します。

それぞれのコマンド送信後にサーバーからのレスポンスメッセージをjTextAreaLogに表示していきます。

java01.phpで、ごく基本的なFTP送信のみの処理を示しましたが、アクセスログを見るとアクセスが非常に多いようなので、 送受信両方に加えファイルリスト表示やPWD、CWDコマンドまで実装しました。実際に試してみる際にはPassiveモードでないと インターネット上の本物のFTPサーバーで試してみることができない(場合がほとんど)ので、Passiveモード固定としました。
Passiveモードでのデータリンクのしかたなどじっくり検討して、理解してみてください。
例によって、NetBeansで作成したソースファイルの、人間が入力した部分のみを掲載します。 各コンポーネント名がわかっていれば問題ありませんよね。
なお、通信が行われない状態でしばらくするとFTPサーバーは接続を自動的に切断します。切断に気づかず「あれ、エラーだ。」と慌てないでください。


TCP/IPソケットプログラミング Java編
↑この本はJavaの通信プログラムの基本理解に手頃です。あまり厚くないのでとっつきやすい。
/**
 *
 * @author Kom. of sys9.org
 */

import java.io.*;
import java.net.Socket;
import java.util.*;
import javax.swing.JFileChooser;

public class FTPgui extends javax.swing.JFrame {
  Socket  socket ;
  private BufferedWriter bufWriter ;  // コントロールチャンネル用出力ストリーム
  private BufferedReader bufReader ;  // コントロールチャンネル用入力ストリーム
  private InputStream inpStream  = null;
  private InputStreamReader inpStreamRd = null;
  private static final String BR = System.getProperty("line.separator");
  
  public FTPgui() {
    initComponents();
  }

  private void jButtonConnectActionPerformed(java.awt.event.ActionEvent evt) {
    try  {
      connect();
    } catch (IOException e) {
        System.err.println("IOException: " + e);
    }
  }                                              

    private void jButtonNLSTActionPerformed(java.awt.event.ActionEvent evt) {
    try  {
      getFileList();
    } catch (IOException e) {
      System.err.println("IOException: " + e);
    }        
    }                                           

    private void jButtonDisconActionPerformed(java.awt.event.ActionEvent evt) {
        
    try  {
      disconnect();
    } catch (IOException e) {
      System.err.println("IOException: " + e);
    }         
    
    }                                             

    private void jButtonPWDActionPerformed(java.awt.event.ActionEvent evt) {
     try  {
      pwd();
    } catch (IOException e) {
      System.err.println("IOException: " + e);
    }         
    }                                          

    private void jButtonSendActionPerformed(java.awt.event.ActionEvent evt) { 
     File file=null;
    JFileChooser filechooser = new JFileChooser("c:\\");
    int selected = filechooser.showOpenDialog(this);
    if (selected == JFileChooser.APPROVE_OPTION){
      file = filechooser.getSelectedFile();
      try  {
        sendFile(file);
      } catch (IOException e) {
        System.err.println("IOException: " + e);
      }         
    }else if (selected == JFileChooser.CANCEL_OPTION){
      //Cansel
    }else if (selected == JFileChooser.ERROR_OPTION){
      //Error
    }
    }                                           

    private void jButtonReceiveActionPerformed(java.awt.event.ActionEvent evt) {
    if(!jTextReceiveFile.getText().equals("")){
      try  {
        receiveFile(jTextReceiveFile.getText());
      } catch (IOException e) {
        System.err.println("IOException: " + e);
      }
    }
    }                                              

    private void jButtonCWDActionPerformed(java.awt.event.ActionEvent evt) {
    //ディレクトリ移動。親ディレクトリに移動するときは「..」を
    //指定すればよい。
    if(!jTextCWD.getText().equals("")){
      try  {
        cwd();
      } catch (IOException e) {
        System.err.println("IOException: " + e);
      }
    }
    }                                          

  private void connect() throws IOException
  {
    //サーバー接続用ソケット作成
    socket = new Socket( jTextServerAdrs.getText(),
        Integer.valueOf(jTextServerPort.getText())) ;
    //入出力ストリーム作成
    inpStream  = socket.getInputStream();
        inpStreamRd =new InputStreamReader(inpStream);
        bufReader = new BufferedReader(inpStreamRd);
    
    bufWriter = new BufferedWriter(
          new OutputStreamWriter(socket.getOutputStream() ) ) ;
    
    //レスポンスコード保持用
    String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        if (!response.startsWith("220 ")) {
            throw new IOException(
        "レスポンスコードが正しい値ではありません。: " + response);
        }
    sendLine("USER " + jTextUser.getText());
        
        response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        if (!response.startsWith("331 ")) {
            throw new IOException(
        "USERに対してのレスポンスコードが正しい値ではありません。: " 
            + response);
        }
        
    char[] password = jPassField.getPassword();
    String passStr = new String(password);
    sendLine("PASS " + passStr);
    response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        if (!response.startsWith("230 ")) {
      throw new IOException(
        "PASSに対してのレスポンスコードが正しい値ではありません。: " 
            + response);
    }
  }

  public synchronized void disconnect() throws IOException {
    try {
      sendLine("QUIT");
      String response = bufReader.readLine();
      jTextAreaLog.append(response+BR);
    }
    finally {
      socket = null;
    }
    }
  
  private void sendLine(String line) throws IOException {
    //1行送信をbufWriterに行う。
        if (socket == null) {
      jTextAreaLog.append("未接続です。"+BR);
            throw new IOException("未接続です。");
        }
        try {
            bufWriter.write(line +BR);
            bufWriter.flush();
        }
        catch (IOException e) {
            socket = null;
            throw e;
        }
    }
  
  private void receiveFile(String fname)  throws IOException {
    //ファイルを受信する。いまどきPORTモードしか使えないサーバーは
    //ないだろうから、PASSIVEモード固定。
    sendLine("PASV");
    String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
    if (!response.startsWith("227 ")) {
      throw new IOException("Passiveモードが利用できません。: " + response);
    }

    //サーバーからのレスポンスメッセージを解析し、
    //データコネクション用ポートを計算
    String ip = null;
    int port = -1;
    int opening = response.indexOf('(');
    int closing = response.indexOf(')', opening + 1);
    if (closing > 0) {
      String dataLink = response.substring(opening + 1, closing);
      StringTokenizer tokenizer = new StringTokenizer(dataLink, ",");
      try {
        ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + 
            "." + tokenizer.nextToken() + "." + tokenizer.nextToken();
        port = Integer.parseInt(tokenizer.nextToken()) * 256 + 
            Integer.parseInt(tokenizer.nextToken());
      }
      catch (Exception e) {
        throw new IOException(
          "データコネクション情報が正しく受信できません。: " 
              + response);
      }
    }    
    Socket dataSocket = new Socket(ip, port);
    
    sendLine("RETR "+ fname);
    response = bufReader.readLine();
    jTextAreaLog.append(response+BR);    
    int readLength = 0;
    BufferedInputStream bufIn = 
      new BufferedInputStream(dataSocket.getInputStream());
    BufferedOutputStream bufOut =
      new BufferedOutputStream(new FileOutputStream("c:\\"+fname)); 
    byte[] buffer = new byte[4096];
    int bytesRead = 0;
    while ((bytesRead = bufIn.read(buffer)) != -1) {
      bufOut.write(buffer, 0, bytesRead);
    }
    bufOut.flush();
    bufOut.close();    
    bufIn.close();

    response = bufReader.readLine();
    jTextAreaLog.append(response+BR);    
    return;
  }
  
  
  private boolean sendFile(File file) throws IOException {
    //ファイルを送信する。いまどきPORTモードしか使えないサーバーは
    //ないだろうから、PASSIVEモード固定。
    String filename = file.getName();
    BufferedInputStream bufIn = 
      new BufferedInputStream(new FileInputStream(file));
    sendLine("PASV");
    String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
    if (!response.startsWith("227 ")) {
      throw new IOException("Passiveモードが利用できません。: " 
          + response);
    }

    //サーバーからのレスポンスメッセージを解析し、
    //データコネクション用ポートを計算
    String ip = null;
    int port = -1;
    int opening = response.indexOf('(');
    int closing = response.indexOf(')', opening + 1);
    if (closing > 0) {
      String dataLink = response.substring(opening + 1, closing);
      StringTokenizer tokenizer = new StringTokenizer(dataLink, ",");
      try {
        ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + 
          "." + tokenizer.nextToken() + "." + tokenizer.nextToken();
        port = Integer.parseInt(tokenizer.nextToken()) * 256 + 
          Integer.parseInt(tokenizer.nextToken());
      }
      catch (Exception e) {
        throw new IOException(
          "データコネクション情報が正しく受信できません。: " 
              + response);
      }
    }
    sendLine("STOR " + filename);
    Socket dataSocket = new Socket(ip, port);
    response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
    if (!response.startsWith("150 ")) {
      throw new IOException("ファイル送信ができません。: " 
          + response);
    }
    BufferedOutputStream bufOut = 
      new BufferedOutputStream(dataSocket.getOutputStream());
    byte[] buffer = new byte[4096];
    int bytesRead = 0;
    while ((bytesRead = bufIn.read(buffer)) != -1) {
      bufOut.write(buffer, 0, bytesRead);
    }
    bufOut.flush();
    bufOut.close();
    dataSocket.close();
    bufIn.close();
    response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
    return response.startsWith("226 ");//226ならば正常に終了
    }

  public String pwd() throws IOException {
        //PWDコマンドを送信し、response文字列を返す。
    sendLine("PWD");
        String dir = null;
        String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        if (response.startsWith("257 ")) {
      // ダブルクォートを取り除く
      int beginIdx = response.indexOf("\"");
      int endIdx  = response.indexOf("\"", beginIdx + 1);
      String result = response.substring(beginIdx + 1, endIdx);
      dir = response;
        }
        return dir;
    }

    public String cwd() throws IOException {
        //CWDコマンドを送信し、response文字列を返す。
    sendLine("CWD "+jTextCWD.getText());
        String dir = null;
        String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        if (response.startsWith("250 ")) {
      // ダブルクォートを取り除く
      int beginIdx = response.indexOf("\"");
      int endIdx  = response.indexOf("\"", beginIdx + 1);
      String result = response.substring(beginIdx + 1, endIdx);
      dir = response;
        }
        return dir;
    }

  public boolean setBin() throws IOException {
        sendLine("TYPE I");
        String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        return (response.startsWith("200 "));
    }
  
  public boolean setAscii() throws IOException {
        sendLine("TYPE A");
        String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
        return (response.startsWith("200 "));
    }
  
  private String[] getFileList() throws IOException {
    //ファイルリストの入ったString型配列を返す。
    //現バージョンではこの配列は使っていない。
    Vector flist_array = new Vector();
    sendLine("PASV");
    String response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
    if (!response.startsWith("227 ")) {
      throw new IOException("Passiveモードが利用できません。: " 
          + response);
    }    
    String ip = null;
    int port = -1;
    int opening = response.indexOf('(');
    int closing = response.indexOf(')', opening + 1);
    if (closing > 0) {
      String dataLink = response.substring(opening + 1, closing);
      StringTokenizer tokenizer = new StringTokenizer(dataLink, ",");
      try {
        ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + 
          "." + tokenizer.nextToken() + "." + tokenizer.nextToken();
        port = Integer.parseInt(tokenizer.nextToken()) * 256 + 
          Integer.parseInt(tokenizer.nextToken());
      }
      catch (Exception e) {
        throw new IOException(
          "データコネクション情報が正しく受信できません。: " + response);
      }
    }
    //NLSTを使用すると、ファイル(ディレクトリ)名のみが得られる。
    //LISTを使用すると
    //    drwxr-xr-x 1 ftp ftp              0 Jul 12 12:47 Windows
    //    -rw-r--r-- 1 ftp ftp            471 Jul 10 13:32 arr.txt
    //のような形でパーミッションやタイムスタンプを含む全ての情報が得られる。
    //FTPクライアントソフトとしてファイラ機能を充実させるならば、
    //この情報を分解してJTableなどの中に表示する。
    //  if(buf.startsWith("d")){
    //     <ディレクトリとしての処理>
    //  }
    //のように。
    
    //sendLine("NLST -alL");
    sendLine("LIST");
    Socket dataSocket = new Socket(ip, port);
    response = bufReader.readLine();
    jTextAreaLog.append(response+BR);
    if (!response.startsWith("150 ")) {//not Connection Accepted
      throw new IOException("データリンクソケット接続ができません。: "
         + response);
    }
    try{
      BufferedReader reader = new BufferedReader(
        new InputStreamReader(dataSocket.getInputStream()));
      // リストの取得
      String buf;
      while((buf = reader.readLine()) != null)
      {
        jTextAreaLog.append(buf+BR);
        flist_array.add(buf);
      }
      // ストリームを閉じる
      reader.close();    
      response = bufReader.readLine();
      jTextAreaLog.append(response+BR);
    }
    catch(Exception e){
      throw new IOException("ファイルリスト取得に失敗。");
    }

    String[] result = new String[flist_array.size()];
    flist_array.toArray(result);    
    return result;
  }
    
}

動作画面例

fig

FTP in Java Sample

Kom., 2013