じぶんメモ

プログラミングのメモ、日常のメモとか。

コマンドプロンプトでgrep

コマンドプロンプトgrepするならfindstr

Windowsコマンドプロンプトgrepと同じことをしたい。
findstrコマンドが良さげ。

findstr [オプション]  "検索対象文字列" "検索対象のファイル"

以下よく使いそうなオプション

デフォルトでは正規表現での検索をしてくれないので、/Rオプションを使用する。

/I 大文字小文字を区別しない
/S ディレクトリを再帰的に検索する
/R 正規表現を使用する
/C 空白を含む文字を検索する場合に指定する
/N 一致した行数を表示
/V 指定した文字を含まない行をすべて表示

使用例

カレントディレクトリ以下で、”This is〜"という文字が含まれている箇所をresult.txtに出力する。

findstr /R /S  /C "This is.*" * > result.txt

JavaでのZipファイル作成

JavaでのZipファイル作成方法を調査した。 一例なので、他の方法もあるかも。
肝心なのは、ZipArchiveOutputStreamのflush()を使用して、1ファイルずつZipに書き込んでいるところ。
flushを使わず、全てのファイルをメモリに格納し、 Zipを生成すると、
OutOfMemoryExceptionが発生する可能性がある。

public String downloadZip() throws Exception {
    //対象年月のFileオブジェクト取得
    File downloadTargetDir = new File("/var/local/testDir/");

    ByteArrayOutputStream zipBAOS = new ByteArrayOutputStream();
    ZipArchiveOutputStream zipArchiveOS = new ZipArchiveOutputStream(zipBAOS);

    // ヘッダー情報設定
    try {
        this.response.setHeader("Content-Transfer-Encoding", "binary");
        this.response.setHeader("Content-Type", "application/zip;charset=UTF-8");
        this.response.setHeader("Content-Disposition", "attachment; filename=\"" + "test.zip" + "\"");
        this.response.setHeader("Cache-Control", "private");
        this.response.setHeader("Pragma", "private");

        // ディレクトリを圧縮
        this.recursiveArchive(outZip, downloadTargetDir);

    } catch ( Exception e ) {
        // ZIP圧縮失敗
        e.printStackTrace();
        throw new Exception(e);
        
    } finally {
        // ZIPエントリクローズ
        try { outZip.closeArchiveEntry(); } catch (Exception e) {}
        try { outZip.close(); } catch (Exception e) {}
        try { zipBAOS.close(); } catch (Exception e) {}
    }
}

/**
 * ディレクトリ圧縮のための再帰処理
 *
 * @param outZip ZipOutputStream
 * @param targetFile File 圧縮したいファイル
 * @param parentFilepath String
 */
private void recursiveArchive(ZipArchiveOutputStream outZip, File targetFile) {
    if ( targetFile.isDirectory() ) {
        File[] files = targetFile.listFiles();
        
        for (File file : files) {
            if ( file.isDirectory() ) {
                recursiveArchive(outZip, file, parentFilepath);
            } else {
                String entryName = file.getName();
                // 圧縮処理
                archive(outZip, file, entryName);
            }
        }
    }
}

/**
 * 圧縮処理
 * @param outZip ZipOutputStream
 * @param targetFile 圧縮したいファイル
 * @param entryName 保存ファイル名
 * @return
 */
private boolean archive(ZipArchiveOutputStream outZip, File targetFile, String entryName) {

    // 圧縮レベル設定
    outZip.setLevel(5);

    try {
        // ZIPエントリ作成
        outZip.putArchiveEntry(new ZipArchiveEntry(entryName));
        // 圧縮ファイル読み込みストリーム取得
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(targetFile));

        // 圧縮ファイルをZIPファイルに出力
        int size = 0;
        //byte buffer[] = new byte[1024]; // 読み込みバッファ
        byte[] bff = new byte[1024];
        while ((size = in.read(bff, 0, bff.length)) != -1) {
            outZip.write(bff, 0, size);
        }
        in.close();
        outZip.closeArchiveEntry();

        try {
            outZip.flush();             
        } catch (Exception e) {
        }            
        
    } catch ( Exception e ) {
        // ZIP圧縮失敗
        return false;
    }
    return true;
}

Javaでのファイル出力(Struts2)

JavaStruts2でファイル出力をする方法を調査した。 OutputStreamWriterを使用し、responseにByteArrayOutputStreamから変換したByteArrayInputStreamを設定する。

@Result(name="success",   value  = "inputStream",
                     params = { "inputName",          "inputStream",
                                "contentType",        "application/octet-stream; charset=UTF-8", 
                                "contentLength",      "${contentLength}",
                                "contentDisposition", "attachment; filename=${fileName}" },
                                 type   = StreamResult.class)

public class WriteAtion {
  /** HTTPレスポンス */
  private HttpServletResponse response;  
  /** ファイルダウンロード用InputStream */
  private InputStream inputStream;
  /** ダウンロードファイル名 */
  private String fileName;
  /** ダウンロードファイルサイズ */
  private long contentLength;


  public String writeFile() {
      // SJISでのファイル出力
      ByteArrayOutputStream stream = null;
      OutputStreamWriter writer = null;

      try {
          stream = new ByteArrayOutputStream();
          writer = new OutputStreamWriter(stream, "SJIS");

          // レコード出力
          String fileText = "1行目";
          writer.write(fileText);
          fileText = "2行目";
          writer.write(fileText);

          writer.close();

      } catch (UnsupportedEncodingException e) {
          return "ERROR";
      } catch (IOException e) {
          return "ERROR";
      } finally {
          IOUtils.closeQuietly(writer);
      }

      // ブラウザへのレスポンス処理
      // ファイル名をセット
      this.setFileName("test.txt");
      // ファイルサイズをフィールドに格納
      this.setContentLength(stream.toByteArray().length);
      // コンテンツタイプをフィールドに格納
      this.setContentType("text/txt");
      // ファイルストリームをフィールドに格納
      this.setInputStream(new ByteArrayInputStream(stream.toByteArray()));
      // ブラウザキャッシュ対策
      this.response.setHeader("Cache-Control", "private");
      this.response.setHeader("Pragma", "private");

      return "SUCCESS";
  }

  /**
   * HTTPレスポンスを取得します。
   * @return HTTPレスポンス
   */
  public HttpServletResponse getResponse() {
      return response;
  }
  /**
   * HTTPレスポンスを設定します。
   * @param response HTTPレスポンス
   */
  public void setResponse(HttpServletResponse response) {
      this.response = response;
  }

  /**
   * ファイルダウンロード用InputStreamを取得します。
   * @return ファイルダウンロード用InputStream
   */
  public InputStream getInputStream() {
    return inputStream;
  }

  /**
   * ファイルダウンロード用InputStreamを設定します。
   * @param inputStream ファイルダウンロード用InputStream
   */
  public void setInputStream(InputStream inputStream) {
    this.inputStream = inputStream;
  }

  /**
   * ダウンロードファイル名を取得します。
   * @return ダウンロードファイル名
   */
  public String getFileName() {
    return fileName;
  }

  /**
   * ダウンロードファイル名を設定します。
   * @param fileName ダウンロードファイル名
   */
  public void setFileName(String fileName) {
    this.fileName = fileName;  
  }

  /**
   * ダウンロードファイルサイズを取得します。
   * @return ダウンロードファイルサイズ
   */
  public long getContentLength() {
    return contentLength;
  }

  /**
   * ダウンロードファイルサイズを設定します。
   * @param contentLength ダウンロードファイルサイズ
   */
  public void setContentLength(long contentLength) {
    this.contentLength = contentLength;
  }

}

tomcat起動スクリプトを自作する

tomcat起動法

CentOStomcatを起動すると、以下の場所に起動シェルスクリプトが生成される。
(環境によって違うかも)

/usr/local/tomcat/bin/startup.sh 

これを実行すればtomcatが起動されるが、面倒なのでservice tomcat startで起動できるようにする。

起動スクリプトファイルの作成

まずはファイルの作成。

vi /etc/rc.d/init.d/tomcat

ファイルに以下の内容を作成。

#!/bin/bash
# Startup script for the Tomcat Servlet Container
#
# chkconfig: 2345 35 65

export LANG=ja_JP.UTF-8

TOMCAT_HOME=/usr/local/tomcat
LOCKFILE=/var/lock/subsys/tomcat

# source function library
. /etc/rc.d/init.d/functions

start(){
    # ロックファイルがなければ起動を開始する
    if [ ! -f ${LOCKFILE} ]; then
        echo "Starting tomcat"
        #sudo -u tomcat ${TOMCAT_HOME}/bin/startup.sh
        ${TOMCAT_HOME}/bin/startup.sh
        sleep 1
        PID=`ps -ef | grep catalina.home=${TOMCAT_HOME} | grep -v grep | awk '{print $2}'`
        echo ${PID} > ${LOCKFILE}
    else
        echo "tomcat is already running"
    fi
}

