I have a Spring Boot app that runs from a WAR file, and I test it in different Operating Systems. It reads a file from the "resources" directory (this is the path within the WAR: "/WEB-INF/classes/file-name") by performing the following steps:
1. Get the InputStream:
InputStream fileAsInputStream = new ClassPathResource("file-name").getInputStream();
2. Convert the InputStream to ByteArray:
byte[] fileAsByteArray = IOUtils.toByteArray(fileAsInputStream );
The issue is that the content of the obtained Byte Array is different between Operating Systems, causing inconsistencies in further operations. The reason for this is that the file contains newline characters ("\n" = 0x0A = 10
in Linux, and "\r\n" = 0x0A 0x0D = 10 13
in Windows). The differences across Operating Systems are explained for example in this thread: What are the differences between char literals '\n' and '\r' in Java?
This is an example where the Byte Arrays have different contents:
- When app runs on Linux: [114, 115, 97, 10, 69, 110] => 10 is the
"\n"
- When app runs on Windows: [114, 115, 97, 13, 10, 69, 110] => 13 10 is the
"\r\n"
So between these two OSs, the 10
is the same with 13 10
. The file is always the same (because it is a Private Key used for establishing the SFTP communication). Differs only the Operating System from which the code is being run.
Is there a solution to obtain the same Byte Array, regardless of the Operating System from which the code is being run?
One working workaround would be to map the newline character to the same byte. So to iterate through the array, and to replace each 10
(for example) with 13 10
.
Another solution that was tried is using StandardCharsets.UTF_8
, but the elements of the arrays are still different:
IOUtils.toByteArray(new BufferedReader(new InputStreamReader(new ClassPathResource("file-name").getInputStream())), StandardCharsets.UTF_8)