You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MarkLogic中获取文本文件大小并解决计算差异问题

问题:MarkLogic中获取与系统一致的日志文件大小及日期统计问题

我需要在MarkLogic中获取文本文件大小,以此统计特定日期日志文件的增长量。以下是我编写的代码:

xquery version "1.0-ml";

declare function local:convertToKilobytes($sizeInCharacters as xs:integer) as xs:decimal 
{
 $sizeInCharacters * 2 div 1024
};

let $error-log := "C:\Program Files\MarkLogic\Data\Logs\ErrorLog.txt"
let $logLines := fn:tokenize(xdmp:filesystem-file($error-log), '\r?\n')
let $uniqueDates := distinct-values(
                    for $line in $logLines
                    let $logDate := fn:substring($line, 1, 10) 
                    where $logDate ne ''
                   return $logDate
                                  )
let $currentSize := sum(for $line in $logLines return string-length($line))

let $logEntries := 
                for $date in $uniqueDates
                let $sizeInCharacters := sum(for $l in $logLines where fn:contains($l, $date) return string-length($l))
                let $sizeInKilobytes := local:convertToKilobytes($sizeInCharacters)
                return
                <log-entry date="{$date}" size-in-kilobytes="{$sizeInKilobytes}"/>

return
<log-growth>{ $logEntries }</log-growth>

运行上述代码后得到结果:

<log-growth>
  <log-entry date="2023-09-11" size-in-kilobytes="75.05859375">
  </log-entry>
</log-growth>

但查看系统文件属性时,显示文件大小为38KB,磁盘占用大小为128KB,两者结果不一致。请问MarkLogic是否有特定函数可获取与系统一致的文件大小?求相关建议。


解决方案

1. 结果不一致的核心原因

  • 字符编码假设错误:你默认每个字符占2字节,但MarkLogic读取文本文件时用UTF-8编码,ASCII字符仅占1字节,多字节字符占2-4字节,直接乘以2会导致计算值偏大。
  • 丢失换行符字节:tokenize拆分时丢弃了原文件中的换行符(\r\n占2字节),这部分字节未被统计,导致结果偏差。
  • 系统显示的“文件大小”是实际字节数,“磁盘占用大小”是文件系统按簇分配的空间,二者本身存在差异,我们需要对齐的是实际文件大小。

2. 使用MarkLogic内置函数获取准确文件大小

MarkLogic提供xdmp:filesystem-file-size()函数,可直接获取文件的实际字节数,与系统属性中的“文件大小”完全一致。

3. 优化后的代码

以下代码同时实现获取系统一致的文件总大小,以及按日期统计日志行的实际字节占比:

xquery version "1.0-ml";

let $error-log := "C:\Program Files\MarkLogic\Data\Logs\ErrorLog.txt"
// 获取文件实际总字节数,与系统显示一致
let $file-total-bytes := xdmp:filesystem-file-size($error-log)
let $file-content := xdmp:filesystem-file($error-log)
let $logLines := fn:tokenize($file-content, '\r?\n')
let $uniqueDates := distinct-values(
                    for $line in $logLines
                    let $logDate := fn:substring($line, 1, 10) 
                    where $logDate ne ''
                   return $logDate
                  )

let $logEntries := 
  for $date in $uniqueDates
  let $date-lines := $logLines[fn:contains(., $date)]
  // 计算每行实际字节数(含换行符):内容字节数 + 换行符字节(Windows为2,Linux为1)
  let $date-bytes := sum(
    for $line in $date-lines
    return fn:string-length(xs:hexBinary(xs:string($line))) div 2 + 2
  )
  let $sizeInKilobytes := $date-bytes div 1024
  return
  <log-entry date="{$date}" size-in-kilobytes="{$sizeInKilobytes}" bytes="{$date-bytes}"/>

return
<log-growth>
  <file-total-bytes>{$file-total-bytes}</file-total-bytes>
  <file-total-kilobytes>{$file-total-bytes div 1024}</file-total-kilobytes>
  {$logEntries}
</log-growth>

4. 关键说明

  • xdmp:filesystem-file-size($path):返回文件实际字节数,与系统“文件大小”完全匹配。
  • 按日期统计时,通过xs:hexBinary计算每行真实字节数,加上换行符字节,确保统计值接近实际占比。
  • 系统“磁盘占用大小”是操作系统层面的簇分配信息,MarkLogic无法直接获取,若需获取可通过调用外部系统命令(如Windows的dir、Linux的ls -s),但需配置xdmp:invoke权限。

内容的提问来源于stack exchange,提问作者Dharmendra Kumar Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:05:28