/* ******************************************* * Copyright (c) 2011 * HT srl, All rights reserved. * Project : RCS, AndroidService * File : AutoFile.java * Created : Apr 9, 2011 * Author : zeno * *******************************************/ package com.android.dvci.file; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.logging.Logger; import com.android.dvci.Status; import com.android.dvci.auto.Cfg; import com.android.dvci.evidence.EvidenceCollector; import com.android.dvci.util.ByteArray; import com.android.dvci.util.Check; import com.android.dvci.util.Execute; import com.android.dvci.util.ExecuteResult; /** * The Class AutoFlashFile. */ public final class AutoFile { /** The Constant TAG. */ private static final String TAG = "AutoFile"; //$NON-NLS-1$ private File file; private String filename; /** * Instantiates a new auto flash file. * http://developer.android.com/guide/topics * /data/data-storage.html#filesInternal * * @param filename * the filename */ public AutoFile(final String filename) { file = new File(filename); this.filename = filename; } public AutoFile(String dir, String filename) { file = new File(dir, filename); this.filename = file.getAbsolutePath(); } public AutoFile(File filesDir, String file) { this(filesDir.getAbsolutePath(), file); } /** * Reads the content of the file. * * @return the byte[] */ public byte[] read() { return read(0); } /** * Reads the content of the file, without checking the file size * this is useful for virtual files like those in /proc/ * * @return the String */ static public String getFileContents(String path) { //...checks on aFile are elided StringBuilder contents = new StringBuilder(); try { //use buffering, reading one line at a time //FileReader always assumes default encoding is OK! BufferedReader input = new BufferedReader(new FileReader(new File(path))); try { String line = null; //not declared within while loop /* * readLine is a bit quirky : it returns the content of a line * MINUS the newline. it returns null only for the END of the * stream. it returns an empty String if two newlines appear in * a row. */ while ((line = input.readLine()) != null) { contents.append(line); contents.append("\n"); } } finally { input.close(); } } catch (IOException ex) { if (Cfg.EXCEPTION) { Check.log(ex); } if (Cfg.DEBUG) { Check.log(ex);//$NON-NLS-1$ } } return contents.toString(); } /** * Read the file starting from the offset specified. * * @param offset * the offset * @return the byte[] */ public byte[] read(final int offset, int length) { length = Math.min(length, (int) file.length() - offset); InputStream in = null; if (Cfg.DEBUG) { Check.asserts(file != null, " (read) Assert failed, null file"); } if (length == 0) { return null; } try { in = new BufferedInputStream(new FileInputStream(file), length); final byte[] buffer = new byte[length]; in.skip(offset); in.read(buffer, 0, length); return buffer; } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(e);//$NON-NLS-1$ } } finally { if (in != null) { try { in.close(); } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(e);//$NON-NLS-1$ } } } } return null; } /** * Read the file starting from the offset specified. * * @param offset * the offset * @return the byte[] */ public byte[] read(final int offset) { final int length = (int) file.length() - offset; InputStream in = null; if (Cfg.DEBUG) { Check.asserts(file != null, " (read) Assert failed, null file"); } if (length == 0) { return null; } try { in = new BufferedInputStream(new FileInputStream(file), length); final byte[] buffer = new byte[length]; in.skip(offset); in.read(buffer, 0, length); return buffer; } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(e);//$NON-NLS-1$ } } finally { if (in != null) { try { in.close(); } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(e);//$NON-NLS-1$ } } } } return null; } /** * Write some data to the file. * * @param data * the data */ public void write(final byte[] data) { write(data, 0, false); } /** * Write a data buffer in the file, at a specific offset. If append is false * the content of the file is overwritten. * * @param data * the data * @param offset * the offset * @param append * the append * @return true, if successful */ public synchronized boolean write(final byte[] data, final int offset, final boolean append) { OutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(file, append), data.length - offset); out.write(data, offset, data.length - offset); out.flush(); return true; } catch (final Exception ex) { if (Cfg.EXCEPTION) { Check.log(ex); } return false; } finally { if (out != null) { try { out.close(); } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(TAG + " Error: " + e.toString());//$NON-NLS-1$ } } } } } public void write(int value) { write(ByteArray.intToByteArray(value)); } /** * Append some data to the file. * * @param data * the data */ public synchronized boolean append(final byte[] data) { if (data == null) { if (Cfg.DEBUG) { Check.log(TAG + " (append) null data"); } return true; } FileOutputStream fout = null; OutputStream out = null; try { fout = new FileOutputStream(file, true); out = new BufferedOutputStream(fout, data.length); out.write(data); out.flush(); } catch (final Exception ex) { return false; } finally { if (fout != null) { try { fout.close(); } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(TAG + " Error: " + e.toString());//$NON-NLS-1$ } } } if (out != null) { try { out.close(); } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(TAG + " Error: " + e.toString());//$NON-NLS-1$ } } } } return true; } /** * Tells if the file exists. * * @return true, if successful */ public boolean exists() { return file.exists(); } /** * The file can be read. * * @return true if readable */ public boolean canRead() { return file.canRead(); } /** * Check. if the file is a directory. //$NON-NLS-1$ * * @return true, if is directory */ public boolean isDirectory() { return file.isDirectory(); } /** * List the content of the directory. * * @return the string[] */ public String[] list() { if (Cfg.DEBUG) { Check.asserts(isDirectory(), "Should be a directory"); //$NON-NLS-1$ } return file.list(); } /** * Gets the size of the file. * * @return the size */ public long getSize() { return file.length(); } /** * Gets the file time. * * @return the file time */ public Date getFileTime() { return new Date(file.lastModified()); } public String getFilename() { return filename; } public String getName() { return file.getName(); } /** * Delete the file. */ public boolean delete() { if (file.exists()) { file.delete(); if(Cfg.DEBUG) { Check.ensures(!file.exists(), "File should be deleted"); } return true; } return false; } public boolean dropExtension(String ext) { final String filename = file.getName(); final int pos = filename.lastIndexOf(ext); final String newname = filename.substring(0, pos); final File newfile = new File(file.getParent(), newname); if (Cfg.DEBUG) { //Check.log(TAG + " (dropExtension): " + EvidenceCollector.decryptName(filename) + " -> " // + EvidenceCollector.decryptName(newname)); } final boolean ret = file.renameTo(newfile); return ret; } public void create() { write(new byte[] { 0 }); if (Cfg.DEBUG) { Check.ensures(file.exists(), "Non existing file"); //$NON-NLS-1$ } } public void write(String string) { write(string.getBytes()); } public void append(String string) { append(string.getBytes()); } public boolean rename(String newfilename) { try { final File newfile = new File(newfilename); if (newfile.exists()) { newfile.delete(); } file.renameTo(newfile); if (Cfg.DEBUG) { Check.asserts(newfile.exists(), "rename"); //$NON-NLS-1$ } } catch (final Exception ex) { if (Cfg.EXCEPTION) { Check.log(ex); } if (Cfg.DEBUG) { Check.log(ex);//$NON-NLS-1$ } return false; } return true; } public String toString() { return getFilename(); } public long lastModified() { return file.lastModified(); } public void chmod(String string) { if (Status.self().haveRoot()) { Execute.executeRoot("chmod " + string + " " + getFilename()); if (Cfg.DEBUG) { ExecuteResult ret = Execute.executeRoot("ls -l " + getFilename()); Check.log(TAG + " (chmod) result: " + ret.getStdout()); } } else { Execute.execute("chmod " + string + " " + getFilename()); } } /** The file. */ public File getFile() { return file; } }