0

I want to transfer a file from C# to a java webservice which accepts base64 strings. The problem is that when I encode the file using the c# Convert class, it produces a string based on a little endian unsigned byte[].

In Java byte[] are signed / big endian. When I decode the delivered string, I get a different byte[] and therefor the file is corrupt.

How can I encode a byte[] in C# to a base64, which is equal to the byte[] that is decoded in java using the same string?

C# side:

byte[] attachment = File.ReadAllBytes(@"c:\temp\test.pdf");
String attachmentBase64 = Convert.ToBase64String(attachment, Base64FormattingOptions.None);

Java side:

  @POST
  @Path("/localpdf")
  @Consumes("text/xml")
  @Produces("text/xml")
  public String getExtractedDataFromEncodedPdf(@FormParam("file") String base64String) {

      if(base64String == null) return null;


      byte[] data = Base64.decodeBase64(base64String.getBytes());

      FileOutputStream ms;
    try {
        ms = new FileOutputStream(new File("C:\\Temp\\test1234.pdf"));
        ms.write(data);
        ms.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

File test1234.pdf is corrupt.

Stefan
  • 15
  • 3
  • Base64 does not care about endianness. See http://stackoverflow.com/a/12025216/900547 –  Jul 09 '15 at 12:36

1 Answers1

1

"Signed" and "big-endian" are very different things, and I believe you're confusing yourself.

Yes, bytes are signed in Java and unsigned in C# - but I strongly suspect you're getting the same actual bits in both cases... it's just that a bit pattern of (say) 11111111 represents 255 in C# and -1 in Java. Unless you're viewing the bytes as numbers (which is rarely useful) it won't matter - it certainly doesn't matter if you just use the bytes to write out a file on the Java side.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks for your clarification. What I do is converting a PDF in C# to base64 String. Then send it to the webservice, decode it there to a byte[] and write it to disk. The file is corrupt and I assumed it is because the bytes "look" different. So, you are saying that this is not the reason. Could you imagine what the problem is? – Stefan Jul 09 '15 at 13:23
  • I already checked it with textfiles and they are not a problem. – Stefan Jul 09 '15 at 13:25
  • @Stefan: we couldn't see any of your code, so we don't know where the problem might be. Now that you've posted code, I can take a closer look when I'm back at a laptop. It would help if you'd post sample failure data. How can you tell the file is corrupt? – Jon Skeet Jul 09 '15 at 13:57
  • I just created a simple PDF containing some text using PDF-Creator and saved it as test.pdf. I can open it with Adobe Acrobat Reader. After sending the file to the webservice and decoding it, it is not longer readable with Adobe Acrobat Reader. This is how I check it. – Stefan Jul 09 '15 at 14:25
  • @Stefan: So now you need to start looking carefully at every step of the process - look at the bytes at the start and at the end. Look at the bytes in memory when debugging the C# code. Look at the bytes in memory when debugging the Java code. Check file lengths. Check the strings you get... all that sort of thing. See http://codeblog.jonskeet.uk/2014/01/20/diagnosing-issues-with-reversible-data-transformations/ – Jon Skeet Jul 09 '15 at 15:29
  • Hey Jon. I analyzed the base64 strings created by java and c# and found the problem. The base64 string in C# contains blanks where as the java string contains plusses.Replacing the blanks with plusses makes the file readable. More information here: [link](http://stackoverflow.com/questions/16527350/java-base64-encoded-string-vs-net-base64-encoded-string) Thank you for you help! – Stefan Jul 09 '15 at 16:15
  • @Stefan: I wouldn't expect `Convert.ToBase64` to include spaces. Are you sure this isn't a problem of URL encoding? – Jon Skeet Jul 09 '15 at 16:17
  • You're right. It's a problem of the URL encoding. The string contains blanks instead of plusses when it arrives at the webservice. It seems that base64 encoding is not for using in urls. According to this [link](http://stackoverflow.com/questions/1228701/code-for-decoding-encoding-a-modified-base64-url) you can make it safe for urls using HttpServerUtility.UrlTokenEncode. The problem is that there might be no equivalent in java. – Stefan Jul 10 '15 at 06:19
  • @Stefan: You don't *need* the equivalent in Java, because the server will decode the URL for you. An alternative is to use a web-safe version of base64 - there are plenty of options there, with C# and Java support. – Jon Skeet Jul 10 '15 at 06:24