Say you have a boolean[]
boolean[] ar = {true,false,false,true,false,true,true,true,false,true,false,false,false,true,true};
and you want to write this to a disk, and you don't care how its is implemented in memory.
public static void main(String... args) throws IOException {
boolean[] ar = {true, false, false, true, false, true, true, true, false, true, false, false, false, true, true};
FileOutputStream out = new FileOutputStream("test.dat");
writeBooleans(out, ar);
out.close();
FileInputStream in = new FileInputStream("test.dat");
boolean[] ar2 = new boolean[ar.length];
readBooleans(in, ar2);
in.close();
System.out.println(Arrays.toString(ar));
System.out.println(Arrays.toString(ar2));
System.out.println("The file size was "+new File("test.dat").length()+" bytes.");
}
private static void writeBooleans(OutputStream out, boolean[] ar) throws IOException {
for (int i = 0; i < ar.length; i += 8) {
int b = 0;
for (int j = Math.min(i + 7, ar.length-1); j >= i; j--) {
b = (b << 1) | (ar[j] ? 1 : 0);
}
out.write(b);
}
}
private static void readBooleans(InputStream in, boolean[] ar) throws IOException {
for (int i = 0; i < ar.length; i += 8) {
int b = in.read();
if (b < 0) throw new EOFException();
for (int j = i; j < i + 8 && j < ar.length; j++) {
ar[j] = (b & 1) != 0;
b >>>= 1;
}
}
}
prints
[true, false, false, true, false, true, true, true, false, true, false, false, false, true, true]
[true, false, false, true, false, true, true, true, false, true, false, false, false, true, true]
The file size was 2 bytes.
but if I look at how big the file actually is
$ ls -l test.dat
-rw-rw-r-- 1 peter peter 2 2012-02-19 14:04 test.dat
$ du -h test.dat
4.0K test.dat
It says the length is 2 bytes, but the disk space used is actually 4 KB.
Note: About 1 minute of your time is worth about the same as 80 MB of SSD (expensive disk, more for HDD) So if you don't think you will be saving at least 80 MB by using this, you could be wasting your time. ;)
You can use BitSet, which can take 16x less space as each character is 16-bit.