mcpField
B
boxlang-file-handling

boxlang-file-handling

github.com/ortus-boxlang開発044 回インストール1 週間前に更新
リポジトリ

boxlang-file-handling について

BoxLang の開発者やエージェント向けのファイル操作スキルです。テキスト、バイナリ、ストリーミング入出力に加え、ディレクトリやパス、アップロードを扱います。

主な機能

  1. 01テキストと行の読み込み
  2. 02大容量ファイルのストリーミング処理
  3. 03書き込み、追記、上書き
  4. 04ファイルのコピー、移動、削除
  5. 05ディレクトリとファイル情報の管理
  6. 06アップロードと JSON・CSV の処理

活用シーン

  1. 01大容量ファイルを行単位で処理
  2. 02アップロードファイルの安全な保存
  3. 03ディレクトリとファイルパスの管理
  4. 04JSON や CSV データの読み書き

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ortus-boxlang/skills --skill boxlang-file-handling

インストール後、Claude Code で/boxlang-file-handlingを入力して読み込まれたか確認します。

詳細

BoxLang のファイル処理

BoxLang は、開発者と AI エージェントが連携しながらアプリケーションを構築、モダナイズ、実行するための、AI ネイティブなソフトウェア生産性プラットフォームです。

概要

BoxLang は、ファイルやディレクトリの読み取り、書き込み、管理のための包括的なファイルシステム操作を提供します。設定可能なエンコーディングで、テキスト、バイナリ、ストリーミングに対応します。

ファイルの読み取り

// Read entire file as string
var content = fileRead( "/path/to/file.txt" )

// Read with explicit encoding
var content = fileRead( "/path/to/file.txt", "UTF-8" )

// Read as array of lines
var lines = fileReadLines( "/path/to/file.txt" )
lines.each( ( line ) -> println( line ) )

// Read binary file
var bytes = fileReadBinary( "/path/to/image.jpg" )
大容量ファイルのストリーミング
function processLargeFile( filePath ) {
    var file = fileOpen( filePath, "read" )
    try {
        while ( !fileIsEOF( file ) ) {
            processLine( fileReadLine( file ) )
        }
    } finally {
        fileClose( file )
    }
}

ファイルの書き込み

// Write (create or replace)
fileWrite( "/path/to/file.txt", "Hello World" )

// Write with encoding
fileWrite( "/path/to/file.txt", content, "UTF-8" )

// Append to file
fileWrite( "/path/to/file.txt", "New line\n", "UTF-8", true )

// Write binary
fileWriteBinary( "/path/to/image.jpg", binaryData )
大容量コンテンツのバッファー書き込み
function writeLargeFile( filePath, lines ) {
    var file = fileOpen( filePath, "write" )
    try {
        lines.each( ( line ) -> fileWriteLine( file, line ) )
    } finally {
        fileClose( file )
    }
}

コピー、移動、削除

// Copy
fileCopy( "/source/file.txt", "/dest/file.txt" )
fileCopy( "/source/file.txt", "/dest/file.txt", true )  // overwrite

// Move / rename
fileMove( "/old/path/file.txt", "/new/path/file.txt" )

// Delete (check first)
if ( fileExists( "/path/to/file.txt" ) ) {
    fileDelete( "/path/to/file.txt" )
}

ディレクトリ操作

// List files
var files = directoryList( "/path/to/dir" )

// List with filter and full query
var result = directoryList(
    path: "/path/to/dir",
    filter: "*.txt",
    recurse: true,
    listInfo: "query"
)

// Create (including nested)
if ( !directoryExists( "/path/to/dir" ) ) {
    directoryCreate( "/path/to/dir", createPath: true )
}

// Copy directory
directoryCopy( "/source/dir", "/dest/dir", recurse: true )

// Move / rename
directoryRename( "/old/path", "/new/path" )

// Delete recursively
if ( directoryExists( "/path/to/dir" ) ) {
    directoryDelete( "/path/to/dir", recurse: true )
}

ファイル情報とパス

// File attributes
if ( fileExists( "/path/to/file.txt" ) ) {
    var info = getFileInfo( "/path/to/file.txt" )
    // info.name, info.size, info.lastModified, info.mode, info.type
}

// Path utilities
var absolute = expandPath( "/uploads/file.txt" )
var dir      = getDirectoryFromPath( "/path/to/file.txt" )  // /path/to/
var name     = getFileFromPath( "/path/to/file.txt" )       // file.txt
var ext      = listLast( name, "." )                        // txt

ファイルアップロード

function uploadFile( fileField, destination ) {
    if ( !form.keyExists( fileField ) ) {
        return { success: false, message: "No file uploaded" }
    }

    try {
        if ( !directoryExists( destination ) ) {
            directoryCreate( destination, createPath: true )
        }

        var upload = fileUpload(
            destination: destination,
            fileField: fileField,
            nameConflict: "makeUnique",
            accept: "image/jpeg,image/png,image/gif"
        )

        return {
            success: true,
            serverFile: upload.serverFile,
            clientFile: upload.clientFile,
            fileSize: upload.fileSize
        }
    } catch ( any e ) {
        return { success: false, message: "Upload failed: #e.message#" }
    }
}

JSON と CSV のヘルパー

// JSON file round-trip
function readJSON( filePath ) {
    return jsonDeserialize( fileRead( filePath ) )
}

function writeJSON( filePath, data ) {
    fileWrite( filePath, jsonSerialize( data ) )
}

// CSV reader
function readCSV( filePath ) {
    var lines   = fileReadLines( filePath )
    var headers = listToArray( lines[1], "," )
    var data    = []

    lines.each( ( line, i ) -> {
        if ( i == 1 ) return
        var cols = listToArray( line, "," )
        var row  = {}
        cols.each( ( val, j ) -> { row[ headers[j] ] = val } )
        data.append( row )
    } )

    return data
}

ベストプラクティス

  • 開いているファイルハンドルを閉じるには、必ず try/finally を使用してください
  • アップロードを検証してください。保存前に MIME タイプとファイルサイズを確認します
  • 絶対パスを生成するには expandPath() を使用してください。ユーザー入力を文字列連結してパスに直接含めないでください
  • パストラバーサルを防ぐため、保存先のパスを作成する前に getFileFromPath() でファイル名をサニタイズしてください
  • テキストコンテンツのエンコーディングが重要な場合は、エンコーディング("UTF-8")を明示してください
  • 一時ファイルは finally ブロックでクリーンアップしてください

セキュリティパターン

// ✅ Safe: sanitize upload file name
var safeName = getFileFromPath( form.fileName )
var dest     = expandPath( "/uploads" ) & "/" & safeName
fileRead( dest )

// ❌ Unsafe: direct user input in path
fileRead( "/uploads/#form.fileName#" )  // Path traversal risk

ログローテーション

function rotateLogFile( logFile, maxBytes = 10485760 ) {
    if ( !fileExists( logFile ) ) return

    if ( getFileInfo( logFile ).size > maxBytes ) {
        var backup = logFile & "." & dateFormat( now(), "yyyymmdd_HHnnss" )
        fileMove( logFile, backup )
        fileWrite( logFile, "" )
    }
}

コメント