Browse Source

Added the init() method to Task

Added the "if" attribute to Target that executes it if and only if the property specified in the attribute is set

There might be better ways of doing it and don't consider this carved in stone, but it works, it's simple and vital for Cocoon.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267599 13f79535-47bb-0310-9956-ffa450edef68
master
Stefano Mazzocchi 25 years ago
parent
commit
ba22b3de5a
4 changed files with 367 additions and 358 deletions
  1. +2
    -1
      src/main/org/apache/tools/ant/Project.java
  2. +257
    -254
      src/main/org/apache/tools/ant/ProjectHelper.java
  3. +47
    -41
      src/main/org/apache/tools/ant/Target.java
  4. +61
    -62
      src/main/org/apache/tools/ant/Task.java

+ 2
- 1
src/main/org/apache/tools/ant/Project.java View File

@@ -176,10 +176,11 @@ public class Project {
log("Setting project property: " + name + " to " +
value, MSG_VERBOSE);
userProperties.put(name, value);
properties.put( name,value);
properties.put(name, value);
}

public String getProperty(String name) {
if (name == null) return null;
String property = (String) properties.get(name);
return property;
}


+ 257
- 254
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -9,7 +9,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -17,15 +17,15 @@
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
@@ -61,7 +61,7 @@ import java.lang.reflect.*;
import java.util.*;
import org.xml.sax.SAXException;
import org.w3c.dom.*;
/**
* Configures a Project (complete with Targets and Tasks) based on
* a XML build file.
@@ -72,281 +72,284 @@ import org.w3c.dom.*;
public class ProjectHelper {

public static void configureProject(Project project, File buildFile)
throws BuildException
throws BuildException
{

// XXX
// need to get rid of the DOM layer and use SAX
Document doc;
try {
doc=Parser.getParser(project).parse(buildFile);
} catch (IOException ioe) {
String msg = "Can't open config file: " + buildFile +
" due to: " + ioe;
throw new BuildException(msg);
} catch (SAXException se) {
String msg = "Can't open config file: " + buildFile +
" due to: " + se;
throw new BuildException(msg);
}
Element root = doc.getDocumentElement();
// sanity check, make sure that we have the right element
// as we aren't validating the input
if (!root.getTagName().equals("project")) {
String msg = "Config file is not of expected XML type";
throw new BuildException(msg);
}
project.setName(root.getAttribute("name"));
project.setDefaultTarget(root.getAttribute("default"));
String baseDir = project.getProperty("basedir");
if (baseDir == null) {
baseDir = root.getAttribute("basedir");
if (baseDir.equals("")) {
// Using clunky JDK1.1 methods here
baseDir = new File(buildFile.getAbsolutePath()).getParent();
}
}
project.setBasedir(baseDir);
// set up any properties that may be in the config file
// configureProperties(project, root);
// set up any task defs that may be in the config file
// configureTaskDefs(project, root);
// set up the targets into the project
init(project, root );
configureTargets(project, root);
// XXX
// need to get rid of the DOM layer and use SAX
Document doc;
try {
doc=Parser.getParser(project).parse(buildFile);
} catch (IOException ioe) {
String msg = "Can't open config file: " + buildFile +
" due to: " + ioe;
throw new BuildException(msg);
} catch (SAXException se) {
String msg = "Can't open config file: " + buildFile +
" due to: " + se;
throw new BuildException(msg);
}
Element root = doc.getDocumentElement();
// sanity check, make sure that we have the right element
// as we aren't validating the input
if (!root.getTagName().equals("project")) {
String msg = "Config file is not of expected XML type";
throw new BuildException(msg);
}
project.setName(root.getAttribute("name"));
project.setDefaultTarget(root.getAttribute("default"));
String baseDir = project.getProperty("basedir");
if (baseDir == null) {
baseDir = root.getAttribute("basedir");
if (baseDir.equals("")) {
// Using clunky JDK1.1 methods here
baseDir = new File(buildFile.getAbsolutePath()).getParent();
}
}
project.setBasedir(baseDir);
// set up any properties that may be in the config file
// configureProperties(project, root);
// set up any task defs that may be in the config file
// configureTaskDefs(project, root);
// set up the targets into the project
init(project, root );
configureTargets(project, root);
}

/** Read and execute init - all other targets will be loaded after ( to
* make sure all properties are set ).
*
*
*/
private static void init(Project project, Element root)
throws BuildException
throws BuildException
{
// Hack - all tasks outside init target will be added to init
// ( will be removed when / if build.xml will start using init )
Target initTarget = new Target();
initTarget.setProject(project);
initTarget.setName( "init" );
project.addTarget( "init", initTarget );
configureTasks( project, initTarget, root );
NodeList list = root.getElementsByTagName("target");
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element)list.item(i);
String targetName = element.getAttribute("name");
if( targetName.equals("init") )
configureTasks(project, initTarget, element);
}
initTarget.execute();
// Hack - all tasks outside init target will be added to init
// ( will be removed when / if build.xml will start using init )
Target initTarget = new Target();
initTarget.setProject(project);
initTarget.setName( "init" );
project.addTarget( "init", initTarget );
configureTasks( project, initTarget, root );
NodeList list = root.getElementsByTagName("target");
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element)list.item(i);
String targetName = element.getAttribute("name");
if( targetName.equals("init") )
configureTasks(project, initTarget, element);
}
initTarget.execute();
}

