mirror of
https://github.com/KOHGYLW/kiftd-source.git
synced 2025-01-08 12:07:47 +08:00
update to v1.2.0 初步实现了移出存储区数据功能
This commit is contained in:
parent
54dcef4979
commit
308449f770
2
TODO.txt
2
TODO.txt
@ -1,4 +1,4 @@
|
||||
kiftd项目 计划表-2024-01-13 by 青阳龙野
|
||||
kiftd项目 计划表-2024-04-03 by 青阳龙野
|
||||
|
||||
已完成 v1.0.17
|
||||
--------------
|
||||
|
@ -244,7 +244,6 @@ public class ConsoleRunner {
|
||||
private void fileSystemManagerModel() {
|
||||
Printer.instance.print("已进入文件管理功能。");
|
||||
try {
|
||||
FileNodeUtil.initNodeTableToDataBase();
|
||||
if (currentFolder == null || currentFolder.getCurrent() == null || FileSystemManager.getInstance()
|
||||
.selectFolderById(currentFolder.getCurrent().getFolderId()) == null) {
|
||||
getFolderView("root");
|
||||
@ -510,7 +509,6 @@ public class ConsoleRunner {
|
||||
private void doImport(String[] args) {
|
||||
// 针对简化命令(只有1个参数),认为要将整个ROOT导出至某位置
|
||||
try {
|
||||
FileNodeUtil.initNodeTableToDataBase();
|
||||
String importTarget;
|
||||
String importPath;
|
||||
Object path;
|
||||
@ -633,7 +631,6 @@ public class ConsoleRunner {
|
||||
private void doExport(String[] args) {
|
||||
// 针对简化命令(只有1个参数),认为要将整个ROOT导出至某位置
|
||||
try {
|
||||
FileNodeUtil.initNodeTableToDataBase();
|
||||
String exportTarget;
|
||||
String exportPath;
|
||||
Object target;
|
||||
|
@ -47,9 +47,9 @@ public class FileBlockUtil {
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>名称</h2>
|
||||
* <h2>初始化临时文件夹</h2>
|
||||
* <p>
|
||||
* 详细说明
|
||||
* 该方法用于初始化临时文件夹,如果该文件夹尚不存在则创建,否则删除其中的一切非隐藏文件(注意:该方法不会处理文件夹和其中的子文件)。
|
||||
* </p>
|
||||
*
|
||||
* @author 青阳龙野(kohgylw)
|
||||
|
@ -22,9 +22,9 @@ public class FSProgressDialog extends KiftdDynamicWindow {
|
||||
private static JButton cancel;// 取消按钮
|
||||
private static boolean listen;// 是否继续监听
|
||||
|
||||
private FSProgressDialog() {
|
||||
private FSProgressDialog(JDialog parentWindow) {
|
||||
setUIFont();// 自动设置字体大小
|
||||
(window = new JDialog(FSViewer.window, "执行中...")).setModal(true);
|
||||
(window = new JDialog(parentWindow, "执行中...")).setModal(true);
|
||||
window.setSize(380, 120);
|
||||
window.setLocation(200, 200);
|
||||
window.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
|
||||
@ -138,11 +138,12 @@ public class FSProgressDialog extends KiftdDynamicWindow {
|
||||
* 通过该方法获取一个新的进度窗口,与前几个窗口不同,每次进行进度监听操作均应获取新窗口而不能使用前一个。
|
||||
* </p>
|
||||
*
|
||||
* @param parentWindow 创建此进度窗口的父窗口对象
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @return kohgylw.kiftd.ui.module.FSProgressDialog 新的窗口对象
|
||||
*/
|
||||
protected static FSProgressDialog getNewInstance() {
|
||||
return new FSProgressDialog();
|
||||
protected static FSProgressDialog getNewInstance(JDialog parentWindow) {
|
||||
return new FSProgressDialog(parentWindow);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ import kohgylw.kiftd.server.exception.FilesTotalOutOfLimitException;
|
||||
import kohgylw.kiftd.server.exception.FoldersTotalOutOfLimitException;
|
||||
import kohgylw.kiftd.server.model.Node;
|
||||
import kohgylw.kiftd.server.util.ConfigureReader;
|
||||
import kohgylw.kiftd.server.util.FileNodeUtil;
|
||||
import kohgylw.kiftd.ui.util.FilesTable;
|
||||
import kohgylw.kiftd.util.file_system_manager.FileSystemManager;
|
||||
import kohgylw.kiftd.util.file_system_manager.pojo.Folder;
|
||||
@ -197,7 +196,7 @@ public class FSViewer extends KiftdDynamicWindow {
|
||||
} else {
|
||||
type = null;
|
||||
}
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance();
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance(window);
|
||||
Thread t = new Thread(() -> {
|
||||
fsd.show();
|
||||
});
|
||||
@ -236,7 +235,7 @@ public class FSViewer extends KiftdDynamicWindow {
|
||||
selectedNodes.add(currentView.getFiles().get(i - borderIndex).getFileId());
|
||||
}
|
||||
}
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance();
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance(window);
|
||||
Thread t = new Thread(() -> {
|
||||
fsd.show();
|
||||
});
|
||||
@ -331,7 +330,7 @@ public class FSViewer extends KiftdDynamicWindow {
|
||||
File pfOld = new File(previewFileDir, n.getFileName());
|
||||
if (!pfOld.isFile() || pfOld.delete()) {
|
||||
// 将要预览的文件导出至此文件夹内
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance();
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance(window);
|
||||
Thread t = new Thread(() -> {
|
||||
fsd.show();
|
||||
});
|
||||
@ -472,7 +471,6 @@ public class FSViewer extends KiftdDynamicWindow {
|
||||
*/
|
||||
public void show() {
|
||||
disableAllButtons();
|
||||
FileNodeUtil.initNodeTableToDataBase();
|
||||
try {
|
||||
if (currentView == null) {
|
||||
getFolderView("root");
|
||||
@ -557,7 +555,7 @@ public class FSViewer extends KiftdDynamicWindow {
|
||||
type = null;
|
||||
}
|
||||
// 打开进度提示会话框
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance();
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance(window);
|
||||
Thread t = new Thread(() -> {
|
||||
fsd.show();
|
||||
});
|
||||
|
@ -6,9 +6,12 @@ import java.awt.Dimension;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
@ -17,6 +20,7 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
@ -24,6 +28,7 @@ import kohgylw.kiftd.printer.Printer;
|
||||
import kohgylw.kiftd.server.util.ConfigureReader;
|
||||
import kohgylw.kiftd.ui.pojo.FileSystemPath;
|
||||
import kohgylw.kiftd.ui.util.PathsTable;
|
||||
import kohgylw.kiftd.util.file_system_manager.FileSystemManager;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -46,6 +51,7 @@ public class FileSystemPathViewer extends KiftdDynamicWindow {
|
||||
|
||||
private static FileSystemPathViewer fsv;// 该窗口的唯一实例
|
||||
private static List<FileSystemPath> paths;// 当前显示的视图
|
||||
private static ExecutorService worker;// 操作线程池
|
||||
private CharsetEncoder encoder;// ISO-8859-1编码器
|
||||
|
||||
// 错误提示信息
|
||||
@ -55,6 +61,7 @@ public class FileSystemPathViewer extends KiftdDynamicWindow {
|
||||
private FileSystemPathViewer() {
|
||||
encoder = Charset.forName("ISO-8859-1").newEncoder();
|
||||
setUIFont();
|
||||
worker = Executors.newSingleThreadExecutor();
|
||||
(window = new JDialog(SettingWindow.window, "管理文件系统路径")).setModal(true);
|
||||
window.setSize(600, 240);
|
||||
window.setDefaultCloseOperation(1);
|
||||
@ -64,7 +71,6 @@ public class FileSystemPathViewer extends KiftdDynamicWindow {
|
||||
Container c = window.getContentPane();
|
||||
JToolBar toolBar = new JToolBar();
|
||||
toolBar.setFloatable(false);
|
||||
// TODO 自动生成的 catch 块
|
||||
addBtn = new JButton("新建 扩展存储区[Add]");
|
||||
changeBtn = new JButton("修改路径[Change]");
|
||||
removeBtn = new JButton("移除路径[Remove]");
|
||||
@ -207,18 +213,82 @@ public class FileSystemPathViewer extends KiftdDynamicWindow {
|
||||
});
|
||||
removeBtn.addActionListener((e) -> {
|
||||
disableAllButtons();
|
||||
if (JOptionPane.showConfirmDialog(window, "确认要移除该扩展存储区么?警告:移除后,该存储区内原先存放的数据将丢失,且设置生效后不可恢复。", "移除扩展存储区",
|
||||
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
|
||||
short index = pathsTable.getSelectFileSystemIndex();
|
||||
for (int i = 0; i < SettingWindow.extendStores.size(); i++) {
|
||||
if (SettingWindow.extendStores.get(i).getIndex() == index) {
|
||||
SettingWindow.extendStores.remove(i);
|
||||
break;
|
||||
worker.execute(() -> {
|
||||
if (JOptionPane.showConfirmDialog(window, "确认要移除该扩展存储区么?警告:移除后,该存储区内原先存放的数据将丢失,且设置生效后不可恢复。", "移除扩展存储区",
|
||||
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
|
||||
short index = pathsTable.getSelectFileSystemIndex();
|
||||
for (int i = 0; i < SettingWindow.extendStores.size(); i++) {
|
||||
if (SettingWindow.extendStores.get(i).getIndex() == index) {
|
||||
final int removeItemIndex = i;// 待删除的扩展存储区索引号
|
||||
// 检查该存储区内是否存有数据
|
||||
try {
|
||||
long total = FileSystemManager.getInstance().getTotalOfNodesAtExtendStore(index);
|
||||
if (total > 0) {
|
||||
// 如果已存有数据,则询问是否需要移出
|
||||
switch (JOptionPane.showConfirmDialog(window,
|
||||
"是否立即将该存储区内的数据全部移出以便留档?注意:该操作即时生效,无论是否应用新设置均无法回退。", "移出",
|
||||
JOptionPane.YES_NO_CANCEL_OPTION)) {
|
||||
case 0:
|
||||
// 是:先执行移出操作
|
||||
JFileChooser transferDirChooer = new JFileChooser();
|
||||
transferDirChooer.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
transferDirChooer.setPreferredSize(fileChooerSize);
|
||||
transferDirChooer.setDialogTitle("请选择移出数据的保存路径...");
|
||||
if (transferDirChooer.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
File transferDir = transferDirChooer.getSelectedFile();
|
||||
FSProgressDialog fsd = FSProgressDialog.getNewInstance(window);
|
||||
Thread t = new Thread(() -> {
|
||||
fsd.show();
|
||||
});
|
||||
t.start();
|
||||
try {
|
||||
boolean r = FileSystemManager.getInstance().transferExtendStore(index,
|
||||
transferDir);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
fsd.close();
|
||||
if (r) {
|
||||
// 若所有数据移出成功,则移除指定存储区并结束流程
|
||||
SettingWindow.extendStores.remove(removeItemIndex);
|
||||
} else {
|
||||
// 若出现错误,则进行提示
|
||||
JOptionPane.showMessageDialog(window,
|
||||
"移出文件时失败,该操作已被中断,未能移出全部数据。", "错误",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
} catch (FileAlreadyExistsException e1) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
fsd.close();
|
||||
JOptionPane.showMessageDialog(window,
|
||||
"目标文件夹内存在同名文件,建议选择一个空文件夹作为移出数据的保存路径。", "错误",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// 否:直接移除指定存储区
|
||||
SettingWindow.extendStores.remove(i);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
SettingWindow.extendStores.remove(i);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
JOptionPane.showMessageDialog(window, "出现意外错误,无法统计存储区数据,请重启应用后重试。", "错误",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
e1.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
enableAllButtons();
|
||||
refresh();
|
||||
enableAllButtons();
|
||||
refresh();
|
||||
});
|
||||
});
|
||||
// 生成文件列表
|
||||
pathsTable = new PathsTable();
|
||||
@ -247,7 +317,7 @@ public class FileSystemPathViewer extends KiftdDynamicWindow {
|
||||
modifyComponentSize(window);
|
||||
}
|
||||
|
||||
// 刷新文件列表
|
||||
// 刷新列表
|
||||
private void refresh() {
|
||||
paths.clear();
|
||||
FileSystemPath mainfsp = new FileSystemPath();
|
||||
|
@ -81,9 +81,12 @@ public class FileSystemManager {
|
||||
private PreparedStatement countNodesByFolderId;
|
||||
private PreparedStatement countFoldersByParentFolderId;
|
||||
private PreparedStatement selectNodesByPathExcludeById;
|
||||
private PreparedStatement countNodesByExtendStoreIndex;
|
||||
private PreparedStatement selectNodesByExtendStoreIndex;
|
||||
|
||||
// 加载资源
|
||||
private FileSystemManager() {
|
||||
FileNodeUtil.initNodeTableToDataBase();
|
||||
Connection c = FileNodeUtil.getNodeDBConnection();
|
||||
try {
|
||||
selectFolderById = c.prepareStatement("SELECT * FROM FOLDER WHERE folder_id = ?");
|
||||
@ -103,6 +106,8 @@ public class FileSystemManager {
|
||||
countNodesByFolderId = c.prepareStatement("SELECT count(file_id) FROM FILE WHERE file_parent_folder = ?");
|
||||
countFoldersByParentFolderId = c
|
||||
.prepareStatement("SELECT count(folder_id) FROM FOLDER WHERE folder_parent = ?");
|
||||
countNodesByExtendStoreIndex = c.prepareStatement("SELECT count(file_id) FROM FILE WHERE file_path LIKE ?");
|
||||
selectNodesByExtendStoreIndex = c.prepareStatement("SELECT * FROM FILE WHERE file_path LIKE ?");
|
||||
} catch (SQLException e) {
|
||||
Printer.instance.print("错误:出现未知错误,文件系统解析失败,无法浏览文件。");
|
||||
}
|
||||
@ -988,4 +993,102 @@ public class FileSystemManager {
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>移出指定扩展存储区内的数据至指定文件夹内</h2>
|
||||
* <p>
|
||||
* 该方法会将指定扩展存储区内的文件逐一移出到指定文件夹内(注意不是复制),若全部移出成功,则原扩展存储区将被清空。
|
||||
* 该方法应作为移除某一扩展存储区前的预操作。
|
||||
* </p>
|
||||
*
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @version 1.0
|
||||
* @return boolean 若全部移出成功则返回true,否则为false
|
||||
* @throws SQLException 各种查询失败的原因
|
||||
* @throws IOException 各种移动失败的原因
|
||||
*
|
||||
*/
|
||||
public boolean transferExtendStore(short index, File reservePath) throws SQLException, IOException {
|
||||
final List<Node> nodes = selectNodesByExtendStoreIndex(index);
|
||||
int total = nodes.size();
|
||||
if (reservePath != null && reservePath.isDirectory()) {
|
||||
per = 0;
|
||||
message = "正在移出数据...";
|
||||
gono = true;
|
||||
for (int i = 0; i < total && gono; i++) {
|
||||
message = "正在移出数据(" + i + "/" + total + ")...";
|
||||
per = (int) (((double) i / total) * 100.0);
|
||||
Node n = nodes.get(i);
|
||||
File b = getFileFormBlocks(n);
|
||||
File parentFolder = new File(reservePath, getNativePath(n));
|
||||
if (!parentFolder.isDirectory()) {
|
||||
if (!parentFolder.mkdirs()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File target = new File(parentFolder, n.getFileName());
|
||||
Files.move(b.toPath(), target.toPath());
|
||||
deleteNodeById(n.getFileId());
|
||||
}
|
||||
return gono;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <h2>获取指定扩展存储区内的文件节点数量</h2>
|
||||
* <p>
|
||||
* 该方法会返回指定扩展存储区内的文件数量,以供判断在移除该扩展存储区前是否需要执行移出操作。
|
||||
* </p>
|
||||
*
|
||||
* @author 青阳龙野(kohgylw)
|
||||
* @version 1.0
|
||||
* @return int 指定扩展存储区内的文件节点数量
|
||||
* @throws SQLException 统计时发生错误
|
||||
*
|
||||
*/
|
||||
public long getTotalOfNodesAtExtendStore(short index) throws SQLException {
|
||||
return countNodesByExtendStoreIndex(index);
|
||||
}
|
||||
|
||||
private long countNodesByExtendStoreIndex(short index) throws SQLException {
|
||||
countNodesByExtendStoreIndex.setString(1, index + "\\_%");
|
||||
ResultSet rs = countNodesByExtendStoreIndex.executeQuery();
|
||||
if (rs.first()) {
|
||||
return rs.getLong(1);
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
private List<Node> selectNodesByExtendStoreIndex(short index) throws SQLException {
|
||||
selectNodesByExtendStoreIndex.setString(1, index + "\\_%");
|
||||
List<Node> nodes = new ArrayList<>();
|
||||
ResultSet rs = selectNodesByExtendStoreIndex.executeQuery();
|
||||
while (rs.next()) {
|
||||
nodes.add(resultSetAccessNode(rs));
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
// 获取一个文件节点的本地路径,例如/ROOT/foo/bar/target.txt在Windows系统下的本地路径为“ROOT\foo\bar\”
|
||||
private String getNativePath(final Node n) throws SQLException {
|
||||
List<String> parentList = new ArrayList<String>();
|
||||
Folder f = selectFolderById(n.getFileParentFolder());
|
||||
while (f != null) {
|
||||
parentList.add(f.getFolderName());
|
||||
if (f.getFolderParent().equals("null")) {
|
||||
break;
|
||||
} else {
|
||||
f = selectFolderById(f.getFolderParent());
|
||||
}
|
||||
}
|
||||
StringBuffer np = new StringBuffer();
|
||||
for (int i = parentList.size() - 1; i >= 0; i--) {
|
||||
np.append(parentList.get(i));
|
||||
np.append(File.separator);
|
||||
}
|
||||
return np.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#Generated by Maven Integration for Eclipse
|
||||
#Mon Jan 15 12:03:25 CST 2024
|
||||
#Wed Apr 03 23:36:07 CST 2024
|
||||
m2e.projectLocation=/Users/kohgylw/Programs/java_workspace/kiftd
|
||||
m2e.projectName=kiftd
|
||||
groupId=kohgylw
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user