
com.epam.deltix.util.io.BasicIOUtil Maven / Gradle / Ivy
/*
* Copyright 2021 EPAM Systems, Inc
*
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership. 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.epam.deltix.util.io;
import com.epam.deltix.util.lang.*;
import com.epam.deltix.util.lang.SortedProperties;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.*;
import com.epam.deltix.util.lang.Util;
import com.epam.deltix.util.text.ShellPatternCSMatcher;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.regex.*;
/**
* I/O Utilities which have no dependencies on Deltix CG code.
*/
public abstract class BasicIOUtil {
public static final String CR = System.getProperty ("line.separator");
public static final String TEMP_FILE_PREFIX = "~";
/**
* Closes a Socket without throwing an exception. Checks for null.
*/
public static void close (Socket s) {
if (s != null)
try {
s.close ();
} catch (Exception x) {
Util.handleException (x);
}
}
/**
* Closes a ServerSocket without throwing an exception. Checks for null.
*/
public static void close (ServerSocket s) {
if (s != null)
try {
s.close ();
} catch (Exception x) {
Util.handleException (x);
}
}
public static void close (ZipFile f) {
if (f != null)
try {
f.close ();
} catch (Exception x) {
Util.handleException (x);
}
}
public static URL createFileUrl (File f) {
String path = f.getAbsolutePath ().replace ('\\', '/');
try {
if (path.length () > 1 && path.charAt (1) == ':') // drive letter
return (new URL ("file:///" + path));
else
return (new URL ("file://" + path));
} catch (IOException iox) {
throw new com.epam.deltix.util.io.UncheckedIOException(iox);
}
}
public static void force (FileChannel fc, boolean metaData)
throws IOException, InterruptedException
{
fc.force (metaData);
// For some reason we can be here without any exceptions
// but with a suddenly closed file.
if (Thread.interrupted ())
throw new InterruptedException ();
else if (!fc.isOpen ())
throw new IOException ("FileChannel is closed.");
}
public static void marshall (Marshaller m, File file, Object object)
throws IOException, JAXBException
{
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
m.marshal(object, out);
out.getChannel().force(false);
} finally {
Util.close(out);
}
}
public static void marshall (Marshaller m, OutputStream out, Object object)
throws IOException, JAXBException
{
try {
m.marshal(object, out);
out.flush();
} finally {
Util.close(out);
}
}
public static Object unmarshal(Unmarshaller u, File file)
throws FileNotFoundException, JAXBException
{
return unmarshal(u, new FileInputStream(file));
}
public static Object unmarshal(Unmarshaller u, String resource)
throws FileNotFoundException, JAXBException
{
return unmarshal(u, openResourceAsStream(resource));
}
public static Object unmarshal(Unmarshaller u, InputStream in)
throws FileNotFoundException, JAXBException
{
try {
return u.unmarshal(in);
} finally {
Util.close(in);
}
}
public static void rename (File from, File to) throws IOException {
if (!from.renameTo (to))
throw new IOException ("Failed to rename " + from + " -> " + to);
}
public static void delete (File f) throws IOException {
if (! deleteFileOrDir(f))
throw new IOException ("Failed to delete " + f);
}
public static void deleteUnchecked (File f) {
if (! deleteFileOrDir(f))
throw new com.epam.deltix.util.io.UncheckedIOException("Failed to delete " + f);
}
/**
* Deletes the specified file, and continues to attempt to delete its parent directories
* up the directory path, until the deletion fails, or the limit file is reached.
* The deletion of a directory
* fails if the directory is not empty (as well as possibly for a number of other reasons).
*
* @param f The file that will be deleted, and then its parent directories
* will be deleted, if they are empty.
* @param limit Unless null, the deletion process will stop at this file. The
* limit is exclusive, i.e. this file will never be deleted.
* @return The first file that failed to be deleted.
*/
public static File deleteWithEmptyParentPath (File f, File limit) {
while (!f.equals (limit) && f.delete ())
f = f.getParentFile ();
return (f);
}
/**
* Recursively deletes given directory and all its content
*
* @return true
if and only if the directory is
* successfully deleted; false
otherwise
*/
public static boolean deleteFileOrDir(File file) {
if(file == null)
return false;
if(!file.exists())
return true;
if(file.isDirectory()) {
File items[] = file.listFiles();
if(items != null) {
for(File item : items)
if( ! deleteFileOrDir(item))
return false;
}
}
return file.delete();
}
public static boolean clearDir(File file) {
if (file == null)
return false;
if (!file.exists())
return true;
if (file.isDirectory()) {
File items[] = file.listFiles();
if(items != null) {
for(File item : items)
if( ! deleteFileOrDir(item))
return false;
}
}
return true;
}
public static void createNew (File f) throws IOException {
if (!f.createNewFile ())
throw new IOException ("Failed to create " + f);
}
/**
* Output character ch
n
times to Writer
* wr
.
*/
public static void pad (char ch, int n, Writer wr) throws IOException {
for (int ii = 0; ii < n; ii++)
wr.write (ch);
}
/**
* Output character ch
n
times to PrintStream
* ps
.
*/
public static void pad (char ch, int n, PrintStream ps) throws IOException {
for (int ii = 0; ii < n; ii++)
ps.print (ch);
}
/**
* Return the short name of teh file without the extension.
*/
public static String getNameNoExt (File f) {
String name = f.getName ();
int dotIdx = name.lastIndexOf ('.');
if (dotIdx < 0)
return (name);
else
return (name.substring (0, dotIdx));
}
/**
* Clones the Serializable object by first writing it to a byte stream
* and then reading it back.
*
* @param object the Serializable object being cloned
*
* @return Object - the cloned object
*
* @throws CloneNotSupportedException - thrown when the afore-mentioned cloning algorithm fails
*/
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static Object clone(Serializable object)
throws CloneNotSupportedException
{
Object clone = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream (4096);
ObjectOutputStream oos = new ObjectOutputStream (baos);
oos.writeObject (object);
oos.close ();
ByteArrayInputStream bais = new ByteArrayInputStream (baos.toByteArray ());
ObjectInputStream ois = new ObjectInputStream (bais);
clone = ois.readObject ();
ois.close ();
} catch (Exception x) {
x.printStackTrace();
throw new CloneNotSupportedException (x.getMessage ());
}
return clone;
}
/**
* Reads entire stream into bufffer
*
* @param is the InputStream to read
* @param readBlockSize - [IMPORTANT] - expected size of the stream or block size
*
* @return Input Stream as array of bytes
* @throws IOException - InputStream.read() fails
*/
public static byte[] getStreamBytes(InputStream is, final int readBlockSize)
throws IOException
{
int bufSize = 0; // actual bytes read
int bufCapacity = readBlockSize; // current buffer capacity
byte buf[] = new byte[bufCapacity];
try {
while (true) {
int bytesRead = is.read (buf, bufSize, readBlockSize);
//System.err.println ("request.is.read() bytesRead=" + bytesRead);
bufSize += (bytesRead > 0) ? bytesRead : 0;
if (bytesRead <= 0) // no more data?
break;
if (bufSize + readBlockSize > bufCapacity) {
// buffer is full but we have more bytes in stream - realloc
bufCapacity += 2 * readBlockSize;
byte[] newbuf = new byte[bufCapacity];
System.arraycopy (buf, 0, newbuf, 0, bufSize);
buf = newbuf;
}
}
} finally {
// Closing stream is responsibility of stream creator!
// if (is != null) is.close();
}
byte[] result = new byte[bufSize];
if (bufSize > 0)
System.arraycopy (buf, 0, result, 0, bufSize);
return result;
}
/** Copy src file into dest */
public static void copyFile (File src, File dest)
throws IOException, InterruptedException
{
FileInputStream in = null;
try {
in = new FileInputStream (src);
copyToFile (in, dest, src.length ());
} finally {
Util.close (in);
}
}
public static void copyFile1(File sourceFile, File destFile) throws IOException {
if (destFile.exists())
destFile.delete();
destFile.createNewFile();
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
}
finally {
Util.close(source);
Util.close(destination);
}
}
public static void copyFile7 (File src, File dest)
throws IOException, InterruptedException {
Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
/**
* Copies file and creates full destination path if needed
*/
public static void copyFileWithPathCreate (File src, File dest)
throws IOException, InterruptedException
{
File directory = dest.getParentFile();
if (!directory.exists()){
directory.mkdirs();
}
copyFile (src, dest);
}
public static void mkParentDirIfNeeded (File f)
throws FileNotFoundException
{
File pd = f.getParentFile ();
if (pd != null)
mkDirIfNeeded (pd);
}
public static void mkDirIfNeeded (File f)
throws FileNotFoundException
{
if (!f.isDirectory () && !f.mkdirs ())
throw new FileNotFoundException ("Cannot create " + f.getPath ());
}
public static void removeRecursive (
File file,
FileFilter filter,
boolean includeThisFile
)
throws IOException
{
if (file.isDirectory ()) {
File [] fileElements = file.listFiles (filter);
if (fileElements != null)
for (int iElement = 0; iElement < fileElements.length; iElement++)
removeRecursive (fileElements [iElement], filter, true);
}
if (includeThisFile) {
file.delete ();
if (file.exists ())
throw new IOException ("Failed to delete " + file);
}
}
public static void removeRecursive (
File file,
FileFilter filter,
List remains,
boolean include
)
throws IOException
{
if (file.isDirectory ()) {
File [] fileElements = file.listFiles (filter);
if (fileElements != null)
for (int iElement = 0; iElement < fileElements.length; iElement++)
removeRecursive (fileElements [iElement], filter, remains, true);
}
if (include && !file.delete ())
remains.add(file);
}
public static void removeRecursive (File file)
throws IOException
{
removeRecursive (file, null, true);
}
public static void removeRecursiveBefore (File file, Date date,
boolean includeThisDir)
throws IOException
{
long lastMod = file.lastModified();
if (file.isDirectory ()) {
File [] fileElements = file.listFiles ();
for (int iElement = 0; iElement < fileElements.length; iElement++)
removeRecursiveBefore (fileElements [iElement], date);
}
if (includeThisDir && lastMod < date.getTime())
file.delete ();
}
public static void removeRecursiveBefore (File file, Date date)
throws IOException
{
long lastMod = file.lastModified();
if (file.isDirectory ()) {
File [] fileElements = file.listFiles ();
for (int iElement = 0; iElement < fileElements.length; iElement++)
removeRecursiveBefore (fileElements [iElement], date);
}
if (lastMod < date.getTime())
file.delete ();
}
public static void readFile (File file, OutputStream out)
throws IOException, InterruptedException
{
FileInputStream fis = new FileInputStream (file);
try {
StreamPump.pump (fis, out);
} finally {
Util.close (fis);
}
}
public static String readTextFromClassPathNoX (String relPath) {
try {
return (readTextFromClassPath (relPath));
} catch (InterruptedException | IOException x) {
throw new com.epam.deltix.util.io.UncheckedIOException(x);
}
}
public static String readTextFromClassPath (String relPath)
throws IOException, InterruptedException
{
InputStream is = openResourceAsStream (relPath);
try {
return (readFromStream (is));
} finally {
Util.close (is);
}
}
public static String [] readLinesFromClassPath (String relPath)
throws IOException, InterruptedException
{
return readLinesFromClassPath (relPath, false);
}
public static String [] readLinesFromClassPath (String relPath, boolean trim)
throws IOException, InterruptedException
{
InputStream is = openResourceAsStream (relPath);
try {
return (readLinesFromReader (new InputStreamReader (is), trim));
} finally {
Util.close (is);
}
}
public static String readTextFile (String filepath)
throws IOException, InterruptedException
{
FileReader fr = null;
try {
fr = new FileReader (filepath);
return (readFromReader (fr));
} finally {
Util.close (fr);
}
}
public static String readTextFile (File f)
throws IOException, InterruptedException
{
FileReader fr = null;
try {
fr = new FileReader (f);
return (readFromReader (fr));
} finally {
Util.close (fr);
}
}
public static String [] readLinesFromTextFile (String filepath)
throws IOException, InterruptedException
{
FileReader fr = null;
try {
fr = new FileReader (filepath);
return (readLinesFromReader (fr));
} finally {
Util.close (fr);
}
}
public static String [] readLinesFromTextFile (File f)
throws IOException, InterruptedException
{
return (readLinesFromTextFile (f, false));
}
public static String [] readLinesFromTextFile (File f, boolean trim)
throws IOException, InterruptedException
{
try (FileReader fr = new FileReader (f)) {
return (readLinesFromReader (fr, trim));
}
}
/**
*/
public static String readFromStream (InputStream is, String encoding)
throws IOException, InterruptedException
{
return (readFromReader (new InputStreamReader (is, encoding)));
}
/**
*/
public static String readFromStream (InputStream is)
throws IOException, InterruptedException
{
return (readFromReader (new InputStreamReader (is)));
}
public static String readFromReader (Reader r)
throws IOException, InterruptedException
{
if (!(r instanceof BufferedReader))
r = new BufferedReader (r);
StringBuffer fileContents = new StringBuffer ();
char [] tmpContent = new char [4096];
for (;;) {
int numRead = r.read (tmpContent, 0, tmpContent.length);
if (Thread.interrupted ())
throw new InterruptedException ();
if (numRead < 0)
break;
fileContents.append (tmpContent, 0, numRead);
}
return (fileContents.toString ());
}
public static String [] readLinesFromReader (Reader r)
throws IOException, InterruptedException {
return readLinesFromReader (r, false);
}
public static String [] readLinesFromReader (Reader r, boolean trim)
throws IOException, InterruptedException
{
BufferedReader brd;
if (r instanceof BufferedReader)
brd = (BufferedReader) r;
else
brd = new BufferedReader (r);
ArrayList lines = new ArrayList ();
for (;;) {
String line = brd.readLine ();
if (line == null)
break;
if (Thread.interrupted ())
throw new InterruptedException ();
if (trim) {
line = line.trim();
if (line.isEmpty()) {
continue;
}
}
lines.add (line);
}
return (lines.toArray (new String [lines.size ()]));
}
public static T readFromReaderWithProperties (Reader r, final Properties props, final T to)
throws IOException, InterruptedException
{
if (!(r instanceof BufferedReader))
r = new BufferedReader (r);
if (props != null) {
r = new TokenReplacingReader(r, new TokenReplacingReader.TokenResolver() {
@Override
public String resolveToken(String token) {
return props.getProperty(token);
}
});
}
CharBuffer tmpContent = CharBuffer.allocate(4096);
for (;;) {
int numRead = r.read (tmpContent);
if (Thread.interrupted ())
throw new InterruptedException ();
if (numRead < 0)
break;
to.append (tmpContent, 0, numRead);
}
return to;
}
public static void replaceProperties (Reader r, Appendable w, Properties props)
throws IOException, InterruptedException
{
readFromReaderWithProperties(r, props, w);
}
public static String getFileText (File file) throws IOException, InterruptedException {
FileInputStream is = new FileInputStream(file);
try {
return BasicIOUtil.readFromStream (is);
} finally {
is.close();
}
}
public static void writeTextFile (String filepath, String content)
throws IOException
{
writeTextFile (new File (filepath), content);
}
public static void writeTextFile (File f, String content)
throws IOException
{
FileWriter fw = new FileWriter (f);
try {
fw.write (content);
fw.close ();
} finally {
Util.close (fw);
}
}
public static void writeLines (File f, Collection lines)
throws IOException
{
PrintWriter fw = new PrintWriter (f);
try {
for (String s : lines)
fw.println (s);
fw.close ();
} finally {
Util.close (fw);
}
}
public static void writeLines (File f, String[] lines)
throws IOException
{
PrintWriter fw = new PrintWriter (f);
try {
for (String s : lines)
fw.println (s);
fw.close ();
} finally {
Util.close (fw);
}
}
public static void writeBytes (
File file,
byte [] bytes,
int offset,
int length
)
throws IOException
{
FileOutputStream fos = new FileOutputStream (file);
try {
fos.write (bytes, offset, length);
} finally {
Util.close (fos);
}
}
public static byte [] readBytes (File file)
throws IOException
{
int flen = (int) file.length ();
byte [] ret = new byte [flen];
readBytes (file, ret, 0, flen);
return (ret);
}
/** @return number of bytes remaining in buffer after read completion */
public static int readFully (
InputStream is,
byte [] bytes,
int offset,
int length
)
throws IOException
{
while (length > 0) {
int count = is.read (bytes, offset, length);
if (count < 0)
throw new EOFException ();
offset += count;
length -= count;
}
return length;
}
public static void skipFully (
InputStream is,
long length
)
throws IOException
{
while (length > 0) {
long count = is.skip (length);
// Note: actually count can't be negative
if (count <= 0)
throw new EOFException ();
length -= count;
}
}
public static void readBytes (
File file,
byte [] bytes,
int offset,
int length
)
throws IOException
{
try (FileInputStream fis = new FileInputStream (file)) {
readFully (fis, bytes, offset, length);
}
}
public static byte [] readBytes (InputStream is)
throws IOException, InterruptedException
{
ByteArrayOutputStream bais = new ByteArrayOutputStream ();
StreamPump.pump (is, bais);
return (bais.toByteArray ());
}
public static Properties readPropsFromFile (File file)
throws IOException
{
Properties props = new SortedProperties ();
FileInputStream fis = new FileInputStream (file);
try {
props.load (fis);
} finally {
Util.close (fis);
}
return (props);
}
/**
* Opens a resource and wraps in a LineNumberReader, throws a FileNotFoundException
* if not found.
*/
public static LineNumberReader openResourceAsReader (String relPath)
throws FileNotFoundException
{
return (new LineNumberReader (new InputStreamReader (openResourceAsStream (relPath))));
}
/**
* Opens a resource as stream, but throws a FileNotFoundException
* if not found.
*/
public static InputStream openResourceAsStream (String relPath)
throws FileNotFoundException
{
InputStream is =
BasicIOUtil.class.getClassLoader ().getResourceAsStream (relPath);
if (is == null)
throw new FileNotFoundException ("CLASSPATH/" + relPath);
return (is);
}
public static void copyResource (String path, String encoding, Writer wr)
throws IOException, InterruptedException
{
InputStream is = openResourceAsStream (path);
try {
InputStream bis = is;
Writer bwr = wr;
if (!(bis instanceof BufferedInputStream))
bis = new BufferedInputStream (bis);
if (!(bwr instanceof BufferedWriter))
bwr = new BufferedWriter (wr);
InputStreamReader rd = new InputStreamReader (bis, encoding);
for (;;) {
int ch = rd.read ();
if (ch < 0)
break;
bwr.write (ch);
}
is.close ();
} finally {
Util.close (is);
}
}
public static void copyResource (String path, OutputStream os)
throws IOException, InterruptedException
{
InputStream is = openResourceAsStream (path);
try {
StreamPump.pump (is, os);
is.close ();
} finally {
Util.close (is);
}
}
public static void extractResource (String path, File dest)
throws IOException, InterruptedException
{
OutputStream os = new FileOutputStream (dest);
try {
copyResource (path, os);
} finally {
Util.close (os);
}
}
public static Properties readPropsFromClassPath (String relPath)
throws IOException
{
Properties props = new SortedProperties ();
InputStream is = openResourceAsStream (relPath);
try {
props.load (is);
} finally {
Util.close (is);
}
return (props);
}
public static void storePropsToFile (
Properties props,
File file,
String header
)
throws IOException
{
FileOutputStream fos = new FileOutputStream (file);
try {
props.store (fos, header);
} finally {
Util.close (fos);
}
}
public static void copyToFile (InputStream is, File destFile)
throws IOException, InterruptedException
{
copyToFile (is, destFile, 0);
}
public static void copyToFile (InputStream is, File destFile, long size)
throws IOException, InterruptedException
{
byte [] buffer = new byte [4096];
copyToFile (is, destFile, size, buffer);
}
public static void copyToFile (InputStream is, File destFile, long size, byte [] buffer)
throws IOException, InterruptedException
{
RandomAccessFile out;
try {
out = new RandomAccessFile (destFile,
"rw");
} catch (IOException ioe) {
throw new AccessibleIOException (ioe,
destFile);
}
try {
if (size < 0)
size = 0;
out.setLength (size); // prevent fragmentation
for (;;) {
if (Thread.interrupted ())
throw new InterruptedException ();
int n = is.read (buffer);
if (n < 0)
break;
out.write (buffer, 0, n);
}
out.close ();
} finally {
Util.close (out);
}
}
/**
* Checks if the file is present.
* @exception FileNotFoundException If the file does not exists.
*/
public static void assertExists (File f) throws FileNotFoundException {
if (!f.exists ())
throw (new FileNotFoundException (f.getPath ()));
}
private static final String SPECIAL_ZIP_ENTRY_NAME = "SERIALIZED-OBJECT";
public static boolean looksLikeZip (File f) {
return (f.getName ().toLowerCase ().endsWith (".zip"));
}
public static OutputStream openMaybeZip (OutputStream fos, boolean compress)
throws IOException
{
if (compress) {
ZipOutputStream zipos = new ZipOutputStream (fos);
zipos.putNextEntry (new ZipEntry (SPECIAL_ZIP_ENTRY_NAME));
return (zipos);
}
else
return (fos);
}
public static InputStream openMaybeZip (InputStream fis, boolean compress)
throws IOException
{
if (compress) {
ZipInputStream zipis = new ZipInputStream (fis);
zipis.getNextEntry ();
return (zipis);
}
else
return (fis);
}
public static InputStream openInputMaybeZip (File f, boolean compress)
throws IOException
{
return (
openMaybeZip (
new BufferedInputStream (new FileInputStream (f)),
compress
)
);
}
public static InputStream openInputMaybeZip (File f)
throws IOException
{
return (openInputMaybeZip (f, looksLikeZip (f)));
}
public static OutputStream openOutputMaybeZip (File f, boolean compress)
throws IOException
{
return (
openMaybeZip (
new BufferedOutputStream (new FileOutputStream (f)),
compress
)
);
}
public static OutputStream openOutputMaybeZip (File f)
throws IOException
{
return (openOutputMaybeZip (f, looksLikeZip (f)));
}
public static void closeMaybeZip (InputStream is) throws IOException {
is.close ();
}
public static void closeMaybeZip (OutputStream os) throws IOException {
if (os instanceof ZipOutputStream) {
ZipOutputStream zipos = (ZipOutputStream) os;
zipos.closeEntry ();
zipos.finish ();
}
else
os.close ();
}
/**
* Write a serializable object to file.
*
* @param f File to write to.
* @param compress Whether to zip up the object.
*/
public static void writeSerializable (
File f,
Serializable obj,
boolean compress
)
throws IOException
{
FileOutputStream fos = new FileOutputStream (f);
try {
OutputStream os = openMaybeZip (fos, compress);
{
ObjectOutputStream oos = new ObjectOutputStream (os);
oos.writeObject (obj);
oos.flush ();
}
closeMaybeZip (os);
} finally {
Util.close (fos);
}
}
/**
* Write a serializable object to file. If the file has the ".zip" extension,
* the object is compressed on write, and a zip file is created.
*
* @param f File to write to.
*/
public static void writeSerializable (File f, Serializable obj)
throws IOException
{
writeSerializable (f, obj, looksLikeZip (f));
}
/**
* Copies files from the specified directory to the specified directory.
* @param from -- directory to copy files from
* @param to -- directory to copy files to
* @param create -- if true and to directory does not exist create it.
* @param recursive -- if true also copies child directories
* @param filter -- if not null only copies files that satisfy the specified filter
* @param excludeFilter -- if not null does not copy files that satisfy the filter
*/
public static void copyDirectory (
File from,
File to,
boolean create,
boolean recursive,
FilenameFilter filter,
FilenameFilter excludeFilter
)
throws IOException, InterruptedException
{
if (create){
if (!to.exists()){
to.mkdirs();
}
}
File [] fileList = from.listFiles(filter);
if (fileList == null)
throw new FileNotFoundException (from.getPath ());
for (int i = 0; i < fileList.length; i++){
File f = fileList [i];
if ((excludeFilter == null)||(!excludeFilter.accept(to, f.getName()))){
File copy = new File (to, f.getName());
if (f.isDirectory()){
copy.mkdir();
if (recursive){
copyDirectory (f, copy, false, recursive, filter, excludeFilter);
}
}
else{
copyFile(f, copy);
}
}
}
}
/**
* Native Java7-way, copies files from the specified directory to the specified directory.
* @param from -- directory to copy files from
* @param to -- directory to copy files to
* @param create -- if true and to directory does not exist create it.
* @param recursive -- if true also copies child directories
* @param filter -- if not null only copies files that satisfy the specified filter
* @param excludeFilter -- if not null does not copy files that satisfy the filter
*/
public static void copyDirectory7 (
final File from,
final File to,
final boolean create,
final boolean recursive,
final FilenameFilter filter,
final FilenameFilter excludeFilter
)
throws IOException, InterruptedException
{
final SimpleFileVisitor visitor = new SimpleFileVisitor() {
private Path fromPath = Paths.get(from.toURI());
private Path toPath = Paths.get(to.toURI());
private StandardCopyOption copyOption = StandardCopyOption.REPLACE_EXISTING;
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path targetPath = toPath.resolve(fromPath.relativize(dir));
if(!Files.exists(targetPath)){
if (create) {
Files.createDirectory(targetPath);
}
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
final String fileName = file.toFile().getName();
if (
((filter == null) || (filter.accept(from, fileName)))
&&
((excludeFilter == null) || (!excludeFilter.accept(to, fileName)))
) {
Files.copy(file, toPath.resolve(fromPath.relativize(file)), copyOption);
}
return FileVisitResult.CONTINUE;
}
};
Files.walkFileTree(Paths.get(from.toURI()), EnumSet.of(FileVisitOption.FOLLOW_LINKS), recursive ? Integer.MAX_VALUE : 1, visitor);
}
private static String getCmdAsString (String [] arr) {
StringBuffer sb = new StringBuffer ();
for (int ii = 0; ii < arr.length; ii++) {
if (ii > 0)
sb.append (' ');
sb.append ('\'');
sb.append (arr [ii]);
sb.append ('\'');
}
return (sb.toString ());
}
public static long getFreeDiskSpaceOn(File filesys)
throws IOException, InterruptedException {
if (!filesys.exists())
throw new FileNotFoundException(filesys.getPath());
String fsep = System.getProperty("file.separator");
String[] cmd = null;
boolean dos = true;
if (fsep.equals("\\"))
cmd = new String[] { "cmd.exe", "/c", "dir", filesys.getPath()};
else {
cmd = new String[] { "/usr/bin/df", "-k", filesys.getPath()};
dos = false;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
int ret =
ProcessHelper.execAndWait(
cmd,
null,
null,
false,
baos,
true,
null,
false);
} catch (IOException e) {
cmd = new String[] { "df", "-k", filesys.getPath()};
int ret =
ProcessHelper.execAndWait(
cmd,
null,
null,
false,
baos,
true,
null,
false);
if (ret != 0)
throw new IOException(
"Command\n" + getCmdAsString(cmd) + "\nexited with " + ret);
}
String s = new String(baos.toByteArray());
if (System.getProperty("debug.diskspace") != null)
System.out.println(
"Output from\n" + getCmdAsString(cmd) + ":\n" + s);
int pos = -1;
long value = 0;
if (dos) {
pos = s.lastIndexOf(" bytes free");
if (pos < 0)
throw new IOException(
"Unrecognized output from\n"
+ getCmdAsString(cmd)
+ ":\n"
+ s);
long exp = 1;
for (;;) {
pos--;
char ch = s.charAt(pos);
if (ch == ' ')
break;
if (ch == ',')
continue;
value += exp * (ch - '0');
exp *= 10;
}
} else {
StringTokenizer st = new StringTokenizer(s);
for (int i = 1; i < 11; i++) {
st.nextToken();
if (i == 10)
value = Long.parseLong(st.nextToken());
value *= 1024; // df -k gives us in kilobytes
}
}
return (value);
}
public static final class FileOnlyFilter implements FileFilter {
public boolean accept(File pathname)
{
return pathname.isFile ();
}
}
/**
* Writes any CharSequence to DataOutput as a 2-byte length (in characters), followed by
* that many characters in raw 2-byte form.
*/
public static int writeUnicode (CharSequence str, DataOutput out) throws IOException {
int strlen = str.length ();
if (strlen > 65535)
throw new UTFDataFormatException ("string too long: " + strlen + " bytes");
out.writeShort ((short) strlen);
for (int ii = 0; ii < strlen; ii++)
out.writeChar (str.charAt (ii));
return (strlen * 2 + 2);
}
/**
* Writes any CharSequence to DataOutput in a way identical to
* DataOutputStream.writeUTF, which is groundlessly defined too narrowly
* by forcing the argument to be a String.
*/
public static int writeUTF (CharSequence str, DataOutput out) throws IOException {
int strlen = str.length();
int utflen = 0;
int c, count = 0;
/* use charAt instead of copying String to char array */
for (int i = 0; i < strlen; i++) {
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
utflen++;
} else if (c > 0x07FF) {
utflen += 3;
} else {
utflen += 2;
}
}
if (utflen > 65535)
throw new UTFDataFormatException(
"encoded string too long: " + utflen + " bytes");
if (out instanceof LittleEndianDataOutputStream) {
out.writeByte((utflen >>> 0) & 0xFF);
out.writeByte((utflen >>> 8) & 0xFF);
} else {
out.writeByte((utflen >>> 8) & 0xFF);
out.writeByte((utflen >>> 0) & 0xFF);
}
int i=0;
for (i=0; i= 0x0001) && (c <= 0x007F))) break;
out.writeByte (c);
}
for (;i < strlen; i++){
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F))
out.writeByte (c);
else if (c > 0x07FF) {
out.writeByte (0xE0 | ((c >> 12) & 0x0F));
out.writeByte (0x80 | ((c >> 6) & 0x3F));
out.writeByte (0x80 | ((c >> 0) & 0x3F));
}
else {
out.writeByte (0xC0 | ((c >> 6) & 0x1F));
out.writeByte (0x80 | ((c >> 0) & 0x3F));
}
}
return utflen + 2;
}
/**
* Reads (appends) a UTF string to an Appendable (such as StringBuidler),
* without clearing it first.
*/
@Deprecated // buggy
public final static void readUTF(DataInput in, Appendable sb) throws IOException {
int utflen = in.readUnsignedShort();
if (utflen == 0)
return;
int c;
int char2, char3;
int count = 0;
for (;;) {
c = in.readByte (); //NB: result in range [-128, 127] -- Andy
//if (c > 127)
// break;
count++;
sb.append ((char) c);
if (count >= utflen)
return;
}
// de-facto unreachable -- Andy
// // If we are here, we have broken out of the previous loop and there is an
// // unhandled escape character in variable c.
// for (;;) {
// switch (c >> 4) {
// case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// /* 0xxxxxxx*/
// count++;
// sb.append ((char)c);
// break;
//
// case 12: case 13:
// /* 110x xxxx 10xx xxxx*/
// count += 2;
// if (count > utflen)
// throw new UTFDataFormatException(
// "malformed input: partial character at end");
// char2 = in.readByte ();
// if ((char2 & 0xC0) != 0x80)
// throw new UTFDataFormatException(
// "malformed input around byte " + count);
// sb.append ((char)(((c & 0x1F) << 6) |
// (char2 & 0x3F)));
// break;
//
// case 14:
// /* 1110 xxxx 10xx xxxx 10xx xxxx */
// count += 3;
// if (count > utflen)
// throw new UTFDataFormatException(
// "malformed input: partial character at end");
// char2 = in.readByte ();
// char3 = in.readByte ();
// if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
// throw new UTFDataFormatException(
// "malformed input around byte " + (count-1));
// sb.append ((char)(((c & 0x0F) << 12) |
// ((char2 & 0x3F) << 6) |
// ((char3 & 0x3F) << 0)));
// break;
//
// default:
// /* 10xx xxxx, 1111 xxxx */
// throw new UTFDataFormatException(
// "malformed input around byte " + count);
// }
//
// if (count >= utflen)
// break;
//
// c = in.readByte ();
// }
}
/**
* Reads (appends) a UTF string to an Appendable (such as StringBuidler),
* without clearing it first.
*/
@Deprecated // buggy
public final static void readUTF(ByteBuffer in, Appendable sb) throws BufferUnderflowException, IOException {
int utflen = 0xFFFF & in.getShort();
if (utflen == 0)
return;
int c;
int char2, char3;
int count = 0;
for (;;) {
c = in.get (); //NB: result in range [-128, 127] -- Andy
// if (c > 127)
// break;
count++;
sb.append ((char) c);
if (count >= utflen)
return;
}
// de-facto unreachable -- Andy
// // If we are here, we have broken out of the previous loop and there is an
// // unhandled escape character in variable c.
// for (;;) {
// switch (c >> 4) {
// case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// /* 0xxxxxxx*/
// count++;
// sb.append ((char)c);
// break;
//
// case 12: case 13:
// /* 110x xxxx 10xx xxxx*/
// count += 2;
// if (count > utflen)
// throw new UTFDataFormatException(
// "malformed input: partial character at end");
// char2 = in.get ();
// if ((char2 & 0xC0) != 0x80)
// throw new UTFDataFormatException(
// "malformed input around byte " + count);
// sb.append ((char)(((c & 0x1F) << 6) |
// (char2 & 0x3F)));
// break;
//
// case 14:
// /* 1110 xxxx 10xx xxxx 10xx xxxx */
// count += 3;
// if (count > utflen)
// throw new UTFDataFormatException(
// "malformed input: partial character at end");
// char2 = in.get ();
// char3 = in.get ();
// if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
// throw new UTFDataFormatException(
// "malformed input around byte " + (count-1));
// sb.append ((char)(((c & 0x0F) << 12) |
// ((char2 & 0x3F) << 6) |
// ((char3 & 0x3F) << 0)));
// break;
//
// default:
// /* 10xx xxxx, 1111 xxxx */
// throw new UTFDataFormatException(
// "malformed input around byte " + count);
// }
//
// if (count >= utflen)
// break;
//
// c = in.get ();
// }
}
public static long addFileToZip (File f, ZipOutputStream zos, String path)
throws IOException, InterruptedException
{
return (addFileToZip (f, zos, path, null));
}
public static interface EntryListener {
public void entryAdded (ZipEntry e)
throws IOException, InterruptedException;
}
public static long addFileToZip (
File f,
ZipOutputStream zos,
String path,
EntryListener listener
)
throws IOException, InterruptedException
{
if (f.isDirectory ()) {
File [] files = f.listFiles ();
long length = 0;
if (files != null) {
for (File ff : files)
length +=
addFileToZip (
ff,
zos,
path == null ? ff.getName () : path + '/' + ff.getName (),
listener
);
}
return (length);
}
else {
ZipEntry e = new ZipEntry (path);
long length = f.length ();
e.setTime (f.lastModified ());
e.setSize (length);
zos.putNextEntry (e);
FileInputStream fis = new FileInputStream (f);
try {
StreamPump.pump (fis, zos);
} finally {
fis.close ();
}
zos.closeEntry ();
if (listener != null)
listener.entryAdded (e);
return (length);
}
}
public static void rezip (
ZipFile src,
ZipOutputStream zos,
String pathPrefix,
boolean ignoreDuplicates
)
throws IOException, InterruptedException
{
Enumeration extends ZipEntry> entries = src.entries ();
while (entries.hasMoreElements ()) {
ZipEntry srcEntry = entries.nextElement ();
String name = srcEntry.getName ();
if (pathPrefix != null)
name = pathPrefix + name;
ZipEntry e = new ZipEntry (name);
e.setTime (srcEntry.getTime ());
e.setSize (srcEntry.getSize ());
try {
zos.putNextEntry (e);
} catch (ZipException x) {
if (ignoreDuplicates && x.getMessage ().startsWith ("duplicate entry"))
continue;
throw x;
}
InputStream is = src.getInputStream (srcEntry);
try {
StreamPump.pump (is, zos);
} finally {
is.close ();
}
zos.closeEntry ();
}
}
public static String replaceProperties(Properties properties, File xmlFile, String xml) throws IOException {
Pattern p = Pattern.compile("\\$\\{([^\\}]*)\\}");
Matcher m = p.matcher(xml);
StringBuffer result = new StringBuffer (xml.length() + 128);
while (m.find()) {
String propertyName = m.group(1);
String propertyValue = properties.getProperty(propertyName);
if (propertyValue != null) {
// escape / and $ as they have special meaning for Matcher.appendReplacement()
propertyValue = propertyValue.replace ("\\", "\\\\");
propertyValue = propertyValue.replace ("$", "\\$");
m.appendReplacement(result, propertyValue);
} else {
throw new IOException ("Cannot find system property \"" + propertyName + "\" defined in " + xmlFile.getAbsolutePath());
}
}
m.appendTail(result);
return result.toString();
}
public static String replaceProperties(Properties properties, File xmlFile) throws IOException, InterruptedException {
String xml = BasicIOUtil.readTextFile(xmlFile);
return replaceProperties(properties, xmlFile, xml);
}
/** Replaces System properties defined in given file as "${property name}" into "{property value}" */
public static String replaceSystemProperties (File xmlFile) throws IOException, InterruptedException {
return replaceProperties(System.getProperties(), xmlFile);
}
/** Replaces System properties defined in given string "${property name}" into "{property value}" */
public static String replaceSystemProperties(File xmlFile, String xml) throws IOException {
return replaceProperties(System.getProperties(), xmlFile, xml);
}
public static LineNumberReader toLineNumberReader (Reader r) {
return (
r instanceof LineNumberReader ?
(LineNumberReader) r :
new LineNumberReader (r)
);
}
public static void dumpWithLineNumbers (Reader text, PrintWriter out)
throws IOException
{
LineNumberReader lnr = toLineNumberReader (text);
String line;
while ((line = lnr.readLine ()) != null)
out.printf ("%-4d: %s\n", lnr.getLineNumber (), line);
}
public static void dumpWithLineNumbers (Reader text, PrintStream out)
throws IOException
{
LineNumberReader lnr = toLineNumberReader (text);
String line;
while ((line = lnr.readLine ()) != null)
out.printf ("%-4d: %s\n", lnr.getLineNumber (), line);
}
public static void dumpWithLineNumbers (CharSequence text, PrintWriter out) {
try {
dumpWithLineNumbers (new CharSequenceReader (text), out);
} catch (IOException x) {
throw new RuntimeException (x);
}
}
public static void dumpWithLineNumbers (CharSequence text, PrintStream out) {
try {
dumpWithLineNumbers (new CharSequenceReader (text), out);
} catch (IOException x) {
throw new RuntimeException (x);
}
}
public static void recursiveListFiles(File root, FileFilter filter, Collection listFiles) {
if (root != null && root.isDirectory ()) {
final File[] contents = root.listFiles ();
if (contents != null) {
for (int index = 0; index < contents.length; index++) {
final File f = contents[index];
if (f.isDirectory ()) {
recursiveListFiles (f,
filter,
listFiles);
} else {
if (filter.accept (f))
listFiles.add (f);
}
}
}
}
}
private static void expandChildPath (
File root,
String [] dirs,
int dirPos,
ArrayList out,
boolean assertExists,
Comparator comparator
)
throws FileNotFoundException
{
File cur = root;
for (;;) {
if (dirPos == dirs.length) {
out.add (cur);
return;
}
String s = dirs [dirPos++];
if (ShellPatternCSMatcher.isPattern (s)) {
File [] children = cur.listFiles ();
if (assertExists && !cur.isDirectory ())
throw new FileNotFoundException ("Not a directory: " + cur.getPath ());
if (children == null)
return;
if (comparator != null)
Arrays.sort (children, comparator);
for (File child : children) {
if (ShellPatternCSMatcher.INSTANCE.matches (child.getName (), s))
expandChildPath (child, dirs, dirPos, out, false, comparator);
}
return;
}
cur = new File (cur, s);
if (assertExists && !cur.exists ())
throw new FileNotFoundException (cur.getPath ());
}
}
public static ArrayList expandPath (String path)
throws FileNotFoundException
{
return (expandPath (path, true));
}
public static ArrayList expandPath (
String path,
boolean assertRootExists
)
throws FileNotFoundException
{
return (expandPath (path, new ComparableComparator (), assertRootExists));
}
public static ArrayList expandPath (
String path,
Comparator comparator,
boolean assertRootExists
)
throws FileNotFoundException
{
String [] dirs = path.replace ('\\', '/').split ("/");
ArrayList files = new ArrayList <> ();
File root = new File(dirs[0].endsWith(":") ? dirs[0] + "\\" : dirs[0]);
expandChildPath (root, dirs, 1, files, assertRootExists, comparator);
return (files);
}
public static String fname (String path) {
int a = path.lastIndexOf ('/');
int b = path.lastIndexOf ('\\');
if (a < 0 && b < 0)
return (path);
return (path.substring (Math.max (a, b) + 1));
}
public static String fhead (String path) {
int n = path.lastIndexOf ('.');
return (n < 0 ? path : path.substring (0, n));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy