見出し画像

Apache Commons VFS のすすめ (1)

はじめに

皆さんは、プログラム内からリモートサーバのファイルシステムにアクセスするとき、どのようにアクセスしているでしょうか?

UrlConnection を使ってリクエストとレスポンスを解析する?
対象のファイルシステムが、FTP だったら、Apache Commons Net の FtpClient を使ってアクセスすると少し楽になるかもしれませんね。

しかし、File クラスと同じような API で、リモートファイルシステムにアクセスしたいと思ったことはありませんでしょうか?

今回ご紹介する Apache Commons VFS はそんな願いを叶えるライブラリとなっています。

Apache Commons VFS とは?

Apache Commons VFS とは Commons Virtual File System といって異なるシステムを同一の API でアクセスするようにする仮想化層を提供するライブラリです。

API を通して各ファイルシステムにアクセス

FTP や HTTP、ローカルファイルシステム、Zip アーカイブ内のファイル
などを同じ API でアクセス出来ます。

デフォルトで HTTP, FTP, WebDAV など多数のファイルシステムがサポートされています。

また、Commons VFS はプロバイダーを実装することにより、新しいファイルシステムのサポートを追加することが出来ます。
追加のプロバイダーとして、Amazon S3 などのプロバイダーが外部の開発者によって実装されていたりします。

使ってみる。

Commons VFS を使用してファイルシステムにアクセスするには、FileSystemManager を取得して、その関数を使用してアクセスします。

VFS クラスにある VFS#getManager() を使用することで FileSystemManager を取得することが出来ます。

FileSystemManager manager = VFS.getManager();
FileObject file = manager.resolveFile("ftp://example.com/commons/vfs/");
// 存在の確認
if (file.exists()) {
  // 子供の取得
  for (FileObject child : file.getChildren()) {
    :
  }
}

ファイルの取得

FileSystemManager#resolveFile(String) を使用して取得します。
取得するときには、URI 形式で指定します。
FileSystemManager は URI のスキーマに対応したプロバイダーを使用して、FileObject を取得します。

FileObject file = manager.resolveFile("ftp://example.com/commons/vfs/");

取得した FileObject は以降、通常の File クラスと同じように存在するかを確認したり、子ファイルをリストしたりすることが出来ます。

ファイルの存在確認

FileObject は FileObject#exists() を使用することで、対象ファイルが存在するかどうかを確認することが出来ます。

// 存在の確認
if (file.exists()) {
  :
}

ファイルタイプ

FileObject は FileObject#getType() によってファイルタイプを取得することが出来ます。
このファイルタイプは、ファイルの種類と存在ステータスを同時に表しています。

if (file.getType() == FileType.FILE) {
  :
}

定義されているファイルタイプは以下の通り。
各タイプ毎に何が取得出来るのかが決まっています。

  • FileType.FILE
    通常のファイル
    コンテンツや属性を含んでいる場合があるが、別ファイルは含まない。

  • FileType.FOLDER
    フォルダ
    属性や別ファイルを含んでいる場合があるが、コンテンツは含まない。

  • FileType.FILE_OR_FOLDER
    ファイルかフォルダ
    コンテンツや属性、別ファイルなどを含んでいる場合がある。
    例えば、Zip ファイルなどのアーカイブファイルを通常ファイルシステムと一緒に透過的に扱うときには、アーカイブファイルは内部にファイルも含むので、ファイルであり、フォルダでもある。
    ただし、あくまで例としての話なので、現在の Commons VFS では Zip ファイルのファイルタイプを取得しても、FileType.FILE_OR_FOLDER が返ってくるわけではない。

  • FileType.IMAGINARY
    ファイルが存在しない。
    コンテンツや属性、別ファイルなどを含まない。

コンテンツの読み書き

ファイルの内容を読み書きするには、FileObject から FileContent を取得し、FileContent から InputStream や OutputStream を取得して、それに対して読み書きする形になります。

FileContent content = file.getContent();

// 読み込み
try (InputStream input = content.getInputStream()) {
  :
}

// 書き込み
try (OutputStream output = content.getOutputStream()) {
  :
}

子供一覧の取得

フォルダ内のファイルやフォルダは、FileObject#getChildren() で一覧が取得出来ます。

// 直下の子供一覧を取得する。
FileObject[] children = file.getChildren();
for (FileObject child : children) {
  :
}

サブパスのファイル取得

サブパスのファイルをピンポイントで取得するには、FileObject#resolveFile(String) を使用して取得します。
この関数では、パスを指定することで深い位置にある子ファイルを取得出来ます。

// 直下の子供
FileObject child = file.resolveFile("hoge.txt");

// パスを指定して更に深い位置にある子供も取得出来る。
FileObject nestedChild = file.resolveFile("foo/bar.png");

属性の取得/設定

対象のファイルシステムが属性をサポートしているとき、ファイルから属性を取得したり、設定したりすることが出来ます。
ただし、ファイルシステムによっては属性を取得出来ても、設定することが出来ないことがあります。

// 取得
Object value = content.getAttribute("hoge");

// 設定
content.setAttribute("hoge", value);

続きは・・・

ここまで Commons VFS の簡単な使用方法を説明してきました。
Commons VFS を使用すると、リモートファイルなどが Java の File クラスと同じようにアクセス出来ることが分かるかと思います。

次回は、もう少し踏み込んだ Commons VFS の使用方法を説明する予定です。
お楽しみに。

#プログラミング #Java #Apache #エンジニア#ITエンジニア#開発#ウイングアーク#ウイングアーク1st#テックブログ#エンジニア転職#エンジニア採用

いいなと思ったら応援しよう!