Jairo Bustos
Jairo Bustos

Reputation: 31

Converting int to byte[] in android

I am using the write() method in order to write in a file of the external storage. This method only accepts byte[] as an input. I have tried passing a String and I get an error message ("The method write(int) in the type FileOutputStream is not applicable for the arguments String"). If I pass an int, I don't get error but in the file nothing is written. The value I get from calling getNumSentPackets() is an int and I need to convert it to byte[]. I have been looking at other questions already answered here and I have tried the ByteBuffer option but the result I get in the file is not what I want, this means, I don't get the number of sent packets. Can anybody help me, please?

This is my code:

     public void createFile(String name) {

    try {
      String filename = name;
      File myFile = new File(Environment.getExternalStorageDirectory(), filename);
      if (!myFile.exists())
        myFile.createNewFile();
      String title = "FLOODING RESULTS FILE\n\n";
      String sent = "Number of sent packets\n";
      FileOutputStream fos;
      byte[] data = title.getBytes();
      byte[] intSent = sent.getBytes();
      int numSent = mSender.getNumSentPackets();
      byte[] numSentBytes = ByteBuffer.allocate(10).putInt(numSent).array();
      try{
      fos = new FileOutputStream(myFile);
      fos.write(data);
      fos.write(intSent);
      fos.write(numSentBytes);
      fos.flush();
      fos.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}

public static int getNumSentPackets() {
  return nSentPackets;
}

The expected output file would be as follows:

FLOODING RESULTS FILE

Number of sent packets 200

200 is only an example, meaning with this that I would like to see there a number which would correspond to the total number of sent packets.

Thank you in advance.

Upvotes: 1

Views: 228

Answers (3)

zapl
zapl

Reputation: 63945

The text representation of "200" requires you to write 3 characters. All files are just a bunch of bytes in the end so there needs to be a mapping from character to some byte value. Assuming ASCII(*) the data to write into the file would be

//                    '2','0','0'
byte[] textVersion = { 50, 48, 48 } 

int on the other hand is a 32bit numeric value, i.e. has 4 bytes and 200 is equivalent to

byte[] intVersion = { 0, 0, 0, 200 }

When using a ByteBuffer, you'll get this. If you write that into a file and a text viewer tries to display that it would display something like ◻◻◻Č if you're lucky. A 0 is actually a non printable control character and therefore often either skipped when printing or replaced with strange looking character like boxes. The 200 would be equivalent to Č in Windows-CP1250. It has no meaning on it's own when interpreted as UTF8 - it's the start of a 2 byte sequence and so the next 2 byte are required to determine which character to display.

You could have used

String.valueOf(200).getBytes( /* you should specify which encoding to use here */ );

which will create the "200" string first, then return you the required bytes for those 3 characters.

You should however use Java's character based IO facility: The numerous (and confusing) Reader & Writer implementations. They all(*^2) wrap an InputStream or OutputStream in the end and do the text to byte conversion for you.

PrintWriter is probably the most convenient to use but not without flaw: https://stackoverflow.com/a/15803472/995891 FileWriter should be avoided because you can't specify the encoding

The longer alternative route would be

BufferedWriter writer = new BufferedWriter(
        new OutputStreamWriter(
             new FileOutputStream(file), encoding));
writer.write("Hello ");
writer.write(String.valueOf(200));
writer.newLine();

(*) most encodings are ASCII compatible for the first 127 characters which basically covers normal english text.

(*^2) nothing forces a Writer to output the characters into a stream, e.g. StringWriter. But they are used mostly that way.

Upvotes: 0

SirDarius
SirDarius

Reputation: 42869

As I am a lazy developer, I like to use the existing facilities in my languages of choice, for example, for java, a PrintWriter.

public void createFile(String filename) {
    try {
      File myFile = new File(Environment.getExternalStorageDirectory(), filename);

      PrintWriter out = new PrintWriter(myFile); // this will create the file if necessary

      out.println("FLOODING RESULTS FILE");
      out.println();
      out.print("Number of sent packets ");
      out.println(mSender.getNumSentPackets());
      out.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

This is much easier to read and maintain than your current approach, and looks more idiomatic.

Upvotes: 1

Kevin Tan
Kevin Tan

Reputation: 1048

ByteBuffer.allocate(capacity).putInt(yourInt).array();

Upvotes: 0

Related Questions