1.WeCode简介
SVN、Git等工具适合多人协作时代码管理。类似在线的Gist(http://gist.github.com),WeCode是适合个人离线代码片段管理。
wecode是CodeHelp的升级版本,是专门为我们程序员设计的一款源代码管理软件。 它能方便的管理您在编程和学习中有用的源代码,减少经常到处查找资料的劳动,节省您在开发中的时间和精力。
知识管理越来越被大家所重视,源代码也应该做为一种知识资源,纳入知识管理体系中去。 利用wecode,可以方便的管理你的各种技术资料和源代码。
CodeHelp: http://blog.csdn.net/thinkry/article/details/248463
WeCode: http://wecode.thinkry.com/
2. WeCode导出
CodeHelp、WeCode作者都是thinkry。我只是写了个导出的Java程序。无论用什么工具,内容可以方便地迁移才是最重要的。之前写了一个CodeHelp导出(导出CodeHelp的数据 : http://www.blogjava.net/wintys/archive/2009/03/16/java_codehelpexporter.html)。现在CodeHelp升级成了WeCode,但是表结构并没有变化,试了一下之前的导出代码在JDK8.0下运行不了,因为sun.jdbc.odbc.JdbcOdbcDriver类被JDK移除了。所以改进了一下,代码如下:
import java.sql.*;
import java.io.*;
import java.util.*;
public class WeCodeExporterMain{
public static void main(String[] args){
String dbq = "D:/helpdb.mdb";
WeCodeExporter exporter = new WeCodeExporter( dbq );
exporter.export();
}
}
/*
*将WeCode数据库中的文件导出
*@version 2015-06-21
*@author wintys@gmail.com
*/
class WeCodeExporter{
Database db;//数据库连接对象
public WeCodeExporter(String dbPath){
db = new Database(dbPath);
try{
db.connect();
}catch(SQLException sqle){
sqle.printStackTrace();
}
}
/**
*按WeCode的目录结构导出文章及其附件。
*但有一点不同,就是不含任何内容的目录不会被创建。
*文章会被导出到当前目录的ExportedFiles目录下。
*/
public void export(){
try{
String sql;
sql = "SELECT T.NodeId AS id , T.ParentId AS parent ,";
sql +="T.Type AS type,T.Title AS title , C.Content AS content ";
sql +="FROM TContent C, TTree T WHERE T.NodeId = C.NodeId ";
ResultSet rs = db.query(sql);
while(rs.next()){
int type = rs.getInt("type");
if(type == 0)//如果是目录,则无操作
continue;
int parent = rs.getInt("parent");
int id = rs.getInt("id");
String title = rs.getString("title");
File fullParentPath = null;
fullParentPath = parentPath(parent , "");
fullParentPath = new File("ExportedFiles/" +
fullParentPath.toString() );
//读取附件的SQL
String sql2 = "SELECT A.Title AS title , A.Data AS data ";
sql2 += "FROM TAttachment A WHERE A.NodeId = " + id;
ResultSet rs2=db.query(sql2);
//判断文章有没有附件
//如果文章没有附件则不创建目录,即文章不包含在目录中
rs2.last();
int num = rs2.getRow();
String article;
if(num > 0){
article = title + "/" ;
}
else{
article = "";
}
fullParentPath = new File(fullParentPath , article);
if(!fullParentPath.exists())
fullParentPath.mkdirs();
//读取文章
InputStream input = rs.getAsciiStream("content");
readDataToFile(new File(fullParentPath , title + ".txt") , input);
//读取文章的附件
rs2.beforeFirst();
while(rs2.next()){
String attachmentName = rs2.getString("title");
InputStream data = rs2.getBinaryStream("Data");
//将附件与其文章一同放在以文章名为目录名的目录中
readDataToFile(new File(fullParentPath , attachmentName) ,
data);
}
rs2.close();
}
rs.close();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
db.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
*从数据流中读取数据到文件
*@param fileName 输出文件的文件名
*@param input 数据输入流
*/
private void readDataToFile(File filePath , InputStream input)
throws IOException{
FileOutputStream file = new FileOutputStream(filePath);
BufferedOutputStream output = new BufferedOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len = input.read(buf))!=-1){
output.write(buf , 0 , len);
}
input.close();
output.close();
}
/**
*递归地构造目录(如果父目录存在的话)。即如果是子目录,则一直找到根目录才返回。
*@param parent 父目录的ParentId
*@param title 文件自身目录名,对于文章而言,path总是传入空字符串。
*@return 返回构造后的目录(含从根目录一直到子目录的各级目录)
*/
private File parentPath(int parent , String path)
throws IOException , SQLException{
if(parent == 0){//根目录
File dir = new File(path);
return dir;
}else{
String sql = "SELECT Title , ParentId FROM TTree ";
sql += "WHERE NodeId=" + parent;
ResultSet rs = db.query(sql);
if(rs.next()){
String nodeTitle = rs.getString("Title");
int nodeParent = rs.getInt("ParentId");
path = nodeTitle + "/" + path;
return parentPath(nodeParent , path);
}
rs.close();
}
return null;///
}
}
/**
*数据库操作类,当前只适用于Access数据库。
*@version 2015-06-21
*@author wintys@gmail.com
*/
class Database{
private Connection conn = null;
private String dbPath = null;
/**
*构造方法
*@param databasePath Access数据库的路径
*/
public Database(String databasePath){
dbPath = databasePath;
}
/**
*连接数据库
*@return 返回一个数据库连接Connection,如果连接数据库失败,返回null。
*/
public Connection connect()
throws SQLException{
if(conn!=null)
return conn;
if(dbPath==null || dbPath.equals("")){
conn = null;
throw new SQLException("数据库路径错误!");
}
//Microsoft Access数据库连接字符串
String url = "jdbc:Access:///"+ dbPath;
try{
Class.forName("com.hxtt.sql.access.AccessDriver");
}catch(ClassNotFoundException e){
e.printStackTrace();
}
Properties prop = new Properties();
prop.put("charSet", "gb2312"); //设置编码防止中文出现乱码
conn = DriverManager.getConnection(url , prop);
return conn;
}
/**
*关闭数据库连接
*/
public void close() throws SQLException{
if(conn!=null)
conn.close();
}
/**
*执行查询,调用者要负责关闭结果集。
*@param sql 要执行的SQL查询语句
*@return 返回查询结果集
*/
public ResultSet query(String sql) throws SQLException{
Statement stmt;
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE ,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sql);
return rs;
}
}
附件1: