1. VFS 相關(VirtualFileSystem)
1.1 VFS作用:
- 提供一個處理檔案的通用API,而不關心檔案的具體位置(無論檔案位於磁碟上、歸檔檔案中還是HTTP伺服器上)
- 追蹤檔案變化,並且在檢測到檔案內容發生更改時能提供新舊兩個版本的檔案
- 建立檔案在VFS和持久化儲存之間的關聯
1.2. VFS中獲取VirtualFile
- 從本地IO檔案中獲取
File ioFile = new File("./io.java")
VritualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile)
virtualFile.refresh(false, true)
複製程式碼
- 利用FileChooser獲取
FileChooserDescriptor singleFileDescriptor = FileChooserDescriptorFactory.createSingleFileDescriptor();
VirtualFile virtualFile = FileChooser.chooseFile(singleFileDescriptor, project, null);
複製程式碼
- 通過URL獲取
VirtualFileManager.getInstance().findFileByUrl("xxx");
VirtualFileManager.getInstance().refreshAndFindFileByUrl("xxx");
複製程式碼
1.3對VirtualFile進行讀寫操作
和Android一樣,Intellij Platform不允許直接在主執行緒進行實時的檔案寫入,需要通過一個非同步任務進行。
WriteCommandAction.runWriteCommandAction(project, new Runnable() {
@Override
public void run() {
// virtualFile.getInputStream() / virtualFile.getOutputStream()
}
});
複製程式碼
1.4 在非同步任務結束後,切回UI執行緒進行UI更新
ApplicationManager.getApplication().invokeLater(new Runnable(){
...
})
複製程式碼
2. PSI相關(Program Structure Interface)
2.1 PSI介紹
PSI(Program Structure Interface)是Intellij Platform中一個非常重要的概念,在IDE所管理的Project中,每個目錄,Package,原始碼和資原始檔都會被抽象成相應的PSI物件。
2.2 常用子類
PsiDirectory、PsiJavaFile和XmlFile
2.3 建立目錄和檔案
//建立目錄
PsiDirectory baseDir = PsiDirectoryFactory.getInstance(project).createDirectory(project.getBaseDir());
//建立Java檔案
PsiJavaFile psiFile = (PsiJavaFile) PsiFileFactory.getInstance(project).createFileFromText("", StdFileTypes.JAVA, "");
//建立Xml檔案
XmlFile psiFile = (XmlFile) PsiFileFactory.getInstance(project).createFileFromText("", StdFileTypes.XML, "");
複製程式碼
2.4 讀寫檔案
和寫入VirtualFile一樣,讀寫操作都需要在WriteCommandAction非同步執行緒中進行。
2.5 Xml檔案寫入屬性
XmlDocument document = xmlFile.getDocument();
if (document != null && document.getRootTag() != null) {
XmlTag rootTag = document.getRootTag();
rootTag.getAttribute(attrName).setValue(attrValue);//set value for exists attr.
rootTag.setAttribute(name,value);//add a new attr and setting value
}
複製程式碼
2.6 搜尋檔案
// 方法一:(全類名)
JavaPsiFacade.getInstance(mFile.getProject()).findClass(qualifiedName,GlobalSearchScope.alScope(mFile.getProject()));
// 方法二: (全類名)
FilenameIndex.getFilesByName()
// 方法三: (短類名)
PsiShortNamesCache.getInstance().getClassesByName()
複製程式碼
2.7 建立Class檔案類
PsiClass clazz = JavaDirectoryService.getInstance().createClass(subDir, className)
複製程式碼
2.8 修改Class內容
// 建立Class元素生成器
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mFile.getProject());
// 利用生成器建立對應的元素(每種元素都對應兩種生成方式)
elementFactory.createField() / elementFactory.createFieldFromText()
elementFactory.createMethod() / elementFactory.createMethodFromText()
elementFactory.createClass() / elementFactory.createClassFromText()
...
//將元素新增到class中
clazz.add(field)
複製程式碼
2.9 修改class的繼承關係
respClass.getExtendsList().add(getReferenceClass(elementFactory, BaseModelStr));
複製程式碼
3.0 修改元素(class field method)的修飾關鍵字(public static ... )
// 新增
respClass.getModifierList().add(elementFactory.createKeyword("public"));
// 刪除
reqClass.getModifierList().getFirstChild().delete();
複製程式碼
3. PSI 與 VFS的聯絡
// VirtualFile 轉 PsiFile
PsiManager.getInstance(project).findFile(virtualFile);
// PsiFile 轉 VirtualFile
VirtualFile virtualFile = psiFile.getVirtualFile();
複製程式碼
4 其他常用方法
// 格式化程式碼
CodeStyleManager.getInstance(project).reformat(psiClass);
// 用編輯器開啟指定檔案
FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, virtualFile), true);
複製程式碼