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

如何用SMBJ从BufferedInputStream写入大文件?代码执行停滞排查

transferTo写入SMB共享文件时卡住,无法执行完成

问题现象

使用transferTo(...)向SMB共享目录写入文件时,目标文件持续增长,但System.out.println("Writing file done.");始终不执行,代码卡在transferTo调用处。

可能原因及解决方案

1. 缓冲输出流与SMB流的适配问题

BufferedOutputStream的缓存机制可能和SMB底层流的提交逻辑冲突,导致数据一直在缓冲中等待,或者transferTo无法触发流的完成信号。

解决方式:

  • 直接使用SMB文件的原始输出流,去掉BufferedOutputStream包装:
    try(
        File f = share.openFile(directory + "\\" + fileName, new HashSet(Arrays.asList(new AccessMask[]{AccessMask.GENERIC_ALL})), fileAttributes, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN_IF, createOptions);
        OutputStream bo = f.getOutputStream()
    ) {
        System.out.println("Writing file to share...");
        bi.transferTo(bo);
        System.out.println("Writing file done.");
    }
    
  • 或者在transferTo执行后显式刷新缓冲:
    bi.transferTo(bo);
    bo.flush();
    

2. 源文件未终止输入

如果sourcePath对应的本地文件正在被其他进程持续写入,FileInputStream会不断读取新增数据,导致transferTo持续向目标文件写入,永远无法结束。

解决方式:

  • 确认源文件为静态文件,无其他进程写入;
  • 若需读取动态写入的文件,可先创建文件快照再读取,或限制读取字节数:
    long sourceSize = new File(sourcePath).length();
    bi.transferTo(bo, 0, sourceSize);
    

3. SMB创建选项的冲突

设置的FILE_SEQUENTIAL_ONLY选项提示服务器文件为顺序访问,但transferTo的底层实现可能不符合该选项的预期,导致服务器端阻塞。

解决方式:

  • 移除FILE_SEQUENTIAL_ONLY选项,使用默认创建配置:
    Set<SMB2CreateOptions> createOptions = new HashSet<>();
    // 移除该行:createOptions.add(SMB2CreateOptions.FILE_SEQUENTIAL_ONLY);
    

4. 替换transferTo为手动循环读写

若上述方法无效,可绕过transferTo,手动实现缓冲区读写逻辑:

byte[] buffer = new byte[8192];
int readLen;
while ((readLen = bi.read(buffer)) != -1) {
    bo.write(buffer, 0, readLen);
}
bo.flush();

内容的提问来源于stack exchange,提问作者user432024

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:17:24