用 js 写了一个批量保存文本文件入数据库的脚本

前几天偶然去 CSDN 逛了一下,发现有人整理了 CSDN 论坛问题的 FAQ 提供下载 (http://community.csdn.net/Expert/topic/4191/4191119.xml?temp=.86224),于是下载了一份。但是发现其中是按照分类目录保存的文本文件形式。问了方便使用,我用 js 写了一个简单的脚本将这些内容分类别存入了 Access 数据库。以下代码保存为 AddFAQ.js :

/// Global ----------------------------------------------------

var consoleOnly = true;
var defaultTimeout = 1;

var WSShell;
var fso;
var currentFolder;

var ForReading = 1, ForWriting = 2, ForAppending = 8;
var CharSetDefault = -2, CharSetUnicode = -1, CharSetAscii = 0;
var AttrNormal = 0, AttrReadOnly = 1, AttrHidden = 2, AttrSystem = 4,
AttrVolume 
= 8, AttrDirectory = 16, AttrArchive = 32, AttrAlias = 1024,
AttrCompressed 
= 2048;

var strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\\CSDN_FAQ.mdb;Persist Security Info=False";

Init();
Main();

function Init() {
    
    
// detect command line
    try {
        WScript.StdOut.WriteLine(
" ");
    } 
catch (e) {
        consoleOnly 
= false;
    }
    
    
// initialize
    WSShell = new ActiveXObject("WScript.Shell");
    fso 
= new ActiveXObject("Scripting.FileSystemObject");
    currentFolder 
= GetCurrentFolder();    
}

function Main() {
    
    
var text;
        
    
// say hello
    text = "开始保存信息.";
    Out(text,
true);
    COut(
"当前工作目录: \r\n"+ currentFolder);    
    
    
var conn = new ActiveXObject("ADODB.Connection");
    conn.Open(strConn);    
    
var rs = new ActiveXObject("ADODB.RecordSet");
    
var rs2 = new ActiveXObject("ADODB.RecordSet");
    rs.Open(
"select cateID, cateName from Category where 1 = 0", conn, 13);
    rs2.Open(
"select faqTitle, faqContent, cateID from FAQ where 1 = 0", conn, 13);

    
var cateFolders = new Enumerator(currentFolder.SubFolders);
    
var treatedFiles = 0;
    
for (; !cateFolders.atEnd(); cateFolders.moveNext()) {
        COut(
"分类目录名:" + cateFolders.item().Name);
        
        rs.AddNew();
        rs(
"cateName"= cateFolders.item().Name;
        rs.Update();
        
var cateID = parseInt(rs("cateId"));        

        
var files = GetFiles(cateFolders.item(), "[.]*[.]txt");
        COut(
"该目录下共有 " + files.length + " 个文件。开始保存"true);
        
        
for (var i = 0; i < files.length; i++) {
            
var f = fso.GetFile(files[i]);
            
var title = f.Name.replace(/([.]txt)/i, '');
            
var content = ReadFile(f);
            
            rs2.AddNew();
            rs2(
"faqTitle"= title;
            rs2(
"faqContent"= content;
            rs2(
"cateID"= cateID;
            rs2.Update();            
            
            treatedFiles
++;
        }
        COut(
"保存完毕。"true);
    }
    rs.Close();
    rs2.Close();
    conn.Close();
    
    
// say goodbye 
    text = "已成功插入数据。\r\n\r\n"
         
+ "处理的文件数目:\t" + treatedFiles + "\r\n"

    Out(text,
false);
}

/// Files ------------------------------------------------------

// getcurrent folder 
function GetCurrentFolder() {    
    
return fso.GetFolder(fso.GetFile(WScript.ScriptFullName).ParentFolder);
}


/// Output ------------------------------------------------------

// output 
function Out(text, useTimeout) {
    
if (useTimeout) { 
        useTimeout 
= defaultTimeout;
    } 
else {
        useTimeout 
= -1
    }

    
if (consoleOnly) {
        WScript.StdOut.WriteLine(text);
    } 
else {
        WSShell.Popup(text, useTimeout, 
"添加信息到 Access 数据库");
    }
}

// output 
function COut(text, useTimeout) {
    
if (useTimeout) { 
        useTimeout 
= defaultTimeout;
    } 
else {
        useTimeout 
= -1
    }

    
if (consoleOnly) {
        WScript.StdOut.WriteLine(text);
    } 
}

function ReadFile(file) {
    
var stream = file.OpenAsTextStream(ForReading, CharSetDefault);
    text 
= stream.ReadAll();
    stream.Close();
    
return text;
}

function WriteFile(file, text) {
    
var ro = ((file.Attributes & AttrReadOnly) != 0);
    
if (ro) file.Attributes -= AttrReadOnly;
    
var stream = file.OpenAsTextStream(ForWriting, CharSetDefault);
    stream.Write(text);
    stream.Close();
    
if (ro) file.Attributes += AttrReadOnly;
}

// determine, if filename matches given mask
function MatchesMask(file, mask) {
    
return new RegExp(mask).test(file);
}

// find files 
function FindFiles(mask) {
    
return GetFiles(currentFolder, mask);
}

// get files in current folder & subfolders
function GetFiles(folder, mask) {
    
var result = new Array();
    
// do files in current folder
    var files = new Enumerator(folder.Files);
    
for (; !files.atEnd(); files.moveNext()) {
        
if (MatchesMask(files.item(), mask)) {
            result.push(
"" + files.item());
        }
    }
    
// do subfolders in current folder
    var folders = new Enumerator(folder.SubFolders);
    
for (; !folders.atEnd(); folders.moveNext()) {
        result 
= result.concat(GetFiles(folders.item(), mask));
    }
    
return result;
}

放在分类的目录下,双击即可执行,或者在命令行下面执行 cscript ADDFAQ.js, 在命令行下的好处是可以把输出看的清楚一点。
这个代码中使用的一些函数是从前几天学习的一个去除 .net 项目 vss 信息的脚本中的,来自 CodeProject,因此本人版权的没有。可见脚本写的好了也可以达到很高的代码复用性

命令行下输出信息如下:

D:\Downloads\CSDN_FAQ>cscript addfaq.js
Microsoft (R) Windows Script Host Version 
5.6
版权所有(C) Microsoft Corporation 
1996-2001。保留所有权利。


开始保存信息.
当前工作目录:
D:\Downloads\CSDN_FAQ
分类目录名:delphi
该目录下共有 
1484 个文件。开始保存
保存完毕。
分类目录名:dotnet
该目录下共有 
795 个文件。开始保存
保存完毕。
分类目录名:java
该目录下共有 
1851 个文件。开始保存
保存完毕。
分类目录名:sqlserver
该目录下共有 
2191 个文件。开始保存
保存完毕。
分类目录名:vb
该目录下共有 
764 个文件。开始保存
保存完毕。
分类目录名:vcmfc
该目录下共有 
1564 个文件。开始保存
保存完毕。
分类目录名:web
该目录下共有 
2930 个文件。开始保存
保存完毕。
分类目录名:windows专区
该目录下共有 
1635 个文件。开始保存
保存完毕。
分类目录名:硬件使用
该目录下共有 
139 个文件。开始保存
保存完毕。
分类目录名:软件工程
该目录下共有 
239 个文件。开始保存
保存完毕。
已成功插入数据。

处理的文件数目:        
13592

用了好几分钟才执行完毕。最终产生的 Access 数据库有 77MB 大。感觉速度有点慢,不过用脚本做一些像这种自己使用的日常功能还是很方便的。

posted on 2005-09-07 14:25 NeilChen 阅读(...) 评论(...) 编辑 收藏

导航

统计