/* * $Id: VMFile.java 5226 2009-04-06 14:55:27Z lsantha $ * * Copyright (C) 2003-2009 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package java.io; import org.jnode.java.io.VMFileHandle; import gnu.classpath.SystemProperties; import gnu.java.io.PlatformHelper; /** * @author Michael Koch (konqueror@gmx.de) */ public final class VMFile { // FIXME: We support only case sensitive filesystems currently. static final boolean IS_CASE_SENSITIVE = true; static final boolean IS_DOS_8_3 = false; /* * This native method does the actual work of getting the last file * modification time. It also does the existence check to avoid the overhead * of a call to exists() */ static long lastModified(String path) { try { return VMIOUtils.getAPI().getLastModified(getNormalizedPath(path)); } catch (IOException ex) { return 0; } } /* * This native method sets the permissions to make the file read only. */ static boolean setReadOnly(String path) { try { VMIOUtils.getAPI().setReadOnly(getNormalizedPath(path)); return true; } catch (IOException ex) { return false; } } /** * This method is used to create a temporary file */ static boolean create(String path) throws IOException { // moved from JNode File.createInternal(File file) v1.3 : if (exists(path)) return false; VMFileHandle vmFileHandler = VMIOUtils.getAPI().open(getNormalizedPath(path), VMOpenMode.WRITE); vmFileHandler.close(); return true; } /* * This native function actually produces the list of file in this directory */ static String[] list(String path) { try { return VMIOUtils.getAPI().list(getNormalizedPath(path)); } catch (IOException ex) { return new String[0]; } } /* * This native method actually performs the rename. */ static boolean renameTo(String targetpath, String destpath) { try{ //todo improve it FileInputStream fis = new FileInputStream(targetpath); FileOutputStream fos = new FileOutputStream(destpath); byte[] buf = new byte[64*1024]; int c = 0; while((c = fis.read(buf)) >= 0){ fos.write(buf, 0, c); } fis.close(); fos.close(); return new File(targetpath).delete(); } catch(Exception e){ return false; } } /* * This native method actually determines the length of the file and handles * the existence check */ static long length(String path) { try { return VMIOUtils.getAPI().getLength(getNormalizedPath(path)); } catch (IOException ex) { return 0; } } /* * This native method does the actual checking of file existence. */ static boolean exists(String path) { try { return VMIOUtils.getAPI().fileExists(getNormalizedPath(path)); } catch (IOException ex) { return false; } } /* * This native method handles the actual deleting of the file */ static boolean delete(String path) { try { VMIOUtils.getAPI().delete(getNormalizedPath(path)); return true; } catch (IOException ex) { return false; } } /* * This method does the actual setting of the modification time. */ static boolean setLastModified(String path, long time) { try { VMIOUtils.getAPI().setLastModified(getNormalizedPath(path), time); return true; } catch (IOException ex) { return false; } } /* * This native method actually creates the directory */ static boolean mkdir(String path) { try { return VMIOUtils.getAPI().mkDir(getNormalizedPath(path)); } catch (IOException io) { return false; } } /* * This native method does the actual check of whether or not a file is a * plain file or not. It also handles the existence check to eliminate the * overhead of a call to exists() */ static boolean isFile(String path) { try { return VMIOUtils.getAPI().isFile(getNormalizedPath(path)); } catch (IOException ex) { return false; } } /** * This native method checks file permissions for writing */ static synchronized boolean canWrite(String path) { try { return VMIOUtils.getAPI().canWrite(getNormalizedPath(path)); } catch (IOException ioe) { return (false); } } /** * This methods checks if a directory can be written to. */ static boolean canWriteDirectory(File dir) { try { String filename = IS_DOS_8_3 ? "tst" : "test-dir-write"; File f = new File(dir, filename); for(int i = 0; i < 100 && f.exists(); i ++){ f = new File(dir, filename + "_" + i); } if(f.exists()) return false; //File test = f.crFile.createTempFile(filename, null, dir); return (f.createNewFile() && f.delete()); } catch (IOException ioe) { return false; } } /** * This native method checks file permissions for reading */ static synchronized boolean canRead(String path) { try { return VMIOUtils.getAPI().canRead(getNormalizedPath(path)); } catch (IOException ex) { return false; } } static synchronized boolean canExecute(String path) { try { return VMIOUtils.getAPI().canExecute(getNormalizedPath(path)); } catch (IOException ex) { return false; } } public static boolean setReadable(String path, boolean enable, boolean owneronly) { try { return VMIOUtils.getAPI().setReadable(getNormalizedPath(path), enable, owneronly); } catch (IOException ex) { return false; } } public static boolean setWritable(String path, boolean enable, boolean owneronly) { try { return VMIOUtils.getAPI().setWritable(getNormalizedPath(path), enable, owneronly); } catch (IOException ex) { return false; } } public static boolean setExecutable(String path, boolean enable, boolean owneronly) { try { return VMIOUtils.getAPI().setExecutable(getNormalizedPath(path), enable, owneronly); } catch (IOException ex) { return false; } } /* * This method does the actual check of whether or not a file is a directory * or not. It also handle the existence check to eliminate the overhead of a * call to exists() */ static boolean isDirectory(String path) { try { return VMIOUtils.getAPI().isDirectory(getNormalizedPath(path)); } catch (IOException ex) { return false; } } /** * This method returns an array of filesystem roots. Some operating systems * have volume oriented filesystem. This method provides a mechanism for * determining which volumes exist. GNU systems use a single hierarchical * filesystem, so will have only one "/" filesystem root. * * @return An array of <code>File</code> objects for each filesystem root * available. * @since 1.2 */ static File[] listRoots() { // ClassPath implementation // File[] roots = new File[1]; // roots[0] = new File("/"); // return roots; // JNode implementation try { return VMIOUtils.getAPI().getRoots(); } catch (IOException ex) { return new File[0]; } } /** * This method tests whether or not this file represents a "hidden" file. On * GNU systems, a file is hidden if its name begins with a "." character. * Files with these names are traditionally not shown with directory listing * tools. * * @return <code>true</code> if the file is hidden, <code>false</code> * otherwise. * @since 1.2 */ static boolean isHidden(String path) { // FIXME: this only works on UNIX return getName(path).startsWith("."); } /** * This method returns the name of the file. This is everything in the * complete path of the file after the last instance of the separator * string. * * @return The file name */ static String getName(String path) { int pos = PlatformHelper.lastIndexOfSeparator(path); if (pos == -1) return path; if (PlatformHelper.endWithSeparator(path)) return ""; return path.substring(pos + File.separator.length()); } /** * This method returns a canonical representation of the pathname of the * given path. The actual form of the canonical representation is different. * On the GNU system, the canonical form differs from the absolute form in * that all relative file references to "." and ".." are resolved and * removed. * <p> * Note that this method, unlike the other methods which return path names, * can throw an IOException. This is because native method might be required * in order to resolve the canonical path * * @exception IOException * If an error occurs */ final static String toCanonicalForm(String path) throws IOException { // FIXME: this only works on UNIX return PlatformHelper.toCanonicalForm(path); } /** * Make an absolate and canonical path from the given path. * @param path * @return */ public static final String getNormalizedPath(String path) { if (!path.startsWith(File.separator)) { path = SystemProperties.getProperty("user.dir") + File.separator + path; } path = PlatformHelper.toCanonicalForm(path); // Strip leading seperator if (path.startsWith(File.separator)) { path = path.substring(1); } // Strip trailing seperator if (path.endsWith(File.separator)) { path = path.substring(0, path.length()-1); } return path; } public static long getTotalSpace(String path) { try { return VMIOUtils.getAPI().getTotalSpace(getNormalizedPath(path)); } catch (IOException ex) { return 0L; } } public static long getFreeSpace(String path) { try { return VMIOUtils.getAPI().getFreeSpace(getNormalizedPath(path)); } catch (IOException ex) { return 0L; } } public static long getUsableSpace(String path) { try { return VMIOUtils.getAPI().getUsableSpace(getNormalizedPath(path)); } catch (IOException ex) { return 0L; } } }