Posted at

Eclipseプラグイン開発でのパス取得とかファイル操作とかのやり方

More than 3 years have passed since last update.

Eclipseのプラグイン開発における小ネタ。


ファイル操作

プラグイン開発ではjava.io.Fileを使わずに、IFileの実装クラスであるorg.eclipse.core.internal.resources.Fileのインスタンスを作成して操作する。

// ワークスペースのルートを取得して、プロジェクトのファイルのFileインスタンスを作成する。

IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IFile scopeFile = root.getFile(new Path("/RemoteSystemsTempFiles/tempFileName"));

ちなみにgetFileに渡すPathは、プロジェクト名とリソース名を含んでいないと、以下のエラーになる。

java.lang.IllegalArgumentException: Path must include project and resource name: /tempFileName

at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63)
at org.eclipse.core.internal.resources.Workspace.newResource(Workspace.java:2137)
at org.eclipse.core.internal.resources.Container.getFile(Container.java:208)
<ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/tempFileName"));の実行箇所>


具体例

例えば、アクティブなエディタのプロジェクトルートを取得し、その配下のファイル情報を作成する場合は、以下のようなコードになる。

// アクティブエディタ(編集中のファイル)の情報を取得する。

IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IEditorPart editor = window.getActivePage().getActiveEditor();
ITextEditor textEditor = (ITextEditor)editor;

// エディタ情報をもとに、編集中のファイルが属するプロジェクト情報を取得する。
IFileEditorInput editorInput = (IFileEditorInput)textEditor.getEditorInput();
IFile file = editorInput.getFile();
IProject project = file.getProject();

// プロジェクトのフルパスに、取得したいファイルのプロジェクトルートからの相対パスを追加して、
// ファイル情報を取得する。
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IPath path = project.getFullPath().append("tempFileName");
IFile file = root.getFile(path);


パスの操作

Pathインスタンスにパスを追加する場合はappendメソッドを使う。

ただし、StringBuilderのappendなどとは違い、appendメソッドが返すのは新規Pathインスタンスなので、呼ぶだけでは情報が捨てられてしまう。

逆に削除する場合はremoveLastSegmentsメソッドを使う。

合わせたサンプルは以下。

// 同一階層の別ファイルにパスを変更

IPath newPath = path.removeLastSegments(1).append("otherFileName");


ファイルの作成、更新、削除

上記手順でFileインスタンスは取得できたので、それに対して作成等の操作を行うサンプルは以下。

try (InputStream in = new ByteArrayInputStream("hoge".getBytes())){

if (file.exists()) {
// 上書き
file.setContents(in, true, true, null);
} else {
// 新規作成
file.create(in, true, null);
}

// 削除
file.delete(false, null);

} catch (CoreException | IOException e) {
e.printStackTrace();
}


importとライブラリ


import文

今回の実装を記述した場合に書くimport文は以下。

import org.eclipse.core.resources.IFile;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;


依存解決

plugin.xmlを「プラグインのマニフェスト・エディター」で開き、依存解決タブに以下を追加する。

※最小バージョンを指定する必要はない。


  • org.eclipse.ui

  • org.eclipse.core.runtime

  • org.eclipse.core.resources

  • org.eclipse.jdt.core

  • org.eclipse.ui.ide

  • org.eclipse.ui.editors

  • org.eclipse.jface.text


結局わからなかったこと

以下は結局わからなかった。


workspace直下にフォルダ、ファイルを作成する方法

先に触れている通り、getFileはプロジェクト名とリソース名を指定していなければエラーとなるため、ワークスペース直下にフォルダやファイルを作成する方法がわからなかった。

以下のようにするとワークスペース配下にプロジェクトとしてフォルダを作成することはできるが・・・

// ワークスペースにRemoteSystemsTempFilesを作成する

IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject("RemoteSystemsTempFiles");
if (!project.exists()) {
try {
project.create(null);
} catch (CoreException e) {
e.printStackTrace();
}
}

どうしたらいいのだろうか。