public static void copyFile()

in src/main/java/org/apache/maven/shared/utils/io/FileUtils.java [1709:1793]


    public static void copyFile(
            @Nonnull File from,
            @Nonnull File to,
            @Nullable String encoding,
            @Nullable FilterWrapper[] wrappers,
            boolean overwrite)
            throws IOException {
        if (wrappers == null || wrappers.length == 0) {
            if (overwrite || !to.exists() || to.lastModified() < from.lastModified()) {
                copyFile(from, to);
            }
        } else {
            Charset charset = charset(encoding);

            // buffer so it isn't reading a byte at a time!
            try (Reader fileReader = Files.newBufferedReader(from.toPath(), charset)) {
                Reader wrapped = fileReader;
                for (FilterWrapper wrapper : wrappers) {
                    wrapped = wrapper.getReader(wrapped);
                }

                if (overwrite || !to.exists()) {
                    try (Writer fileWriter = Files.newBufferedWriter(to.toPath(), charset)) {
                        IOUtil.copy(wrapped, fileWriter);
                    }
                } else {
                    CharsetEncoder encoder = charset.newEncoder();

                    int totalBufferSize = FILE_COPY_BUFFER_SIZE;

                    int charBufferSize = (int) Math.floor(totalBufferSize / (2 + 2 * encoder.maxBytesPerChar()));
                    int byteBufferSize = (int) Math.ceil(charBufferSize * encoder.maxBytesPerChar());

                    CharBuffer newChars = CharBuffer.allocate(charBufferSize);
                    ByteBuffer newBytes = ByteBuffer.allocate(byteBufferSize);
                    ByteBuffer existingBytes = ByteBuffer.allocate(byteBufferSize);

                    CoderResult coderResult;
                    int existingRead;
                    boolean writing = false;

                    try (RandomAccessFile existing = new RandomAccessFile(to, "rw")) {
                        int n;
                        while (-1 != (n = wrapped.read(newChars))) {
                            ((Buffer) newChars).flip();

                            coderResult = encoder.encode(newChars, newBytes, n != 0);
                            if (coderResult.isError()) {
                                coderResult.throwException();
                            }

                            ((Buffer) newBytes).flip();

                            if (!writing) {
                                existingRead = existing.read(existingBytes.array(), 0, newBytes.remaining());
                                ((Buffer) existingBytes).position(existingRead);
                                ((Buffer) existingBytes).flip();

                                if (newBytes.compareTo(existingBytes) != 0) {
                                    writing = true;
                                    if (existingRead > 0) {
                                        existing.seek(existing.getFilePointer() - existingRead);
                                    }
                                }
                            }

                            if (writing) {
                                existing.write(newBytes.array(), 0, newBytes.remaining());
                            }

                            ((Buffer) newChars).clear();
                            ((Buffer) newBytes).clear();
                            ((Buffer) existingBytes).clear();
                        }

                        if (existing.length() > existing.getFilePointer()) {
                            existing.setLength(existing.getFilePointer());
                        }
                    }
                }
            }
        }

        copyFilePermissions(from, to);
    }