stop(){
    if [ -f ${LOCKFILE} ]; then
        echo "Shutting down tomcat"
        #sudo -u tomcat ${TOMCAT_HOME}/bin/shutdown.sh
        ${TOMCAT_HOME}/bin/shutdown.sh
        echo "Shutted down tomcat"
        rm -f ${LOCKFILE}
    else
        echo "tomcat is not running"
    fi
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    status)
        #${TOMCAT_HOME}/bin/catalina.sh version
        if [ -f ${LOCKFILE} ]
        then
          echo "tomcat(pid:"`cat ${LOCKFILE}`") is running."
        else
          echo "tomcat is not running."
        fi
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status}"
esac

exit 0

TOMCAT_HOMEとLOCKFILEの場所は環境によって変えること。 あとは起動ファイルに権限を付与し、chkconfigをonにすればサーバー起動時に自動的にtomcatが起動される。

sudo chmod 755 /etc/rc.d/init.d/tomcat
sudo chkconfig tomcat on

使用方法は以下の通り

sudo service tomcat start
sudo service tomcat stop
sudo service tomcat restart
sudo service tomcat status

Javaでファイルダウンロード

Javaでファイルをダウンロードする方法について調査した。
ファイルをBufferedInputStreamにし、viewへのリターン時にアノテーションでパラメータとして設定する。
以下Struts2を使用した実装例。

 

@Result(name="success",   value  = "inputStream",
                     params = { "inputName",          "inputStream",
                                "contentType",        "application/octet-stream; charset=UTF-8", 
                                "contentLength",      "${contentLength}",
                                "contentDisposition", "attachment; filename=${fileName}" },
                                 type   = StreamResult.class)

public class DownloadAtion {
  /** ファイルダウンロード用InputStream */
  private InputStream inputStream;
  /** ダウンロードファイル名 */
  private String fileName;
  /** ダウンロードファイルサイズ */
  private long contentLength;

  public String download() throws Exception {
    String sampleFilePath = "/usr/local/files/test.txt";
    File downloadFile = new File(sampleFilePath);

    // ファイルが存在し、ディレクトリで場合にダウンロードを行う。
    if (downloadFile.exists() && !downloadFile.isDirectory()) {
      try {
        // ダウンロード用にinputStream化する。
        inputStream = new BufferedInputStream(new FileInputStream(sampleFilePath));
        // ファイル名
        fileName = URLEncoder.encode(downloadFile.getName(), "UTF-8");fileName = URLEncoder.encode(downloadFile.getName(), "UTF-8");
        // ファイルのバイト数
        contentLength = downloadFile.length();
    
        return "success";
      } catch (Exception e) {
        return "error";
      }
    }

    // ファイルが存在しないか、パスがファイルでない場合はエラーを返す。
    return "error";
  }

  /**
   * ファイルダウンロード用InputStreamを取得します。
   * @return ファイルダウンロード用InputStream
   */
  public InputStream getInputStream() {
    return inputStream;
  }

  /**
   * ファイルダウンロード用InputStreamを設定します。
   * @param inputStream ファイルダウンロード用InputStream
   */
  public void setInputStream(InputStream inputStream) {
    this.inputStream = inputStream;
  }

  /**
   * ダウンロードファイル名を取得します。
   * @return ダウンロードファイル名
   */
  public String getFileName() {
    return fileName;
  }

  /**
   * ダウンロードファイル名を設定します。
   * @param fileName ダウンロードファイル名
   */
  public void setFileName(String fileName) {
    this.fileName = fileName;  
  }

  /**
   * ダウンロードファイルサイズを取得します。
   * @return ダウンロードファイルサイズ
   */
  public long getContentLength() {
    return contentLength;
  }

  /**
   * ダウンロードファイルサイズを設定します。
   * @param contentLength ダウンロードファイルサイズ
   */
  public void setContentLength(long contentLength) {
    this.contentLength = contentLength;
  }

}

Javaでのファイルの存在チェック

File.exists()がよさげ。

    // 同名のファイルが存在する場合はシステム日付をファイル名に付与
    File file = new File(uploadDir + uploadFileName);

    if (file.exists()){
        System.out.print("ファイルあるよー");
    }