Happy New Year! Today's "best of" is the "best" code to copy file data that I've ever seen. Originally from September. --Remy


Nibbles in a byte

The great thing about Android is the low barrier to entry: thanks to open-source tooling, emulators, and the decision to build on a language often taught in schools, just about anyone can write a simple little app.

The worst thing about Android is the low barrier to entry. Just about anyone can write a simple little app, whether they know what they're doing or not. The following code snippet is intended to take bytes from an InputStream (a common paradigm for web in Java) and save them into a file.


public void download(InputStream in, String fileName) {
	Vector vector = new Vector<>();
	byte[] tmpByteArray = new byte[1024];
	while (true) {
		int r = in.read(tmpByteArray, 0, 1024);
		if (r == -1) {
			break;
		}
		for (int i = 0; i < r; i++) {
			vector.add(Byte.valueOf(tmpByteArray[i]));
		}
	}
	byte[] byteArray = new byte[vector.size()];
	for (int i = 0; i < vector.size(); i++) {
		byteArray[i] = ((Byte) vector.elementAt(i)).byteValue();
	}
	File fout = new File(this.outFileDir.getAbsolutePath(), fileName);
	FileOutputStream fos = new FileOutputStream(fout);
	BufferedOutputStream bos = new BufferedOutputStream(fos);
	bos.write(byteArray);
	bos.close();
	fos.close();
	in.close();
}
 
 

Our Anonymous submitter writes:

At first glance it doesn't look that bad, but only until you start to estimate the memory usage of this nice little code snippet.

For those not familiar with Java and its internal representation of objects a little hint: Every Byte is a Java Object and every Java Object has a memory overhead of several bytes because of memory alignment. In detail the overhead for every object is 8 bytes for a 32-bit JVM for the Android Dalvik VM.

The code copies every received byte into a Byte object and then copies it again into a byte array before writing everything into the file-system! Hence this tiny little code snippet requires about 9-10 times the file-size in memory for downloading and saving the file.

Incidentally, the last time this author had to write code for this purpose, it looked something like this:


	BufferedReader inputReader = new BufferedReader(new InputStreamReader(in));
	File destination = new File(fileName);
	FileWriter output = new FileWriter(destination)
	String line;
	while ((line = inputReader.readLine()) != null) {
		output.write(line + "\n");
	}
	
	output.close();
	in.close();