首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

VBScript 文本文件分割工具代碼審查

     編輯:PHP 相關知識

代碼識別與功能分析

輸入內容為 VBScript (Visual Basic Script) 而非 PHP,副檔名通常為 .vbs。功能:使用 ADO (ActiveX Data Objects) 以文本驅動程式 (Microsoft.Jet.OLEDB.4.0) 開啟大型文本文件,按每 5000 行分割為多個小檔案。

核心邏輯解讀

' 參數處理
Set Arg = Wscript.Arguments
If Arg.Count = 0 Then Wscript.Quit
' 解析輸入路徑
path = Left(Arg(0), InStrRev(Arg(0), "\"))
Fname = Replace(Arg(0), path, "")

' ADO 連接文本文件
Set Conn = CreateObject("ADODB.Connection")
Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & path & ";Extended Properties=""text;HDR=NO;FMT=Delimited"""

' 統計總行數
Set Rs = CreateObject("ADODB.Recordset")
Rs.Open "Select count(*) FROM " & Fname, Conn, 3, 3, &H0001
allline = Rs(0)

' 逐批次讀取並寫入分割文件
Rs.Open "Select * FROM " & Fname, Conn, 3, 3, &H0001
Do Until Rs.EOF
    n = 0
    Do Until n = 5000
        Set MyTables = fso.CreateTextFile(Arg(0) & i & ".txt", True)
        MyTables.WriteLine Rs.Fields.Item(0).Value
        Rs.MoveNext
        n = n + 1
        If Rs.EOF Then Exit Do
    Loop
    MyTables.Close
    i = i + 1
Loop

關鍵技術點與缺陷

項目說明問題/風險
ADO 文本驅動將文本視為資料表,每行一記錄,第一欄為內容需安裝 Jet OLEDB Provider (Windows 內建但 64 位系統需 32 位兼容)、Schema.ini 定義格式
記憶體模型游標類型 3 (adOpenStatic), 鎖類型 3 (adLockOptimistic)大文件可能佔用大量記憶體,非流式處理
分割邏輯缺陷內層 Do Until n = 5000 中重複 CreateTextFile、WriteLine、Close嚴重效能問題:每行開關檔案,磁碟 I/O 暴增;正確做法:外層開檔、內層寫入、批次關閉
錯誤處理On Error Resume Next 忽略所有錯誤靜默失敗,難以排查 (如權限不足、磁碟滿、ADO 連接失敗)
變數作用域未聲明變數 (Option Explicit 缺失)拼寫錯誤導致新變數隱性建立,邏輯錯誤難查
編碼假設預設系統預設編碼 (ANSI/GBK)UTF-8 文本可能讀取亂碼,需在 Extended Properties 指定 CharacterSet=65001

PHP 版重寫參考 (流式、高效、健壯)

<?php
/**
 * 大文本文件分割器
 * 用法: php split.php input.txt 5000 [output_dir]
 */
$inputFile = $argv[1] ?? die("Usage: php split.php   [output_dir]\n");
$linesPerFile = (int)($argv[2] ?? 5000);
$outputDir = $argv[3] ?? dirname($inputFile) . '/split_out';

if (!is_file($inputFile) || !is_readable($inputFile)) die("Input file not readable\n");
if (!is_dir($outputDir)) mkdir($outputDir, 0755, true);

$handle = fopen($inputFile, 'r');
if (!$handle) die("Cannot open input file\n");

$fileNum = 1;
$lineCount = 0;
$outHandle = null;
$baseName = basename($inputFile);
$baseName = preg_replace('/\.[^.]+$/', '', $baseName);

try {
    while (($line = fgets($handle)) !== false) {
        if ($lineCount === 0) {
            $outFile = $outputDir . '/' . $baseName . '_part' . str_pad($fileNum, 3, '0', STR_PAD_LEFT) . '.txt';
            $outHandle = fopen($outFile, 'w');
            if (!$outHandle) throw new RuntimeException("Cannot create output file: $outFile");
        }
        fwrite($outHandle, $line);
        $lineCount++;
        
        if ($lineCount >= $linesPerFile) {
            fclose($outHandle);
            $outHandle = null;
            $lineCount = 0;
            $fileNum++;
        }
    }
} finally {
    if ($handle) fclose($handle);
    if ($outHandle) fclose($outHandle);
}

echo "Done. Split into $fileNum files in $outputDir\n";
?>

PHP 版優勢對比

  • 流式處理:fgets 逐行讀取,記憶體常數級 (僅單行緩衝),支援 TB 級大文件。
  • 批次寫入:單檔案開啟/關閉,I/O 操作減少 5000 倍。
  • 異常安全:try/finally 確保資源釋放,錯誤可捕獲處理。
  • 跨平台:Linux/Windows/macOS 同代碼運行,無 COM/ADO 依賴。
  • 編碼自動適配:PHP 內部 UTF-8,讀寫保持原編碼位元組序列。

適用場景建議

  • 日誌文件分割 (Nginx/Apache access.log, error.log)
  • 巨量 CSV/TSV 數據預處理分片導入資料庫
  • 郵件列表/字典文件分片分發
  • 任何超過記憶體大小的文本文件切分需求
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved