Copy file in Java and replace existing target

89,959

Solution 1

As a complement to @assylias' answer:

If you use Java 7, drop File entirely. What you want is Path instead.

And to get a Path object matching a path on your filesystem, you do:

Paths.get("path/to/file"); // argument may also be absolute

Get used to it real fast. Note that if you still use APIs which require File, Path has a .toFile() method.

Note that if you are in the unfortunate case where you use an API which returns File objects, you can always do:

theFileObject.toPath()

But in code of yours, use Path. Systematically. Without a second thought.

EDIT Copying a file to another using 1.6 using NIO can be done as such; note that the Closer class is inspited by Guava:

public final class Closer
    implements Closeable
{
    private final List<Closeable> closeables = new ArrayList<Closeable>();

    // @Nullable is a JSR 305 annotation
    public <T extends Closeable> T add(@Nullable final T closeable)
    {
        closeables.add(closeable);
        return closeable;
    }

    public void closeQuietly()
    {
        try {
            close();
        } catch (IOException ignored) {
        }
    }

    @Override
    public void close()
        throws IOException
    {
        IOException toThrow = null;
        final List<Closeable> l = new ArrayList<Closeable>(closeables);
        Collections.reverse(l);

        for (final Closeable closeable: l) {
            if (closeable == null)
                continue;
            try {
                closeable.close();
            } catch (IOException e) {
                if (toThrow == null)
                    toThrow = e;
            }
        }

        if (toThrow != null)
            throw toThrow;
    }
}

// Copy one file to another using NIO
public static void doCopy(final File source, final File destination)
    throws IOException
{
    final Closer closer = new Closer();
    final RandomAccessFile src, dst;
    final FileChannel in, out;

    try {
        src = closer.add(new RandomAccessFile(source.getCanonicalFile(), "r");
        dst = closer.add(new RandomAccessFile(destination.getCanonicalFile(), "rw");
        in = closer.add(src.getChannel());
        out = closer.add(dst.getChannel());
        in.transferTo(0L, in.size(), out);
        out.force(false);
    } finally {
        closer.close();
    }
}

Solution 2

You need to pass Path arguments as explained by the error message:

Path from = cfgFilePath.toPath(); //convert from File to Path
Path to = Paths.get(strTarget); //convert from String to Path
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);

That assumes your strTarget is a valid path.

Solution 3

package main.java;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class CopyFileOnExist {

    public static void main(String[] args)  {

        Path sourceDirectory = Paths.get("C:/Users/abc/Downloads/FileNotFoundExceptionExample/append.txt");
        Path targetDirectory = Paths.get("C:/Users/abc/Downloads/FileNotFoundExceptionExample/append5.txt");

        //copy source to target using Files Class
        try {
            Files.copy(sourceDirectory, targetDirectory,StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            System.out.println(e.toString());
        }
    }

}

Solution 4

strTarget is a "String" object and not a "Path" object

Share:
89,959

Related videos on Youtube

commander_keen
Author by

commander_keen

Defender of the Earth!

Updated on February 20, 2020

Comments

  • commander_keen
    commander_keen about 4 years

    I'm trying to copy a file with java.nio.file.Files like this:

    Files.copy(cfgFilePath, strTarget, StandardCopyOption.REPLACE_EXISTING);
    

    The problem is that Eclipse says "The method copy(Path, Path, CopyOption...) in the type Files is not applicable for the arguments (File, String, StandardCopyOption)"

    I'm using Eclipse and Java 7 on Win7 x64. My project is set up to use Java 1.6 compatibility.

    Is there a solution to this or do I have to create something like this as a workaround:

    File temp = new File(target);
    
    if(temp.exists())
      temp.delete();
    

    Thanks.

  • commander_keen
    commander_keen almost 11 years
    Arg, why did I think it was an issue with the copyOption... Totally ignored the first two parameter types, thank you. Seems like I've been coding for too long in the heat. ;-)
  • commander_keen
    commander_keen almost 11 years
    I wonder if this will work when I compile with compliance level for Java 1.6 as mentioned, but in any case thanks for the note, will keep it in mind for the future.
  • fge
    fge almost 11 years
    @commander_keen do you mean the code you will deploy to runs 1.6 JVMs?
  • commander_keen
    commander_keen almost 11 years
    Uff, after copying the exported jar to a PC with Java 1.6 (that's why I mentioned that I need to be 1.6 compatible although I develop with Java 7 and compile for 1.6), it moans "Exception in thread "main" java.lang.NoSuchMethodError: java.io.File.toPath()Lja va/nio/file/Path;" according to the documentations it's right, this method is only available since Java 7. (I wonder why this was not critized during development/design-time like other things I tried to use from Java 7 before, now I have to check everything by hand...)
  • commander_keen
    commander_keen almost 11 years
    That is correct. As now recognized in the comments above, the whole Path thing and copy methods won't work. :-( Have to figure out how to copy files with Java 1.6 methods only and implement it again. Hints on best practice for 1.6 are welcome, though.
  • suriv
    suriv almost 8 years
    Files != File. Files is part of nio. Please don't write 60 lines of boilerplate to avoid using Files.copy.
  • fge
    fge almost 8 years
    @suriv the OP says he has to use Java 6... And yes, I know JSR 203. Quite well in fact.
  • Vikas Roy
    Vikas Roy almost 2 years
    I have one query about this : if two persons are uploading a image which name and type is same but image is different then who will upload in last with same type then previous image will replace with new image which has same type. what should i do for this problem because type and name is same but image is different so I don't want to replace it.
  • assylias
    assylias almost 2 years
    @VikasRoy I suggest you ask a separate question explaining your specific issue.