private static void configureTargets(Project project, Element root)
throws BuildException
throws BuildException
{
// configure targets
NodeList list = root.getElementsByTagName("target");
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element)list.item(i);
String targetName = element.getAttribute("name");
String targetDep = element.getAttribute("depends");

// all targets must have a name
if (targetName.equals("")) {
String msg = "target element appears without a name attribute";
throw new BuildException(msg);
}

// init is done already
if( targetName.equals("init") )
continue;
Target target = new Target();
target.setName(targetName);
project.addTarget(targetName, target);
// take care of dependencies
if (targetDep.length() > 0) {
StringTokenizer tok =
new StringTokenizer(targetDep, ",", false);
while (tok.hasMoreTokens()) {
target.addDependency(tok.nextToken().trim());
}
}

// populate target with tasks

configureTasks(project, target, element);
}
// configure targets
NodeList list = root.getElementsByTagName("target");
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element)list.item(i);
String targetName = element.getAttribute("name");
String targetDep = element.getAttribute("depends");
String targetCond = element.getAttribute("if");

// all targets must have a name
if (targetName.equals("")) {
String msg = "target element appears without a name attribute";
throw new BuildException(msg);
}

// init is done already
if( targetName.equals("init") )
continue;

Target target = new Target();
target.setName(targetName);
target.setCondition(targetCond);
project.addTarget(targetName, target);

// take care of dependencies

if (targetDep.length() > 0) {
StringTokenizer tok =
new StringTokenizer(targetDep, ",", false);
while (tok.hasMoreTokens()) {
target.addDependency(tok.nextToken().trim());
}
}

// populate target with tasks

configureTasks(project, target, element);
}
}

private static void configureTasks(Project project,
Target target,
Element targetElement)
throws BuildException
Target target,
Element targetElement)
throws BuildException
{
NodeList list = targetElement.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);

// right now, all we are interested in is element nodes
// not quite sure what to do with others except drop 'em

if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
String taskType = element.getTagName();

// special case - no target in a target.
// hack to allow this method to set "init" target
// using root element
if( ! taskType.equals( "target" ) ) {
// XXX
// put in some sanity checking
Task task = project.createTask(taskType);
// get the attributes of this element and reflect them
// into the task
NamedNodeMap nodeMap = element.getAttributes();
configureTask(project, task, nodeMap);
target.addTask(task);
}
}
}
NodeList list = targetElement.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);

// right now, all we are interested in is element nodes
// not quite sure what to do with others except drop 'em

if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
String taskType = element.getTagName();

// special case - no target in a target.
// hack to allow this method to set "init" target
// using root element
if( ! taskType.equals( "target" ) ) {
// XXX
// put in some sanity checking

Task task = project.createTask(taskType);

// get the attributes of this element and reflect them
// into the task

NamedNodeMap nodeMap = element.getAttributes();
configureTask(project, task, nodeMap);
task.init();
target.addTask(task);
}
}
}
}

