/* * Copyright (c) 2016 Ngewi Fet <ngewif@gmail.com> * * 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 org.gnucash.android.util; import android.util.Log; import org.gnucash.android.db.MigrationHelper; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; /** * Moves all files from one directory into another. * The destination directory is assumed to already exist */ public class RecursiveMoveFiles implements Runnable { File mSource; File mDestination; /** * Constructor, specify origin and target directories * @param src Source directory/file. If directory, all files within it will be moved * @param dst Destination directory/file. If directory, it should already exist */ public RecursiveMoveFiles(File src, File dst){ mSource = src; mDestination = dst; } /** * Copy file from one location to another. * Does not support copying of directories * @param src Source file * @param dst Destination of the file * @return {@code true} if the file was successfully copied, {@code false} otherwise * @throws IOException */ private boolean copy(File src, File dst) throws IOException { FileChannel inChannel = new FileInputStream(src).getChannel(); FileChannel outChannel = new FileOutputStream(dst).getChannel(); try { long bytesCopied = inChannel.transferTo(0, inChannel.size(), outChannel); return bytesCopied >= src.length(); } finally { if (inChannel != null) inChannel.close(); outChannel.close(); } } /** * Recursively copy files from one location to another and deletes the origin files after copy. * If the source file is a directory, all of the files in it will be moved. * This method will create the destination directory if the {@code src} is also a directory * @param src origin file * @param dst destination file or directory * @return number of files copied (excluding parent directory) */ private int recursiveMove(File src, File dst){ int copyCount = 0; if (src.isDirectory() && src.listFiles() != null){ dst.mkdirs(); //we assume it works everytime. Great, right? for (File file : src.listFiles()) { File target = new File(dst, file.getName()); copyCount += recursiveMove(file, target); } src.delete(); } else { try { if(copy(src, dst)) src.delete(); } catch (IOException e) { Log.d(MigrationHelper.LOG_TAG, "Error moving file: " + src.getAbsolutePath()); } } Log.d("RecursiveMoveFiles", String.format("Moved %d files from %s to %s", copyCount, src.getPath(), dst.getPath())); return copyCount; } @Override public void run() { recursiveMove(mSource, mDestination); } }