import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test{
	static byte[] bytes = new byte[8 * 1024];
	static int cnt = 0;

	/**
	 * Copies srcFile to dstFile.
	 *
	 * @param srcFile         The source File.
	 * @param dstFile         The destination File.
	 * @param ignoreFileFlags If <code>true</code> the flags should not be
	 *                        transmitted to the copied file. (executable, readable,
	 *                        writable).
	 * @throws IOException Thrown if file copy fails.
	 */
	private static void copyFile(File srcFile, File dstFile, boolean ignoreFileFlags) throws IOException {
		File parentFolder = dstFile.getParentFile();
		if (!parentFolder.exists()) {
			if (!parentFolder.mkdirs()) {
				throw new IOException("Could not create folder: " + parentFolder);
			}
		}

		FileInputStream fis = new FileInputStream(srcFile);
		try {
			FileOutputStream fos = new FileOutputStream(dstFile);
			copyInputStreamToOutputStream(fis, fos, true);
		} finally {
			/*
			 * Streams are always closed by the "copy" method. But if the output stream
			 * cannot not be created, make sure the input stream is closed safely and
			 * silently.
			 */
			fis.close();
		}

		try {
			long srcLastModified = srcFile.lastModified();
			if (srcLastModified > 0) {
				dstFile.setLastModified(srcLastModified);
			}
			if (!ignoreFileFlags) {
				if (!srcFile.canWrite()) {
					// Set the read-only property
					dstFile.setReadOnly();
				}
				dstFile.setExecutable(srcFile.canExecute());
				dstFile.setReadable(srcFile.canRead());
				dstFile.setWritable(srcFile.canWrite());
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}

	private static void read(File file) {
		try {
			File dst = File.createTempFile("test", ".xml");
			dst.deleteOnExit();
			copyFile(file, dst, false);
			// System.err.println(file);
			FileInputStream fis = new FileInputStream(dst);
			int len = -1;
			while ((len = fis.read(bytes)) != -1) {
				for (int i = 0; i < len; i++) {
					if (bytes[i] == 0) {
						cnt++;
					}
				}
			}
			;
			fis.close();
			dst.delete();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Copies input stream content to output stream.
	 *
	 * @param is                The input stream.
	 * @param os                The output stream.
	 * @param closeOutputStream <code>true</code> to also close the output stream.
	 *                          The input stream is always closed.
	 *
	 * @throws IOException Thrown if file copy fails.
	 */
	public static void copyInputStreamToOutputStream(InputStream is, OutputStream os, boolean closeOutputStream)
			throws IOException {
		BufferedOutputStream bos = new BufferedOutputStream(os, 8000);
		BufferedInputStream bis = new BufferedInputStream(is, 8000);
		try {
			byte[] buff = new byte[8192 * 2];
			int count;
			while ((count = bis.read(buff)) != -1) {
				bos.write(buff, 0, count);
			}
		} finally {
			try {
				bis.close();
			} finally {
				if (closeOutputStream) {
					bos.close();
				} else {
					bos.flush();
				}
			}
		}
	}

	public static void main(String[] args) {
		File start = new File("D:\\DITA");
		for (int i = 0; i < 10; i++) {
			long before = System.currentTimeMillis();
			recurseRead(start);
			long after = System.currentTimeMillis();

			System.err.println("Took: " + (after - before));
			//System.err.println(cnt);
		}
	}

	private static void recurseRead(File file) {
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					recurseRead(files[i]);
				}
			}
		} else {
			read(file);
		}
	}
}