private static void configureTask(Project project,
Task taskInst,
NamedNodeMap nodeMap)
throws BuildException
Task taskInst,
NamedNodeMap nodeMap)
throws BuildException
{
Object task=taskInst;
if( task instanceof TaskAdapter )
task=((TaskAdapter)task).getProxy();
// XXX
// instead of doing this introspection each time around, I
// should have a helper class to keep this info around for
// each kind of class
Hashtable propertySetters = new Hashtable();
BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(task.getClass());
} catch (IntrospectionException ie) {
String msg = "Can't introspect task class: " + task.getClass();
throw new BuildException(msg);
}
PropertyDescriptor[] pda = beanInfo.getPropertyDescriptors();
for (int i = 0; i < pda.length; i++) {
PropertyDescriptor pd = pda[i];
String property = pd.getName();
Method setMethod = pd.getWriteMethod();
if (setMethod != null) {
// make sure that there's only 1 param and that it
// takes a String object, all other setMethods need
// to get screened out
Class[] ma =setMethod.getParameterTypes();
if (ma.length == 1) {
Class c = ma[0];
if (c.getName().equals("java.lang.String")) {
propertySetters.put(property, setMethod);
}
}
}
}
for (int i = 0; i < nodeMap.getLength(); i++) {
Node node = nodeMap.item(i);
// these should only be attribs, we won't see anything
// else here.
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
Attr attr = (Attr)node;
// reflect these into the task
Method setMethod = (Method)propertySetters.get(attr.getName());
if (setMethod == null) {
String msg = "Configuration property \"" + attr.getName() +
"\" does not have a setMethod in " + task.getClass();
throw new BuildException(msg);
}
String value=replaceProperties( attr.getValue(), project.getProperties() );
try {
setMethod.invoke(task, new String[] {value});
} catch (IllegalAccessException iae) {
String msg = "Error setting value for attrib: " +
attr.getName();
iae.printStackTrace();
throw new BuildException(msg);
} catch (InvocationTargetException ie) {
String msg = "Error setting value for attrib: " +
attr.getName() + " in " + task.getClass().getName();
ie.printStackTrace();
ie.getTargetException().printStackTrace();
throw new BuildException(msg);
}
}
}
Object task=taskInst;
if( task instanceof TaskAdapter )
task=((TaskAdapter)task).getProxy();
// XXX
// instead of doing this introspection each time around, I
// should have a helper class to keep this info around for
// each kind of class
Hashtable propertySetters = new Hashtable();
BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(task.getClass());
} catch (IntrospectionException ie) {
String msg = "Can't introspect task class: " + task.getClass();
throw new BuildException(msg);
}
PropertyDescriptor[] pda = beanInfo.getPropertyDescriptors();
for (int i = 0; i < pda.length; i++) {
PropertyDescriptor pd = pda[i];
String property = pd.getName();
Method setMethod = pd.getWriteMethod();
if (setMethod != null) {
// make sure that there's only 1 param and that it
// takes a String object, all other setMethods need
// to get screened out
Class[] ma =setMethod.getParameterTypes();
if (ma.length == 1) {
Class c = ma[0];
if (c.getName().equals("java.lang.String")) {
propertySetters.put(property, setMethod);
}
}
}
}
for (int i = 0; i < nodeMap.getLength(); i++) {
Node node = nodeMap.item(i);
// these should only be attribs, we won't see anything
// else here.
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
Attr attr = (Attr)node;
// reflect these into the task
Method setMethod = (Method)propertySetters.get(attr.getName());
if (setMethod == null) {
String msg = "Configuration property \"" + attr.getName() +
"\" does not have a setMethod in " + task.getClass();
throw new BuildException(msg);
}
String value=replaceProperties( attr.getValue(), project.getProperties() );
try {
setMethod.invoke(task, new String[] {value});
} catch (IllegalAccessException iae) {
String msg = "Error setting value for attrib: " +
attr.getName();
iae.printStackTrace();
throw new BuildException(msg);
} catch (InvocationTargetException ie) {
String msg = "Error setting value for attrib: " +
attr.getName() + " in " + task.getClass().getName();
ie.printStackTrace();
ie.getTargetException().printStackTrace();
throw new BuildException(msg);
}
}
}
}

