Copy file in Java and replace existing target
Asked Answered
A

5

53

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.

Amylopectin answered 18/6, 2013 at 13:0 Comment(0)
T
10

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();
    }
}
Twentyfourmo answered 18/6, 2013 at 13:8 Comment(5)
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.Amylopectin
@Amylopectin do you mean the code you will deploy to runs 1.6 JVMs?Twentyfourmo
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.Amylopectin
Files != File. Files is part of nio. Please don't write 60 lines of boilerplate to avoid using Files.copy.Idelson
@Idelson the OP says he has to use Java 6... And yes, I know JSR 203. Quite well in fact.Twentyfourmo
T
130

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.

Thun answered 18/6, 2013 at 13:2 Comment(4)
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. ;-)Amylopectin
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...)Amylopectin
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.Needle
@VikasRoy I suggest you ask a separate question explaining your specific issue.Thun
T
10

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();
    }
}
Twentyfourmo answered 18/6, 2013 at 13:8 Comment(5)
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.Amylopectin
@Amylopectin do you mean the code you will deploy to runs 1.6 JVMs?Twentyfourmo
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.Amylopectin
Files != File. Files is part of nio. Please don't write 60 lines of boilerplate to avoid using Files.copy.Idelson
@Idelson the OP says he has to use Java 6... And yes, I know JSR 203. Quite well in fact.Twentyfourmo
F
7
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());
        }
    }

}
Fabaceous answered 19/2, 2019 at 13:46 Comment(0)
B
1

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

Benildas answered 18/6, 2013 at 13:3 Comment(0)
T
0

your statement Files.copy(path,Stringor address,StandardCopyOption) is this While you are giving a String where you have to set path of where you want to save file. So simple Use this statement below:-

Files.copy(path,Paths.get(String or address),StandardCopyOption) by using Paths.get converts String into File location or path source path where you have to save file.

Totalitarianism answered 23/5, 2023 at 10:21 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Alamein

© 2022 - 2024 — McMap. All rights reserved.