0

I have tried a lot with many ways to write a program that : write a one byte value in a file as it is.. for example write 01010101 in a file.. then i want to read the file and print what i wrote.So it should display 01010101. None of my codes worked so. Any help? Because i am writing a compression program it essential to be 1 byte and not 8

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main2 {
    public static void main(String[] args) throws Exception {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("Text.t"));
        dos.writeBytes(String.valueOf(01010101));
        File file = new File("Text.t");
        BufferedReader br = new BufferedReader(
            new InputStreamReader(
                new FileInputStream(file)));
        System.out.println(br.readLine());
        dos.close();
        br.close();

    }
}

It works well with binary code that starst with 1 but with 0 not.. for example for 01010101 it shows 266305

2 Answers2

3

The problem with "It works well with binary code that starst with 1 but with 0 not.. for example for 01010101 it shows 266305" is that 01010101 is an octal literal and is read in by the compiler as base-8 (aka Octal).

Use 1010101 when writing the literal - leading zeros mean nothing to numbers; but they do mean something to how the Java code is parsed!

Decimal numbers that are displayed as "00xyz" are often zero-padded, which is applied to the string representation; the number itself is xyz.


From the comment I believe the desired operation is to use a binary literal. You'll have to emit this using a "bit converter" to display as expected - the bit converter will take the value of eg. 0b11 (integer 3) and turn it into a string "11". You may also want to apply a padding with an assumed output width - again, 0b01 == 0b1 and the leading 0 means nothing to an integer.

The following will emit the decimal string representation of the huffman bit sequence, without any leading zeros. However this when paired with above should get you off on the right track.

 dos.writeBytes(String.valueOf(0b01001010));
Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
  • i am writing huffman code so every 0 or 1 is very important. i cannot write 1010101 ... for example the letter A may be encoded 00000000 . –  Jan 09 '15 at 16:04
  • The leading 0 of integers mean nothing. It is in your head. Any such leading 0 is an artifact of a representation of such. Usually when talking about something like huffman there is an implicit 'length' of used bits [grossly simplifying] that is shown in algorithm papers (which show the *bits* and not an *integer value*) - integers in Java have no such notion. – user2864740 Jan 09 '15 at 16:04
  • yes but i am telling you again.. i am writing huffman code so when i read it back when it sees 001 this may be letter b when it sees 1 this may be letter g –  Jan 09 '15 at 16:06
  • I'm saying you're misunderstanding integers - and the representation of such. First off, the *integer* value `int i = 101` is gibberish to huffman encoding (well it likely means something but does not represent the tree "as it looks"). However, the sequence of *bits* {0,1,0,1} means something. Did you mean to use a [binary literal](http://docs.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html) instead? – user2864740 Jan 09 '15 at 16:07
  • If you want to write the leading zeroes, then you need to write them as strings or something. If you just use something like `int i = 0000000`, the compiler will see that and say "Okay, I have an octal literal. A bunch of zeroes. So zero." It will ignore them. Put them inside a string if you want to keep them and print them. – scott_fakename Jan 09 '15 at 16:09
  • yes you are right.. you were talkin about it integers... yes for integers is gibberish the leading zeros.. but in my case it really matters.. so what can i do?i dony mean in my code.. because there i am using integer so.. there i problem.. –  Jan 09 '15 at 16:11
  • i i put them in astring for example 00000 is 5 bytes.. too many... i am writing a compression program –  Jan 09 '15 at 16:12
  • @Panagiotis123 Huffman encoders count the encoding bits when they run. This is not represented implicitly in integers. – user2864740 Jan 09 '15 at 16:16
  • @user2864740 sorry i could not understand the bit converter . could you please edit your post and write the code that you mean? –  Jan 09 '15 at 16:31
  • 1
    Since you are dealing with Huffman codes, you should think about the encoded strings as a sequence of bits, not as numbers. That is, if you write to a text file "01010101" you are using 8 bytes instead of 1 which completely defeats the purpose of compression. This is because you are converting an integer to a string and then writing the bytes in that string to file. You need to write the integer (or byte) directly to the file, e.g., using `writeByte`. – Giovanni Botta Jan 09 '15 at 16:36
  • To add to that, if you get a chance to find [Sedgewick's algorithm book](https://books.google.com/books?id=idUdqdDXqnAC&printsec=frontcover&dq=algorithms&hl=en&sa=X&ei=igOwVOaFIpGTNvuphJgG&ved=0CDEQ6AEwAg#v=onepage&q=algorithms&f=false), it has very clear explanations and good java code to do exactly what you are trying to. – Giovanni Botta Jan 09 '15 at 16:37
0

I would use a Byte representation for radix 2 e.g. Byte.parseByte("00010001", 2). But the problem is Java's primitives are signed numbers so it won't work for negative values (when first digit is 1), thus Byte.parseByte("10010011", 2) will throw a NumberFormatException.

The trick here is to initially replace leading digit (if it is 1, with 0), parse it and then set the bit again to 1. Then store this byte to your file.

private static byte binaryStringToByte(String s) {
    //also check for null, length = 8, contain 0/1 only etc.
    if (s.startsWith("0")) {
        return Byte.parseByte(s, 2);
    } else {
        StringBuilder sBuilder = new StringBuilder(s);
        sBuilder.setCharAt(0, '0');
        byte temp = Byte.parseByte(sBuilder.toString(), 2);
        return (byte) (temp | (1 << 7));
    }
}

Then, to get the binary String representation of a byte use this code:

byte b = binaryStringToByte("10001000");
String s1 = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
Kostas Kryptos
  • 4,081
  • 2
  • 23
  • 24
  • Your code is little difficult...what method do you suggest me to use in order to write in the file? i would write the string s1? –  Jan 09 '15 at 17:11
  • no, you should store the byte returned from binaryStringToByte. check this http://stackoverflow.com/questions/4350084/byte-to-file-in-java – Kostas Kryptos Jan 09 '15 at 17:18