/** Replace ${NAME} with the property value
*/
public static String replaceProperties( String value, Hashtable keys )
throws BuildException
throws BuildException
{
// XXX use Map instead of proj, it's too heavy
// XXX need to replace this code with something better.
StringBuffer sb=new StringBuffer();
int i=0;
int prev=0;
// assert value!=nil
int pos;
while( (pos=value.indexOf( "$", prev )) >= 0 ) {
if(pos>0)
sb.append( value.substring( prev, pos ) );
if( value.charAt( pos + 1 ) != '{' ) {
sb.append( value.charAt( pos + 1 ) );
prev=pos+2; // XXX
} else {
int endName=value.indexOf( '}', pos );
if( endName < 0 ) {
throw new BuildException("Syntax error in prop: " +
value );
}
String n=value.substring( pos+2, endName );
String v=(String) keys.get( n );
//System.out.println("N: " + n + " " + " V:" + v);
sb.append( v );
prev=endName+1;
}
}
if( prev < value.length() ) sb.append( value.substring( prev ) );
// System.out.println("After replace: " + sb.toString());
// System.out.println("Before replace: " + value);
return sb.toString();
// XXX use Map instead of proj, it's too heavy
// XXX need to replace this code with something better.
StringBuffer sb=new StringBuffer();
int i=0;
int prev=0;
// assert value!=nil
int pos;
while( (pos=value.indexOf( "$", prev )) >= 0 ) {
if(pos>0)
sb.append( value.substring( prev, pos ) );
if( value.charAt( pos + 1 ) != '{' ) {
sb.append( value.charAt( pos + 1 ) );
prev=pos+2; // XXX
} else {
int endName=value.indexOf( '}', pos );
if( endName < 0 ) {
throw new BuildException("Syntax error in prop: " +
value );
}
String n=value.substring( pos+2, endName );
String v=(String) keys.get( n );
//System.out.println("N: " + n + " " + " V:" + v);
sb.append( v );
prev=endName+1;
}
}
if( prev < value.length() ) sb.append( value.substring( prev ) );
// System.out.println("After replace: " + sb.toString());
// System.out.println("Before replace: " + value);
return sb.toString();
}
}



+ 47
- 41
src/main/org/apache/tools/ant/Target.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -9,7 +9,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -17,15 +17,15 @@
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
@@ -54,73 +54,79 @@

package org.apache.tools.ant;

import java.util.Enumeration;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.*;

/**
* This class implements a target object with required parameters.
*
*
* @author duncan@x180.com
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
*/

public class Target {

private String name;
private Vector dependencies = new Vector();
private Vector tasks = new Vector();
Project project;
public void setProject( Project project) {
this.project=project;
private String condition = "";
private Vector dependencies = new Vector(2);
private Vector tasks = new Vector(5);
private Project project;

public void setProject(Project project) {
this.project = project;
}

public Project getProject() {
return project;
return project;
}

public void setDepends( String depS ) {
if (depS.length() > 0) {
StringTokenizer tok =
new StringTokenizer(depS, ",", false);
while (tok.hasMoreTokens()) {
addDependency(tok.nextToken().trim());
}
}
public void setDepends(String depS) {
if (depS.length() > 0) {
StringTokenizer tok =
new StringTokenizer(depS, ",", false);
while (tok.hasMoreTokens()) {
addDependency(tok.nextToken().trim());
}
}
}
public void setAttribute(String name, Object value) {
// XXX
if( value instanceof Task)
addTask( (Task)value);
if (value instanceof Task) {
addTask((Task) value);
}
}
public void setName(String name) {
this.name = name;
this.name = name;
}

public String getName() {
return name;
return name;
}

public void addTask(Task task) {
tasks.addElement(task);
tasks.addElement(task);
}

public void addDependency(String dependency) {
dependencies.addElement(dependency);
dependencies.addElement(dependency);
}

public Enumeration getDependencies() {
return dependencies.elements();
return dependencies.elements();
}

public void setCondition(String property) {
this.condition = property;
}

public void execute() throws BuildException {
Enumeration enum = tasks.elements();
while (enum.hasMoreElements()) {
Task task = (Task)enum.nextElement();
task.execute();
}
if ((this.condition != null) || (this.condition.equals("")) || (project.getProperty(this.condition) != null)) {
Enumeration enum = tasks.elements();
while (enum.hasMoreElements()) {
Task task = (Task) enum.nextElement();
task.execute();
}
} else {
project.log("Skipped because property '" + this.condition + "' not set.", this.name, Project.MSG_VERBOSE);
}
}
}

+ 61
- 62
src/main/org/apache/tools/ant/Task.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -9,7 +9,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -17,15 +17,15 @@
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
@@ -54,24 +54,18 @@

package org.apache.tools.ant;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.StringTokenizer;
import java.util.Vector;
import java.io.*;
import java.util.*;

/**
* Base class for all tasks in the
* Base class for all tasks.
*
* @author duncan@x180.com
*/

public abstract class Task {

protected Project project = null;
Target target;
protected Target target = null;

/**
* Sets the project object of this task. This method is used by
@@ -81,75 +75,80 @@ public abstract class Task {
*
* @param project Project in whose scope this task belongs.
*/

void setProject(Project project) {
this.project = project;
this.project = project;
}

public void setAttribute( String name, Object v) {
if("target".equals( name ) ) {
Target t=(Target)v;
target=t;
project=t.getProject();
return;
}
// System.out.println("Set Att " +name + " = " + v );
// if( v!=null) System.out.println(v.getClass());
/**
* Sets a task attribute.
*
* @param name the attribute name
* @param value the attribute value
*/
public void setAttribute(String name, Object value) {
if (name.equals("target")) {
this.target = (Target) value;
this.project = this.target.getProject();
}
}

/**
* Called by the project to let the task initialize properly. Normally it does nothing.
*
* @throws BuildException if someting goes wrong with the build
*/
public void init() throws BuildException {}

/**
* Called by the project to let the task do it's work.
* Called by the project to let the task do it's work. Normally it does nothing.
*
* @throws BuildException if someting goes wrong with the build
*/
public abstract void execute() throws BuildException;
public void execute() throws BuildException {};

/**
* Convienence method to copy a file from a source to a destination
*
* @throws IOException
*/

protected void copyFile(String sourceFile, String destFile)
throws IOException
throws IOException
{
copyFile(new File(sourceFile), new File(destFile));
copyFile(new File(sourceFile), new File(destFile));
}
/**
* Convienence method to copy a file from a source to a destination.
*
* @throws IOException
*/

protected void copyFile(File sourceFile,File destFile) throws IOException {

if (destFile.lastModified() < sourceFile.lastModified()) {
project.log("Copy: " + sourceFile.getAbsolutePath() + " > "
+ destFile.getAbsolutePath(), project.MSG_VERBOSE);

// ensure that parent dir of dest file exists!
// not using getParentFile method to stay 1.1 compat

File parent = new File(destFile.getParent());
if (!parent.exists()) {
parent.mkdirs();
}

// open up streams and copy using a decent buffer

FileInputStream in = new FileInputStream(sourceFile);
FileOutputStream out = new FileOutputStream(destFile);
byte[] buffer = new byte[8 * 1024];
int count = 0;
do {
out.write(buffer, 0, count);
count = in.read(buffer, 0, buffer.length);
} while (count != -1);
in.close();
out.close();
}
protected void copyFile(File sourceFile, File destFile) throws IOException {

if (destFile.lastModified() < sourceFile.lastModified()) {
project.log("Copy: " + sourceFile.getAbsolutePath() + " > "
+ destFile.getAbsolutePath(), project.MSG_VERBOSE);

// ensure that parent dir of dest file exists!
// not using getParentFile method to stay 1.1 compat
File parent = new File(destFile.getParent());
if (!parent.exists()) {
parent.mkdirs();
}

// open up streams and copy using a decent buffer
FileInputStream in = new FileInputStream(sourceFile);
FileOutputStream out = new FileOutputStream(destFile);

byte[] buffer = new byte[8 * 1024];
int count = 0;
do {
out.write(buffer, 0, count);
count = in.read(buffer, 0, buffer.length);
} while (count != -1);

in.close();
out.close();
}
}
}


Loading…
Cancel
Save