/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.sdklib.internal.repository; import com.android.sdklib.SdkConstants; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * Helper methods used when dealing with archives installation. */ abstract class OsHelper { /** * Helper to delete a file or a directory. * For a directory, recursively deletes all of its content. * Files that cannot be deleted right away are marked for deletion on exit. * The argument can be null. */ static void deleteFileOrFolder(File fileOrFolder) { if (fileOrFolder != null) { if (fileOrFolder.isDirectory()) { // Must delete content recursively first for (File item : fileOrFolder.listFiles()) { deleteFileOrFolder(item); } } if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) { // Trying to delete a resource on windows might fail if there's a file // indexer locking the resource. Generally retrying will be enough to // make it work. // // Try for half a second before giving up. for (int i = 0; i < 5; i++) { if (fileOrFolder.delete()) { return; } try { Thread.sleep(100 /*ms*/); } catch (InterruptedException e) { // Ignore. } } fileOrFolder.deleteOnExit(); } else { // On Linux or Mac, just straight deleting it should just work. if (!fileOrFolder.delete()) { fileOrFolder.deleteOnExit(); } } } } /** * Sets the executable Unix permission (0777) on a file or folder. * <p/> * This invokes a chmod exec, so there is no guarantee of it being fast. * Caller must make sure to not invoke this under Windows. * * @param file The file to set permissions on. * @throws IOException If an I/O error occurs */ static void setExecutablePermission(File file) throws IOException { Runtime.getRuntime().exec(new String[] { "chmod", "777", file.getAbsolutePath() }); } /** * Copies a binary file. * * @param source the source file to copy * @param dest the destination file to write * @return True if the file was successfully copied. False otherwise. */ static boolean copyFile(File source, File dest) { byte[] buffer = new byte[8192]; FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(source); fos = new FileOutputStream(dest); int read; while ((read = fis.read(buffer)) != -1) { fos.write(buffer, 0, read); } return true; } catch (Exception e) { // Ignore. Simply return false below. } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { // Ignore. } } if (fos != null) { try { fos.close(); } catch (IOException e) { // Ignore. } } } return false; } }