All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.jet.impl.util.IOUtil Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.jet.impl.util;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import static com.hazelcast.internal.util.ExceptionUtil.sneakyThrow;

public final class IOUtil {

    private static final int BUFFER_SIZE = 1 << 14;

    private IOUtil() {
    }

    /**
     * Creates a ZIP-file stream from the directory tree rooted at the supplied
     * {@code baseDir}. Copies the stream into the provided output stream, closing
     * it when done.
     * 

* Note: hidden files and directories are ignored */ public static void packDirectoryIntoZip(@Nonnull Path baseDir, @Nonnull OutputStream destination) throws IOException { try ( ZipOutputStream zipOut = new ZipOutputStream(destination); Stream fileStream = Files.walk(baseDir) ) { fileStream.forEach(p -> { try { if (Files.isHidden(p) || p == baseDir) { return; } String relativePath = baseDir.relativize(p).toString(); boolean directory = Files.isDirectory(p); // slash has been added instead of File.separator since ZipEntry.isDirectory is checking against it. relativePath = directory ? relativePath + "/" : relativePath; zipOut.putNextEntry(new ZipEntry(relativePath)); if (!directory) { Files.copy(p, zipOut); } zipOut.closeEntry(); } catch (IOException e) { throw sneakyThrow(e); } }); } } /** * Creates a ZIP-file stream from the supplied input stream. The input will * be stored in a single file in the created zip. The {@code destination} * stream will be closed. * * @param source the stream to copy from * @param destination the stream to write to * @param fileName the name of the file in the destination ZIP */ public static void packStreamIntoZip( @Nonnull InputStream source, @Nonnull OutputStream destination, @Nonnull String fileName ) throws IOException { try ( ZipOutputStream dstZipStream = new ZipOutputStream(destination) ) { dstZipStream.putNextEntry(new ZipEntry(fileName)); copyStream(source, dstZipStream); } } public static void copyStream(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[BUFFER_SIZE]; for (int readCount; (readCount = in.read(buf)) > 0; ) { out.write(buf, 0, readCount); } } public static void unzip(InputStream is, Path targetDir) throws IOException { targetDir = targetDir.toAbsolutePath(); try (ZipInputStream zipIn = new ZipInputStream(is)) { for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) { Path resolvedPath = targetDir.resolve(ze.getName()).normalize(); if (!resolvedPath.startsWith(targetDir)) { // see: https://snyk.io/research/zip-slip-vulnerability throw new RuntimeException("Entry with an illegal path: " + ze.getName()); } if (ze.isDirectory()) { Files.createDirectories(resolvedPath); } else { Path dir = resolvedPath.getParent(); assert dir != null : "null parent: " + resolvedPath; Files.createDirectories(dir); Files.copy(zipIn, resolvedPath); } } } } /** * Extracts the file name from the URL. File name is the part of {@code * url.getPath()} after the last '/' character. Returns empty string if the * path ends with a '/'. *

* Returns null if input is null or if {@code url.getPath()} returns null. */ @Nullable public static String fileNameFromUrl(@Nullable URL url) { String fnamePath; if (url == null || (fnamePath = url.getPath()) == null) { return null; } // URLs always use forward slash to separate directories int lastSlash = fnamePath.lastIndexOf('/'); return lastSlash < 0 ? fnamePath : fnamePath.substring(lastSlash + 1); } @Nonnull public static String canonicalName(String directory) { return Util.uncheckCall(() -> new File(directory).getCanonicalPath()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy