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

跨操作系统读取Spring Boot WAR中文件,如何获取一致字节数组?

跨操作系统读取WAR包内文件时字节数组不一致的解决方案

场景描述

我有一个以WAR包运行的Spring Boot应用,需在不同操作系统中测试。读取resources目录(WAR内路径为/WEB-INF/classes/file-name)文件的步骤如下:

  • 获取输入流:
    InputStream fileAsInputStream = new ClassPathResource("file-name").getInputStream();
    
  • 将输入流转换为字节数组:
    byte[] fileAsByteArray = IOUtils.toByteArray(fileAsInputStream);
    

问题现象

不同操作系统下得到的字节数组内容不一致,导致后续SFTP通信操作异常。核心原因是文件中的换行符差异:

  • Linux环境下换行符为\n(十六进制0x0A,十进制10)
  • Windows环境下换行符为\r\n(十六进制0x0D 0x0A,十进制13、10)

示例差异:

  • Linux环境字节数组:[114, 115, 97, 10, 69, 110]
  • Windows环境字节数组:[114, 115, 97, 13, 10, 69, 110]

文件为SFTP通信的私钥,内容本身一致,但运行操作系统不同导致字节数组差异。尝试用StandardCharsets.UTF_8处理(如下代码),仍无法解决问题:

IOUtils.toByteArray(new BufferedReader(new InputStreamReader(new ClassPathResource("file-name").getInputStream())), StandardCharsets.UTF_8)

目前已有的临时方案是遍历字节数组,将换行符统一映射为相同字节(例如把10替换为13+10),但希望找到更优的解决方案。

最优解决方案

1. 从根源避免:确保WAR包内文件字节一致

直接读取原始字节流本应在任何系统下得到相同结果,若出现差异,大概率是文件在打包或版本控制阶段被修改了换行符。可通过以下方式解决:

  • 版本控制设置:在Git的.gitattributes文件中添加规则,强制私钥文件以二进制方式存储,避免自动转换换行符:
    file-name binary
    
  • 打包工具配置:在Maven/Gradle中关闭资源过滤,防止打包时修改文件内容:
    • Maven:在pom.xml的resources节点中设置<filtering>false</filtering>
      <build>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
          </resource>
        </resources>
      </build>
      
    • Gradle:在build.gradle中设置resources的filtering为false
      sourceSets {
        main {
          resources {
            filtering = false
          }
        }
      }
      

完成上述配置后,直接使用最初的代码读取字节流,即可在任意操作系统下得到一致的结果。

2. 统一转换换行符(若无法保证文件一致性)

如果无法避免文件本身存在换行符差异,可通过字符流读取后统一转换为目标格式,比手动遍历字节数组更简洁高效:

// 读取文件内容为字符串,统一换行符为LF(\n)
String content = IOUtils.toString(new ClassPathResource("file-name").getInputStream(), StandardCharsets.UTF_8);
// 将CRLF或单独的CR统一替换为LF
content = content.replaceAll("\r\n?", "\n");
// 转换为统一的字节数组
byte[] consistentBytes = content.getBytes(StandardCharsets.UTF_8);

3. 关于私钥文件的说明

SSH私钥本质是文本格式,正常情况下换行符差异不会影响其有效性。若你的SFTP客户端对换行符敏感,使用上述统一转换方案即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:55:18