话说long long ago,在本人开发项目时,需要导入一个文件夹(目录)下的文件,通过解析其中的数据并入库。
选择一个文件目录,好像没有这个控件。开始想到了不选目录,选文件。但是要选多个文件哦,而且数目不固定。
用file文件浏览不好,想到了用swfUpload可以选择多个文件。可以做到,但是还是选择文件不是选择目录。
不过我想要的,想呀想的……
诶~可以用ExtJS,自己扩展一个还是可以的。于是就有了今天这篇文章和这个文件浏览器。
extFileBrowser.html
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>Ext 文件浏览选择器</title>
- <meta http-equiv="author" content="hoojo">
- <meta http-equiv="email" content="hoojo_@126.com">
- <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo">
- <meta http-equiv="ext-lib" content="v2.2.1">
- <meta http-equiv="version" content="v1.0">
- <meta http-equiv="content-type" content="text/html; charset=gbk">
- <link rel="stylesheet" type="text/css" href="ext-2.2/resources/css/ext-all.css" />
- <script type="text/javascript" src="ext-2.2/adapter/ext/ext-base.js"></script>
- <script type="text/javascript" src="ext-2.2/ext-all.js"></script>
- <script type="text/javascript" src="Ext.hoo.component.FileBrowserComponent.js"></script>
- <script type="text/javascript">
- Ext.onReady(function(){
- Ext.BLANK_IMAGE_URL = "ext-2.2/resources/images/default/s.gif";
- var fileBrowser = new Ext.hoo.component.FileBrowserWindow();
- //var fileBrowser = new Ext.hoo.component.FileBrowserPanel();
- fileBrowser.show();
- fileBrowser.tree.getSelectionModel().on("beforeselect", function (sm, node) {
- //只能选择文件夹,如果要选择文件修改这里即可
- var flag = ((!node || (!!node && !!node.leaf)) || !(node.attributes.path.indexOf(":") != -1)) ? true : false;
- fileBrowser.buttons[0].setDisabled(flag);
- fileBrowser.buttons[1].setDisabled(flag);
- }, fileBrowser.tree);
- });
- </script>
- </head>
- <body>
- </body>
- </html>
Ext.hoo.component.FileBrowserComponent.js
- /**
- * Ext.hoo.component.FileBrowserWindow 系统文件浏览选择组件,可以选定电脑上的文件或文件夹
- * @author: hoojo
- * @createDate 2010-10-17
- * @email: hoojo_@126.com
- * @blog: http://blog.csdn.net/IBM_hoojo
- * @ext_lib: v2.2
- * @version 1.0
- */
- Ext.ns("Ext.hoo.component");
- Ext.hoo.component.FileBrowserWindow = Ext.extend(Ext.Window, {
- constructor: function (config) {
- config = config || {};
- Ext.apply(this, config);
- this.tree = new Ext.hoo.tree.FileSystemTree();
- Ext.hoo.component.FileBrowserWindow.superclass.constructor.call(this, {
- renderTo: Ext.getBody(),
- width: 300,
- height: 300,
- frame: true,
- layout: "fit",
- border: false,
- title: "请选择",
- items: this.tree,
- buttons: [{
- text: "新建",
- disabled: true,
- handler: this.onNewHandler,
- scope: this
- }, {
- text: "确定",
- disabled: true,
- handler: this.onOkHandler,
- scope: this
- }, {
- text: "取消",
- handler: function () {
- this.hide(Ext.getBody());
- },
- scope: this
- }]
- });
- },
- onNewHandler: function () {
- this.setPath();
- this.setFile();
- Ext.Msg.prompt("新建文件", "请输入文件夹名称", this.onCreateDir, this);
- },
- onOkHandler: function () {
- this.setPath();
- this.setFile();
- Ext.Msg.alert("路径", this.getPath());
- },
- onCreateDir: function (btn, text) {
- if (btn == "ok") {
- var path = this.getPath();
- var node = this.getFile();
- var dirName = text;
- if (!!path && !!dirName) {
- //本地添加模式
- /*var newNode = new Ext.tree.AsyncTreeNode({
- text: dirName,
- path: node.attributes.path + "/" + dirName
- });
- node.expand(true, true);
- node.appendChild(newNode);*/
- //远程加载模式
- Ext.Ajax.request({
- url: Ext.hoo.tree.FileSystemTree.TREE_CREATE_DIR_URL,
- params: {path: encodeURIComponent(path), dirName: encodeURIComponent(dirName)},//处理中文文件名,乱码问题
- success: function (response, options) {
- var returnNnode = Ext.decode(response.responseText);
- node.appendChild(returnNnode);
- node.expand(true);
- },
- failure: function (response) {
- Ext.Msg.alert("程序异常", response.responseText);
- }
- });
- }
- }
- },
- setPath: function () {
- this.path = this.tree.getSelectedNode().attributes.path || "";
- },
- setFile: function () {
- this.nodeFile = this.tree.getSelectedNode() || {};
- },
- getPath: function () {
- return this.path;
- },
- getFile: function () {
- return this.nodeFile;
- }
- });
- /**
- * Ext.hoo.component.FileBrowserPanel 系统文件浏览选择组件,可以选定电脑上的文件或文件夹
- * 不同于上面的是,这里是一个panel。有时候弹出window,并不能达到预想的效果。特别是window弹出在
- * iframe中的Object对象上面,如:在播放器上面弹出此组件,拖动windwo的效果不理想。
- * 这时就需要用模态,模态嵌入FileBrowserPanel组件即可
- * @author: hoojo
- * @createDate 2010-10-17
- * @email: hoojo_@126.com
- * @blog: http://blog.csdn.net/IBM_hoojo
- * @ext_lib: v2.2
- * @version 1.0
- */
- Ext.hoo.component.FileBrowserPanel = Ext.extend(Ext.Panel, {
- constructor: function (config) {
- config = config || {};
- Ext.apply(this, config);
- this.tree = new Ext.hoo.tree.FileSystemTree();
- Ext.hoo.component.FileBrowserPanel.superclass.constructor.call(this, {
- renderTo: Ext.getBody(),
- border: false,
- width: 300,
- height: 400,
- layout: "fit",
- title: "请选择",
- items: this.tree,
- buttons: [{
- text: "新建",
- disabled: true,
- handler: this.onNewHandler,
- scope: this
- }, {
- text: "确定",
- disabled: true,
- handler: function () {
- this.path = this.tree.getSelectedNode().attributes.path || "";
- this.nodeFile = this.tree.getSelectedNode() || {};
- //window.returnValue = this.path;
- //window.close();
- Ext.Msg.alert("路径", this.path);
- },
- scope: this
- }, {
- text: "取消",
- handler: function () {
- this.hide(Ext.getBody());
- //window.close();
- },
- scope: this
- }]
- });
- },
- onNewHandler: function () {
- this.setPath();
- this.setFile();
- Ext.Msg.prompt("新建文件", "请输入文件夹名称", this.onCreateDir, this);
- },
- onCreateDir: function (btn, text) {
- if (btn == "ok") {
- var path = this.getPath();
- var node = this.getFile();
- var dirName = text;
- if (!!path && !!dirName) {
- //本地添加模式
- /*var newNode = new Ext.tree.AsyncTreeNode({
- text: dirName,
- path: node.attributes.path + "/" + dirName
- });
- node.expand(true, true);
- node.appendChild(newNode);*/
- //远程加载模式
- Ext.Ajax.request({
- url: Ext.hoo.tree.FileSystemTree.TREE_CREATE_DIR_URL,
- params: {path: encodeURIComponent(path), dirName: encodeURIComponent(dirName)},//处理中文文件名,乱码问题
- success: function (response, options) {
- var returnNnode = Ext.decode(response.responseText);
- node.appendChild(returnNnode);
- node.expand(true, true);
- },
- failure: function (response) {
- Ext.Msg.alert("程序异常", response.responseText);
- }
- });
- }
- }
- },
- setPath: function () {
- this.path = this.tree.getSelectedNode().attributes.path || "";
- },
- setFile: function () {
- this.nodeFile = this.tree.getSelectedNode() || {};
- },
- getPath: function () {
- return this.path;
- },
- getFile: function () {
- return this.nodeFile;
- }
- });
- /**
- * Ext.hoo.tree.FileSystemTree 系统文件树,显示所有的文件
- * @author: hoojo
- * @createDate 2010-10-17
- * @email: hoojo_@126.com
- * @blog: http://blog.csdn.net/IBM_hoojo
- * @ext_lib: v2.2
- * @version 1.0
- */
- Ext.ns("Ext.hoo.tree");
- Ext.hoo.tree.FileSystemTree = Ext.extend(Ext.tree.TreePanel, {
- constructor: function () {
- Ext.hoo.tree.FileSystemTree.superclass.constructor.call(this, {
- //rootVisible: false,
- autoScroll: true,
- root: new Ext.tree.AsyncTreeNode({
- text: "My System Files",
- id: "0",
- path: "root",
- children:[]
- }),
- listeners: {
- expandnode: {
- fn: this.onExpandNode,
- scope: this
- }
- }
- });
- },
- onExpandNode: function (node) {
- //只对未加载过的添加子结点,加载后不在重复加载;避免增加请求,浪费资源
- if (!node.attributes.isLoad) {
- Ext.Ajax.request({
- url: Ext.hoo.tree.FileSystemTree.TREE_DATA_URL,
- params: {path: encodeURIComponent(node.attributes.path)},//处理中文文件名,乱码问题
- success: function (response, options) {
- node.attributes.isLoad = true;//设置加载标示
- var nodes = Ext.decode(response.responseText);
- node.appendChild(nodes);
- },
- failure: function (response) {
- Ext.Msg.alert("程序异常", response.responseText);
- }
- });
- }
- },
- getSelectedNode: function () {
- return this.getSelectionModel().getSelectedNode();
- }
- });
- Ext.hoo.tree.FileSystemTree.TREE_CREATE_DIR_URL = "http://localhost:8080/Test/FileBrowser?method=mkDir";
- Ext.hoo.tree.FileSystemTree.TREE_DATA_URL = "http://localhost:8080/Test/FileBrowser?method=getData";
服务器端java code:
FileBrowser Servlet:
- package com.hoo.servlet;
- import java.io.File;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.URLDecoder;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.swing.filechooser.FileSystemView;
- import net.sf.json.JSONArray;
- import com.hoo.entity.FileInfo;
- import com.hoo.util.FileUtils;
- /**
- * <b>function:</b> 查询本地硬盘文件数据、创建目录
- * @project Test
- * @package com.hoo.servlet
- * @fileName FileBrowser.java
- * @author hoojo
- */
- public class FileBrowser extends HttpServlet {
- private static final long serialVersionUID = 1599390137455995515L;
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- response.setContentType("text/html");
- response.setCharacterEncoding("UTF-8");
- PrintWriter out = response.getWriter();
- String path = request.getParameter("path");
- path = path == null ? "" : URLDecoder.decode(path, "UTF-8");
- String method = request.getParameter("method");
- FileInfo info = new FileInfo();
- if ("getData".equals(method)) {
- if ("root".equals(path)) {
- FileSystemView fsv = FileSystemView.getFileSystemView();
- File[] roots = fsv.getRoots(); //File.listRoots();
- //桌面
- for (File f : roots) {
- info.getChildren().add(FileUtils.getFileInfo(f));
- }
- for (File f : roots[0].listFiles()) {
- if (f.getName().contains("My Documents")) {
- info.getChildren().add(FileUtils.getFileInfo(f));
- }
- }
- FileInfo fileInfo = new FileInfo();
- fileInfo.setName("我的电脑");
- fileInfo.setPath("My Computer");
- for (File fi : roots[0].listFiles()[0].listFiles()) {
- fileInfo.getChildren().add(FileUtils.getFileInfo(fi));
- }
- info.getChildren().add(fileInfo);
- fileInfo = new FileInfo();
- fileInfo.setName("网上邻居");
- fileInfo.setPath("Network Place");
- for (File fi : roots[0].listFiles()[1].listFiles()) {
- fileInfo.getChildren().add(FileUtils.getFileInfo(fi));
- }
- info.getChildren().add(fileInfo);
- out.print(JSONArray.fromObject(info.getChildren()).toString());
- } else if (path != null && !"".equals(path)) {
- FileUtils.getFileInfo(info, new File(path), new String[] {"*"});
- out.print(JSONArray.fromObject(info.getChildren()).toString());
- }
- }
- if ("mkDir".equals(method)) {
- String dirName = request.getParameter("dirName");
- dirName = dirName == null ? "" : URLDecoder.decode(dirName, "UTF-8");
- boolean success = false;
- try {
- success = FileUtils.mkDir(path, dirName);
- FileInfo node = FileUtils.getFileInfo(new File(FileUtils.getDoPath(path) + dirName));
- out.print(JSONArray.fromObject(node));
- } catch (Exception e) {
- e.printStackTrace();
- success = false;
- }
- System.out.println(success);
- }
- out.flush();
- out.close();
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
这个类用到了json-lib.jar工具包,此包可以帮我们把java对象,包括list、map、array序列化成json的字符串。
至少用到以下依赖包:
FileInfo 封装文件信息的java Bean:
- package com.hoo.entity;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * <b>function:</b>文件信息
- * @author hoojo
- * @createDate Oct 10, 2010 9:53:51 PM
- * @file FileInfo.java
- * @package com.hoo.entity
- * @project MultiUpload
- * @blog http://blog.csdn.net/IBM_hoojo
- * @email hoojo_@126.com
- * @version 1.0
- */
- public class FileInfo {
- //文件id
- private String id;
- //文件名称
- private String name;
- private String text;
- //文件路径
- private String path;
- //是否有目录,有无子节点
- private boolean leaf;
- //修改日期
- private String editDate;
- //后缀
- private String suffix;
- //长度
- private long length;
- // 子目录中所有文件
- private List<FileInfo> children = new ArrayList<FileInfo>();
- //setter、getter
- public String toString() {
- return "name:" + name + ", size:" + children.size();
- }
- }
FileUtils 文件操作工具类
- package com.hoo.util;
- import java.io.File;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.UUID;
- import com.hoo.entity.FileInfo;
- /**
- * <b>function:</b> 磁盘文件操作工具类
- * @project Test
- * @package com.hoo.util
- * @fileName FileUtils.java
- * @createDate 2010-10-4 下午03:32:42
- * @author hoojo
- */
- @SuppressWarnings("unused")
- public abstract class FileUtils {
- /**
- * <b>function:</b>传递一个File,返回该文件的FileInfo实体类
- * @author hoojo
- * @createDate Oct 10, 2010 10:10:19 PM
- * @param file File
- * @return FileInfo
- */
- public static FileInfo getFileInfo(File file) {
- FileInfo info = new FileInfo();
- if (file != null) {
- info.setId(UUID.randomUUID().toString());
- if (file.getName() == null || "".equals(file.getName()) || "::".equals(file.getName())) {
- info.setName(file.getAbsolutePath());
- } else {
- info.setName(file.getName());
- }
- //info.setLeaf(file.isFile());
- info.setLeaf(!file.isDirectory());
- info.setLength(file.length());
- info.setPath(getDoPath(file.getAbsolutePath()));
- info.setSuffix(getType(file.getName()));
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- Date date = new Date();
- date.setTime(file.lastModified());
- info.setEditDate(sdf.format(date));
- }
- return info;
- }
- public static void setFileInfo(File file, FileInfo info) {
- if (file != null && info != null) {
- info.setId(UUID.randomUUID().toString());
- if (file.getName() == null || "".equals(file.getName()) || "::".equals(file.getName())) {
- info.setName(file.getAbsolutePath());
- } else {
- info.setName(file.getName());
- }
- //info.setLeaf(file.isFile());
- info.setLeaf(!file.isDirectory());
- info.setLength(file.length());
- info.setPath(getDoPath(file.getAbsolutePath()));
- info.setSuffix(getType(file.getName()));
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- Date date = new Date();
- date.setTime(file.lastModified());
- info.setEditDate(sdf.format(date));
- }
- }
- /**
- * <b>function:</b>处理后的系统文件路径
- * @author hoojo
- * @createDate Oct 10, 2010 12:49:31 AM
- * @param path 文件路径
- * @return 返回处理后的路径
- */
- public static String getDoPath(String path) {
- path = path.replace("//", "/");
- String lastChar = path.substring(path.length() - 1);
- if (!"/".equals(lastChar)) {
- path += "/";
- }
- return path;
- }
- /**
- * <b>function:</b>和文件后缀一样,不同的是没有“.”
- * @author hoojo
- * @createDate Oct 10, 2010 2:42:43 PM
- * @param fileName 文件名称
- * @return
- */
- public static String getType(String fileName) {
- int index = fileName.lastIndexOf(".");
- if (index != -1) {
- String suffix = fileName.substring(index + 1);//后缀
- return suffix;
- } else {
- return null;
- }
- }
- /**
- * <b>function:</b> 得到指定目录下所有的文件集合
- * @createDate 2010-10-20 下午02:20:06
- * @author hoojo
- * @param info 将数据设置在该变量中
- * @param file 文件目录
- */
- public static void getAllFileInfo(FileInfo info, File file) {
- if (file.isDirectory()) {
- long size = 0;
- File[] allFiles = file.listFiles();
- for (File f : allFiles) {
- size += f.length();
- FileInfo fi = getFileInfo(f);
- info.getChildren().add(fi);
- getAllFileInfo(fi, f);
- }
- info.setLength(size);
- }
- }
- /**
- * <b>function:</b> 得到当前目录所有文件
- * @createDate 2010-10-20 下午02:21:06
- * @author hoojo
- * @param info 文件对象
- * @param file 目录
- */
- public static void getFileInfo(FileInfo info, File file, String[] allowTypes) {
- if (file.isDirectory()) {
- long size = 0;
- File[] allFiles = file.listFiles();
- for (File f : allFiles) {
- size += f.length();
- FileInfo fi = getFileInfo(f);
- if (f.isDirectory()) {
- info.getChildren().add(fi);
- } else {
- if (validTypeByName(f.getName(), allowTypes, true)) {
- info.getChildren().add(fi);
- }
- }
- }
- info.setLength(size);
- }
- }
- /**
- * <b>function:</b> 根据文件名和类型数组验证文件类型是否合法,flag是否忽略大小写
- * @author hoojo
- * @createDate Oct 10, 2010 11:54:54 AM
- * @param fileName 文件名
- * @param allowTypes 类型数组
- * @param flag 是否获得大小写
- * @return 是否验证通过
- */
- public static boolean validTypeByName(String fileName, String[] allowTypes, boolean flag) {
- String suffix = getType(fileName);
- boolean valid = false;
- if (allowTypes.length > 0 && "*".equals(allowTypes[0])) {
- valid = true;
- } else {
- for (String type : allowTypes) {
- if (flag) {//不区分大小写后缀
- if (suffix != null && suffix.equalsIgnoreCase(type)) {
- valid = true;
- break;
- }
- } else {//严格区分大小写
- if (suffix != null && suffix.equals(type)) {
- valid = true;
- break;
- }
- }
- }
- }
- return valid;
- }
- /**
- * <b>function:</b> 在path目录下创建目录
- * @createDate 2010-11-3 下午04:03:34
- * @author hoojo
- * @param path
- * @param dirName
- * @return
- */
- public static boolean mkDir(String path, String dirName) {
- boolean success = false;
- File file = new File(getDoPath(path) + dirName);
- if (!file.exists()) {
- success = file.mkdirs();
- }
- return success;
- }
- }
点击新建可以创建新目录,确定可以获取选择的路径。