@Override
    public void visit(final File f, final String _relativePath) throws IOException {
        int mode = IOUtils.mode(f);

        // On Windows, the elements of relativePath are separated by
        // back-slashes (\), but Zip files need to have their path elements separated
        // by forward-slashes (/)
        String relativePath = _relativePath.replace('\\', '/');

        BasicFileAttributes basicFileAttributes = Files.readAttributes(Util.fileToPath(f), BasicFileAttributes.class);
        if (basicFileAttributes.isDirectory()) {
            ZipEntry dirZipEntry = new ZipEntry(this.prefix + relativePath + '/');
            // Setting this bit explicitly is needed by some unzipping applications (see JENKINS-3294).
            dirZipEntry.setExternalAttributes(BITMASK_IS_DIRECTORY);
            if (mode != -1)   dirZipEntry.setUnixMode(mode);
            dirZipEntry.setTime(basicFileAttributes.lastModifiedTime().toMillis());
            zip.putNextEntry(dirZipEntry);
            zip.closeEntry();
        } else {
            ZipEntry fileZipEntry = new ZipEntry(this.prefix + relativePath);
            if (mode != -1)   fileZipEntry.setUnixMode(mode);
            fileZipEntry.setTime(basicFileAttributes.lastModifiedTime().toMillis());
            fileZipEntry.setSize(basicFileAttributes.size());
            zip.putNextEntry(fileZipEntry);
            try (InputStream in = FilePath.openInputStream(f, openOptions)) {
                int len;
                while ((len = in.read(buf)) >= 0)
                    zip.write(buf, 0, len);
            } catch (InvalidPathException e) {
                throw new IOException(e);
            }
            zip.closeEntry();
        }
        entriesWritten++;
    }
@Test
    public void huge64bitFile() throws IOException {
        // create huge64bitFileTest.txt
        Path hugeFile = tmp.newFolder().toPath().resolve("huge64bitFileTest.txt");
        long length = 4L * 1024 * 1024 * 1024 + 2;
        try (RandomAccessFile largeFile = new RandomAccessFile(hugeFile.toFile(), "rw")) {
            largeFile.setLength(length);
        } catch (IOException e) {
            // We probably don't have enough free disk space. That's ok, we'll skip this test...
            Assume.assumeNoException(e);
        }

        // a file to store the zip archive in
        Path zipFile = Files.createTempFile(tmp.getRoot().toPath(), "test", ".zip");

        // create zip from tmpDir
        try (ZipArchiver archiver = new ZipArchiver(Files.newOutputStream(zipFile))) {
            archiver.visit(hugeFile.toFile(), "huge64bitFileTest.txt");
        }

        // examine zip contents and assert that there's an item there...
        try (ZipFile zipFileVerify = new ZipFile(zipFile.toFile())) {
            assertEquals(1, zipFileVerify.size());
            ZipEntry zipEntry = zipFileVerify.entries().nextElement();
            assertEquals("huge64bitFileTest.txt", zipEntry.getName());
            assertEquals(length, zipEntry.getSize());
        }
    }