1

This is basically what I am trying to do.

I wanna take a File

Turn it into a Byte Array

Turn it into a String

Store it in a MySQL Table

Retrieve the String

Turn it back into a Byte Array

Turn it back into a File

Now, I have some code for you, which I tried to comment as best as I could. My problem is, that the file I get at the end of this code, doesn't come out right. It's missing information. It's a text file, so I should be able to tell whether the file is complete or not.

As far as I can see, it looks like I only get the last part of the file, and not the entire file. I am pretty sure I messing something up badly somewhere in this conversion. If you got suggestions on how to do this conversion and retrieval more efficiently (Still keeping the Database and all that in mind), please let me know as well!

The code is listed below

import java.io.*;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class main {
    public static void main(String[] args) {
        // The file we want to save.
        File f = new File("build.xml");
        try {
            // Make it into a byte array first
            FileInputStream fis = new FileInputStream(f);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            try {
                for(int readNum; (readNum = fis.read(buf)) != -1;) {
                    bos.write(buf, 0, readNum);
                    System.out.println("read " + readNum + " bytes,");
                }
                StringBuilder s = new StringBuilder();
                // Now we simulate making it into a String, for easier storage
                // in a database.
                for(byte b : buf) {
                    // for debugging
                    s.append(b).append(",");
                    System.out.print(b +",");
                }
                // Now we want to retrieve the file from the database as a string
                File someFile = new File("build2.xml");
                FileOutputStream fos = new FileOutputStream(someFile);
                // We count how many bytes there are in this string.
                // One byte per Token.
                StringTokenizer st = new StringTokenizer(s.toString(),",");
                buf = new byte[st.countTokens()];
                int i = 0;
                StringBuilder t = new StringBuilder();
                // Now we parse out all Bytes from the string, and put them into
                // the prepared byte array.
                while(st.hasMoreTokens()) {
                    byte b = Byte.parseByte(st.nextToken());
                    System.out.print(b + ",");
                    buf[i] = b;
                    i++;
                    // for debugging
                    t.append(b).append(",");
                }
                // Here I print true if both strings are exactly the same
                // which they should be, which means that the bytes are intact
                // before and after conversion.
                System.out.println("\n" +(t.toString().equals(s.toString()) ? true : false));
                // Here we would make the physical file on the machine.
                fos.write(buf);
                fos.flush();
                fos.close();
            } catch (IOException ex) {
                Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

http://pastebin.com/699yuE8f

Venki
  • 1,419
  • 5
  • 28
  • 38
OmniOwl
  • 5,477
  • 17
  • 67
  • 116

3 Answers3

2

Your approach is totally ignoring encodings, which is not a good thing. Characters are not equal to or equivalent to bytes.

If you have to do it in the sequence you describe, then create the string by something like this:

String intermediateString = new String(theByteArray,
                                       theSameEncodingTheFileWasCreatedWith);

Likewise, when you convert the string back into bytes, get the bytes like this:

byte[] bytesToSave = intermediateString.getBytes(theSameEncodingTheFileWasCreatedWith);

But besides any of that, what's the point of using the string at all? Why not just store the bytes right into the database?

QuantumMechanic
  • 13,795
  • 4
  • 45
  • 66
  • I've never stored bytes in a Database before, so I wanted to try and store it as something more familiar, for shits and giggles. But I've turned a byte array into a file before, without having to think of encoding so..yeah. – OmniOwl May 17 '12 at 16:40
  • When saving a byte array as a file you don't have care about encodings. Bytes are bytes. The need for encoding comes when a string is in the middle of the process. bytes -> string and string -> bytes means you have to deal with encodings. – QuantumMechanic May 17 '12 at 16:42
  • @Vipar: It makes a big difference what kind of bytes you're trying to store. QuantumMechanic is right, `char` != `byte`! Are you trying to store *the text that is in the file* to the database, or are you trying to store *textual data that will enable you to reconstitute the file*? And if you want the latter, why not just store the actual bytes as a BLOB? – Daniel Pryden May 17 '12 at 16:43
  • Because I am fairly new to this approach. How does a BLOB work in a MySQL DB? Is it a byte representation? – OmniOwl May 17 '12 at 16:44
  • @Vipar: BLOB is an acronym for Binary Large OBject. Check the MySQL documentation, there is plenty of information there. If you're still stuck, then feel free to open a new question here. – Daniel Pryden May 17 '12 at 16:49
  • Thanks for the information. I have accepted this as the answer to my problem. I will look into adding it as a BLOB then, rather than String. – OmniOwl May 17 '12 at 16:50
1

You simply messed up the string creation, and you don't read the bos but the buf.

            for(byte b : >>buf<<) {
                // for debugging
                s.append(b).append(",");
                System.out.print(b +",");
            }

Otherwise I am not convinced that it will work or it is a good solution. Why can't you just store it simply in the database?

Matzi
  • 13,770
  • 4
  • 33
  • 50
  • Because, I wanted to store it as plain text, and not as physical files. – OmniOwl May 17 '12 at 16:37
  • 1
    @Vipar: Storing arbitrary binary data as strings is a well-known problem. The normal solution is to use something like [base64](http://en.wikipedia.org/wiki/Base64) instead of inventing your own encoding. – Daniel Pryden May 17 '12 at 16:41
0

The code you shared is IMHO more complicated as it had to be.

Why do you read your text on byte-level if you are only interested in it's String representation?

I would prefer to read the file using an InputStreamReader. That allows you to directly operate on characters.

Robert
  • 39,162
  • 17
  • 99
  • 152
  • No need to be harsh. I am just shooting in the dark here. Thanks for the input though. – OmniOwl May 17 '12 at 16:42
  • I am not sure why you think my answer is harsh. I though a direct answer directly gets you to the point. The longer a code gets the more possibilities a coder gets for placing bugs in it. – Robert May 17 '12 at 17:04