diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index a9332c94e..3149ef34b 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1592,7 +1592,7 @@ public class Base { } - // Because the Oracle JDK is 64-bit only, we lose this ability, feature, + // Because the Oracle JDK is 64-bit only, we lose this ability, feature, // edge case, headache. // /** // * Return whether sketches will run as 32- or 64-bits. On Linux and Windows, @@ -1605,10 +1605,10 @@ public class Base { // } // return nativeBits; // } - - /** + + /** * Return whether sketches will run as 32- or 64-bits based - * on the JVM that's in use. + * on the JVM that's in use. */ static public int getNativeBits() { return nativeBits; @@ -2604,6 +2604,47 @@ public class Base { } + static public void copyFile(File sourceFile, + File targetFile,Sketch.ProgressBarGUI.Task progBar, + double progress,double totalSize) throws IOException { + // Overloaded copyFile that is called whenever a Save As is being done, so that the + // ProgressBar is updated for very large files as well + BufferedInputStream from = + new BufferedInputStream(new FileInputStream(sourceFile)); + BufferedOutputStream to = + new BufferedOutputStream(new FileOutputStream(targetFile)); + byte[] buffer = new byte[16 * 1024]; + int bytesRead; + int totalRead=0; + while ((bytesRead = from.read(buffer)) != -1) { + to.write(buffer, 0, bytesRead); + totalRead += bytesRead; + if (totalRead >= 524288) //to update progress bar every 50MB + { + progress += totalRead; + progBar.setProgressBarStatus((int) Math.min( + Math.ceil((double)progress * 100.0 / (double)totalSize), 100)); + totalRead = 0; + } + } + if (sourceFile.length()>524288) { + // Update the progress bar one final time if file size is more than 50MB, + // otherwise, the update is handled either by the copyDir function, + // or directly by Sketch.ProgressBarGUI.Task.doInBackground() + progress += totalRead; + progBar.setProgressBarStatus((int) Math.min( + Math.ceil((double)progress * 100.0 / (double)totalSize), 100)); + } + from.close(); + from = null; + to.flush(); + to.close(); + to = null; + + targetFile.setLastModified(sourceFile.lastModified()); + targetFile.setExecutable(sourceFile.canExecute()); + } + /** * Grab the contents of a file as a string. */ @@ -2649,7 +2690,7 @@ public class Base { * files and potentially troublesome .svn folders. */ static public void copyDir(File sourceDir, - File targetDir,Sketch.ProgressBarGUI.Task progBar,double progress,double totalSize) throws IOException { + File targetDir) throws IOException { if (sourceDir.equals(targetDir)) { final String urDum = "source and target directories are identical"; throw new IllegalArgumentException(urDum); @@ -2664,17 +2705,48 @@ public class Base { File target = new File(targetDir, files[i]); if (source.isDirectory()) { //target.mkdirs(); - copyDir(source, target, progBar, progress, totalSize); + copyDir(source, target); target.setLastModified(source.lastModified()); } else { copyFile(source, target); - progress += source.length(); - progBar.setProgressBarStatus((int) Math.min( - Math.ceil((double)progress * 100.0 / (double)totalSize), 100)); } } } + + static public double copyDir(File sourceDir, + File targetDir,Sketch.ProgressBarGUI.Task progBar, + double progress,double totalSize) throws IOException { + // Overloaded copyDir so that the Save As progress bar gets updated when the + // files are in folders as well (like in the data folder) + if (sourceDir.equals(targetDir)) { + final String urDum = "source and target directories are identical"; + throw new IllegalArgumentException(urDum); + } + targetDir.mkdirs(); + String files[] = sourceDir.list(); + for (int i = 0; i < files.length; i++) { + // Ignore dot files (.DS_Store), dot folders (.svn) while copying + if (files[i].charAt(0) == '.') continue; + //if (files[i].equals(".") || files[i].equals("..")) continue; + File source = new File(sourceDir, files[i]); + File target = new File(targetDir, files[i]); + if (source.isDirectory()) { + //target.mkdirs(); + progress = copyDir(source, target, progBar, progress, totalSize); + progBar.setProgressBarStatus((int) Math.min( + Math.ceil((double)progress * 100.0 / (double)totalSize), 100)); + target.setLastModified(source.lastModified()); + } else { + copyFile(source, target, progBar, progress, totalSize); + // Update SaveAs progress bar + progress += source.length(); + progBar.setProgressBarStatus((int) Math.min( + Math.ceil((double)progress * 100.0 / (double)totalSize), 100)); + } + } + return progress; + } static public void copyDirNative(File sourceDir, File targetDir) throws IOException { diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 9cbadfd41..3678c9659 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -896,7 +896,8 @@ public class Sketch { } - + // Class used to handle progress bar, and run Save As in background so that + // progress bar can update without freezing public class ProgressBarGUI extends JFrame implements PropertyChangeListener { @@ -924,10 +925,10 @@ public class Sketch { long progress = 0; setProgress(0); - for (File copyable : ProgressBarGUI.this.copyItems) + for (File copyable : ProgressBarGUI.this.copyItems) { // loop to copy over the items that make sense, and to set the // current progress - { + if (copyable.isDirectory()) { Base.copyDir(copyable, new File(ProgressBarGUI.this.newFolder, @@ -936,18 +937,23 @@ public class Sketch { } else { Base.copyFile(copyable, new File(ProgressBarGUI.this.newFolder, - copyable.getName())); - progress += getFileLength(copyable); - setProgress((int) Math.min( + copyable.getName()), this,progress,totalSize); + if (getFileLength(copyable)<524288) { + // If the file length > 50MB, the Base.copyFile() function has + // been redesigned to change progress every 50MB so that + // the progress bar doesn't stagnate during that time + progress += getFileLength(copyable); + setProgress((int) Math.min( Math.ceil((double)progress * 100.0 / (double)totalSize), 100)); + } } } return null; } - public void setProgressBarStatus(int status) - { + public void setProgressBarStatus(int status) { + setProgress(status); } @@ -996,7 +1002,7 @@ public class Sketch { t.execute(); } - private long getFileLength(File f)// function to return the length of + public long getFileLength(File f)// function to return the length of // the file, or // ENTIRE directory, including the // component files