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

javaxt.io.File Maven / Gradle / Ivy

package javaxt.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Locale;

//******************************************************************************
//**  File Class
//******************************************************************************
/**
 * Used to represent a single file on a file system. In many ways, this class is
 * an extension of the java.io.File class. However, unlike the java.io.File
 * class, this object provides functions that are relevant and specific to files
 * (not directories).
 *
 ******************************************************************************/

public class File implements Comparable {

	private java.io.File file; // <--DO NOT USE DIRECTLY! Use getFile() instead.
	private String name = "";
	private String path = "";
	private FileAttributes attr;
	private long lastAttrUpdate = 0;

	public final String PathSeparator = System.getProperty("file.separator");
	public final String LineSeperator = System.getProperty("line.separator");
	private static final boolean isWindows = Directory.isWindows;
	private int bufferSize = 1024 * 1024; // 1MB

	// **************************************************************************
	// ** Constructor
	// **************************************************************************
	/**
	 * Creates a new File instance by converting the given pathname string into
	 * an abstract pathname.
	 */
	public File(String Path) {
		if (Path == null) {
			throw new NullPointerException();
		}

		if (Path.startsWith("\"") && Path.endsWith("\"")) {
			Path = Path.substring(1, Path.length() - 1).trim();
		}
		if (Path.endsWith("\\") || Path.endsWith("/")) {
			throw new IllegalArgumentException("Invalid Path: " + Path);
		}

		init(Path);

		// int idx = Path.replace("\\", "/").lastIndexOf("/")+1;
		// path = Path.substring(0, idx);
		// name = Path.substring(idx);
	}

	// **************************************************************************
	// ** Constructor
	// **************************************************************************
	/**
	 * Instantiates this class using a java.io.File. Please use the Directory
	 * class for directories. Example:
	 * 
	 * 
	 * if (file.isDirectory())
	 *     new Directory(file);
	 * 
*/ public File(java.io.File File) { if (File == null) { throw new NullPointerException(); } if (File.isDirectory()) { throw new IllegalArgumentException("Invalid Path."); } this.file = File; init(file.getAbsolutePath()); } // ************************************************************************** // ** Constructor // ************************************************************************** /** * Creates a new File instance from a parent abstract pathname and a child * pathname string. */ public File(java.io.File Parent, String Child) { this(Parent.getPath(), Child); } public File(Directory Parent, String Child) { this(Parent.getPath(), Child); } public File(String Parent, String Child) { if (Parent == null || Child == null) { throw new NullPointerException(); } // Normalize the strings Parent = Parent.replace("\\", "/"); Child = Child.replace("\\", "/"); // Combine the Parent and Child into a single path. This is done in // case the Child variable contains additional path information. if (!Parent.endsWith("/")) Parent += "/"; if (Child.startsWith("/")) Child = Child.substring(1); if (Child.endsWith("/")) Child = Child.substring(0, Child.length() - 1); init(Parent + Child); } /** * Used to parse the absolute path to the file. For performance reasons, we * do not rely on the java.io.File to determine the path and name variables. */ private void init(String Path) { Path = Path.replace("\\", "/"); String[] arr = Path.split("/"); if (arr.length > 1) { name = arr[arr.length - 1]; path = Path.substring(0, Path.lastIndexOf(name)); } else { path = Path; } if (path.isEmpty()) path = PathSeparator; else path = path.replace("/", PathSeparator); if (!path.endsWith(PathSeparator)) path += PathSeparator; } // ************************************************************************** // ** Get File Name // ************************************************************************** /** Returns the name of the file, excluding the path. */ public String getName() { return name; } // ************************************************************************** // ** Get File Name // ************************************************************************** /** * Returns the name of the file, excluding the path. * * @param IncludeFileExtension * If true, includes the file extension. Otherwise, will return * the file name without the extension. */ public String getName(boolean IncludeFileExtension) { if (!IncludeFileExtension) { int idx = name.lastIndexOf("."); if (idx > -1) return name.substring(0, idx); } return name; } // ************************************************************************** // ** Get File Path // ************************************************************************** /** * Used to retrieve the path to the file, excluding the file name. Appends a * file separator to the end of the string. */ public String getPath() { return path; } // ************************************************************************** // ** Get Directory // ************************************************************************** /** Returns the file's parent directory. Same as getParentDirectory() */ public Directory getDirectory() { return getParentDirectory(); } // ************************************************************************** // ** Get Parent Directory // ************************************************************************** /** * Returns the file's parent directory. Returns null if the parent directory * is unknown. */ public Directory getParentDirectory() { if (path.length() > 0) return new Directory(path); else return null; } // ************************************************************************** // ** toFile // ************************************************************************** /** Returns the java.io.File representation of this object. */ public java.io.File toFile() { return getFile(); } // ************************************************************************** // ** getFile // ************************************************************************** /** Returns the java.io.File representation of this object. */ private java.io.File getFile() { if (file == null) file = new java.io.File(path + name); return file; } // ************************************************************************** // ** Get File Extension // ************************************************************************** /** * Returns the file's extension, excluding the last dot/period (e.g. * "C:\image.jpg" will return "jpg"). Returns a zero-length string if there * is no extension. */ public String getExtension() { int idx = name.lastIndexOf("."); if (idx > -1) return name.substring(idx + 1); else return ""; } // ************************************************************************** // ** getSize // ************************************************************************** /** * Returns the size of the file, in bytes. Returns 0L if the file is does * not exist or if the object is a directory. */ public long getSize() { if (file != null) return getFileSize(); try { FileAttributes attr = getFileAttributes(); if (attr != null) return attr.getSize(); else { getFile(); return getFileSize(); } } catch (java.io.FileNotFoundException e) { return 0L; } } private long getFileSize() { long size = file.length(); if (size > 0L && file.isFile()) return size; else return 0L; } // ************************************************************************** // ** getDate // ************************************************************************** /** * Returns a timestamp of when the file was last modified. Returns null if * the file does not exist or if the object is a directory. */ public java.util.Date getDate() { if (file != null) return getFileDate(); try { FileAttributes attr = getFileAttributes(); if (attr != null) return attr.getLastWriteTime(); else { getFile(); return getFileDate(); } } catch (java.io.FileNotFoundException e) { return null; } } private java.util.Date getFileDate() { if (file.exists() && file.isFile()) return new java.util.Date(file.lastModified()); else return null; } // ************************************************************************** // ** setDate // ************************************************************************** /** * Used to set/update the last modified date. */ public boolean setDate(java.util.Date lastModified) { if (lastModified != null) { java.io.File file = getFile(); if (file.exists() && file.isFile()) { long t = lastModified.getTime(); if (getDate().getTime() != t) { attr = null; return getFile().setLastModified(t); } } } return false; } // ************************************************************************** // ** Exists // ************************************************************************** /** * Used to determine whether a file exists. Returns false if the file system * can't find the file or if the object is a directory. */ public boolean exists() { if (file != null) { return (file.isFile() && file.exists()); } try { FileAttributes attr = getFileAttributes(); if (attr != null) return true; else { getFile(); return (file.isFile() && file.exists()); } } catch (java.io.FileNotFoundException e) { return false; } } // ************************************************************************** // ** isHidden // ************************************************************************** /** * Used to check whether the file is hidden. Returns true if the file exists * and is hidden according to the conventions of the underlying file system. */ public boolean isHidden() { if (file != null) { return (file.isFile() && file.isHidden()); } try { FileAttributes attr = getFileAttributes(); if (attr != null) return attr.isHidden(); else { getFile(); return (file.isFile() && file.isHidden()); } } catch (java.io.FileNotFoundException e) { return false; } } // ************************************************************************** // ** isReadOnly // ************************************************************************** /** * Used to check whether the file has write permissions. Returns true if the * file exists and the application is not allowed to write to the file. */ public boolean isReadOnly() { if (file != null) { return (file.isFile() && !file.canWrite()); } try { FileAttributes attr = getFileAttributes(); if (attr != null) return attr.isReadOnly(); else { getFile(); return (file.isFile() && !file.canWrite()); } } catch (java.io.FileNotFoundException e) { return false; } } // ************************************************************************** // ** isExecutable // ************************************************************************** /** * Used to check whether the file has execute permissions. Note that this * method is not supported by JDK 1.5 or lower. Instead, the method will * return false. */ public boolean isExecutable() { java.io.File File = getFile(); if (File != null) { // return File.canExecute(); //<--incompatable with JDK 1.5 String[] arr = System.getProperty("java.version").split("\\."); if (Integer.valueOf(arr[0]).intValue() == 1 && Integer.valueOf(arr[1]).intValue() < 6) return false; else { try { return (Boolean) File.getClass().getMethod("canExecute").invoke(File, null); } catch (Exception e) { return false; } } } else return false; } // ************************************************************************** // ** isLink // ************************************************************************** /** * Used to determine whether the file is actually a link to another file. * Returns true for symbolic links, Windows junctions, and Windows * shortcuts. */ public boolean isLink() { return getLink() != null; } // ************************************************************************** // ** getLink // ************************************************************************** /** * Returns the target of a symbolic link, Windows junction, or Windows * shortcut. */ public java.io.File getLink() { try { return getFileAttributes().getLink(); } catch (Exception e) { return null; } } // ************************************************************************** // ** Delete File // ************************************************************************** /** Used to delete the file. Warning: this operation is irrecoverable. */ public boolean delete() { java.io.File file = getFile(); if (file != null) { if (file.delete()) { attr = null; return true; } } return false; } // ************************************************************************** // ** setBufferSize // ************************************************************************** /** * Used to set the size of the buffer used to read/write bytes. The default * is 1MB (1,048,576 bytes) */ public void setBufferSize(int numBytes) { bufferSize = numBytes; } // ************************************************************************** // ** Move File // ************************************************************************** /** * Used to move the file to a different directory. If the operation is * successful, returns a handle to the new file. Otherwise, the original * file is returned. */ public javaxt.io.File moveTo(Directory Destination) { return moveTo(new javaxt.io.File(Destination, getName()), true); } // ************************************************************************** // ** Move File // ************************************************************************** /** * Used to move the file to a different location. If the operation is * successful, returns a handle to the new file. Otherwise, the original * file is returned. */ public javaxt.io.File moveTo(javaxt.io.File Destination, boolean Overwrite) { if (Destination.exists()) { if (Overwrite) { Destination.delete(); } else { return this; } } java.io.File oldFile = getFile(); java.io.File newFile = Destination.toFile(); newFile.getParentFile().mkdirs(); if (oldFile.renameTo(newFile)) { attr = null; file = newFile; init(file.getAbsolutePath()); } return this; } // ************************************************************************** // ** Copy File // ************************************************************************** /** * Used to create a copy of this file. Preserves the last modified date * associated with the source file. Returns true if the file was copied * successfully. */ public boolean copyTo(Directory Destination, boolean Overwrite) { return copyTo(new File(Destination, getName()), Overwrite); } // ************************************************************************** // ** Copy File // ************************************************************************** /** * Used to create a copy of this file. Preserves the last modified date * associated with the source file. Returns true if the file was copied * successfully. */ public boolean copyTo(javaxt.io.File Destination, boolean Overwrite) { // Validate Input/Output java.io.File File = getFile(); if (File.exists() == false) return false; if (Destination.exists() && Overwrite == false) return false; if (File.equals(Destination.toFile())) return false; // Create New Path Destination.getParentDirectory().create(); // Copy File ReadableByteChannel inputChannel = null; WritableByteChannel outputChannel = null; try { FileInputStream input = new FileInputStream(File); FileOutputStream output = new FileOutputStream(Destination.toFile()); inputChannel = Channels.newChannel(input); outputChannel = Channels.newChannel(output); final java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocateDirect(bufferSize); while (inputChannel.read(buffer) != -1) { buffer.flip(); outputChannel.write(buffer); buffer.compact(); } buffer.flip(); while (buffer.hasRemaining()) { outputChannel.write(buffer); } inputChannel.close(); outputChannel.close(); Destination.toFile().setLastModified(File.lastModified()); return true; } catch (Exception e) { try { inputChannel.close(); } catch (Exception ex) { } try { outputChannel.close(); } catch (Exception ex) { } return false; } } // ************************************************************************** // ** Rename File // ************************************************************************** /** * Used to rename the file. The existing file name is replaced with a new * name. Only the file name is affected. The file path remains unchanged. * This method is therefore different from the java.io.File "renameTo" * method. If the operation is successful, returns a handle to the new file. * Otherwise, the original file is returned. * * @param FileName * The new file name (including the file extension). */ public javaxt.io.File rename(String FileName) { if (FileName != null) { FileName = FileName.trim(); if (FileName.length() > 0) { java.io.File File = getFile(); if (File != null) { java.io.File newFile = new java.io.File(getPath() + FileName); if (File.renameTo(newFile)) { attr = null; file = newFile; init(file.getAbsolutePath()); } } } } return this; } // ************************************************************************** // ** getBufferedWriter // ************************************************************************** /** * Used to instantiate a BufferedWriter for this file. */ public BufferedWriter getBufferedWriter(String charsetName) { try { java.io.File File = getFile(); attr = null; File.getParentFile().mkdirs(); if (charsetName == null) { return new BufferedWriter(new FileWriter(File)); } else { return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(File), charsetName)); } } catch (Exception e) { return null; } } // ************************************************************************** // ** getBufferedReader // ************************************************************************** /** * Used to extract the contents of the file into a BufferedReader. * *
	 * BufferedReader br = file.getBufferedReader("UTF-8");
	 * String strLine;
	 * while ((strLine = br.readLine()) != null) {
	 *     System.out.println(strLine);
	 * }
	 * 
* * @return BufferedReader or null */ public BufferedReader getBufferedReader() { java.io.File File = getFile(); if (File.exists()) { try { // NOTE: FileReader always assumes default encoding is OK! return new BufferedReader(new FileReader(File)); } catch (Exception e) { } } return null; } // ************************************************************************** // ** getBufferedReader // ************************************************************************** /** * Used to extract the contents of the file into a BufferedReader. * *
	 * BufferedReader br = file.getBufferedReader("UTF-8");
	 * String strLine;
	 * while ((strLine = br.readLine()) != null) {
	 *     System.out.println(strLine);
	 * }
	 * 
* * WARNING: This method will never throw an error. * * @param charsetName * Name of the character encoding used to read the file. Examples * include UTF-8 and ISO-8859-1 */ public BufferedReader getBufferedReader(String charsetName) { java.io.File File = getFile(); if (File.exists()) { try { return new java.io.BufferedReader(new java.io.InputStreamReader(this.getInputStream(), charsetName)); } catch (Exception e) { } } return null; } // ************************************************************************** // ** getBufferedImage // ************************************************************************** public java.awt.image.BufferedImage getBufferedImage() { Image img = getImage(); if (img != null) return img.getBufferedImage(); return null; } // ************************************************************************** // ** getImage // ************************************************************************** /** * Used to open the file and read the contents into an image. */ public Image getImage() { java.io.File File = getFile(); if (File.exists()) return new Image(File); else return null; } // ************************************************************************** // ** getText // ************************************************************************** /** * Used to open the file and read the contents into a string. */ public String getText() { try { return getText("UTF-8"); } catch (Exception e) { } try { return getBytes().toString(); } catch (Exception e) { } return ""; } // ************************************************************************** // ** getText // ************************************************************************** /** * Used to extract the contents of the file as a String. Returns an empty * String if the file is empty or the contents cannot be converted to a * String. * * @param charsetName * Name of the character encoding used to read the file. Examples * include UTF-8 and ISO-8859-1 */ public String getText(String charsetName) { try { return getBytes().toString(charsetName); } catch (Exception e) { } return ""; } // ************************************************************************** // ** getXML // ************************************************************************** /** * Returns an XML DOM Document (org.w3c.dom.Document) represented by this * file. Returns a null if the file contents cannot be converted into a DOM * Document. */ public org.w3c.dom.Document getXML() { FileInputStream is = null; try { is = getInputStream(); org.w3c.dom.Document xml = javaxt.xml.DOM.createDocument(is); is.close(); return xml; } catch (Exception e) { } finally { if (is != null) { try { is.close(); } catch (Exception e) { } } } return null; } // ************************************************************************** // ** getBytes // ************************************************************************** /** * Returns a ByteArrayOutputStream for the file. Returns a null if a * ByteArrayOutputStream cannot be created (e.g. file does not exist). */ public ByteArrayOutputStream getBytes() { return getBytes(getFile(), bufferSize); } private static ByteArrayOutputStream getBytes(java.io.File File, int bufferSize) { if (File.exists()) { FileInputStream is = null; try { is = new FileInputStream(File); ByteArrayOutputStream bas = new ByteArrayOutputStream(); byte[] b = new byte[bufferSize]; int x = 0; while ((x = is.read(b, 0, bufferSize)) > -1) { bas.write(b, 0, x); } bas.close(); is.close(); return bas; } catch (Exception e) { } finally { if (is != null) { try { is.close(); } catch (Exception e) { } } } } return null; } // ************************************************************************** // ** checksum // ************************************************************************** /** * Returns a long value representing a cyclic redundancy check (CRC-32 * checksum) of the file, or -1 if not known. */ public long checksum() { if (!exists()) return -1; try { java.util.zip.CRC32 crc = new java.util.zip.CRC32(); crc.update(getBytes().toByteArray()); return crc.getValue(); } catch (Exception e) { return -1; } } // ************************************************************************** // ** getSHA1 // ************************************************************************** /** * Returns a string representing the SHA-1 hash for the file. */ public String getSHA1() { return getHash("SHA-1"); } // ************************************************************************** // ** getMD5 // ************************************************************************** /** * Returns a string representing the MD5 hash for the file. */ public String getMD5() { return getHash("MD5"); } // ************************************************************************** // ** getHash // ************************************************************************** private String getHash(String algorithm) { if (!exists()) return null; try { java.security.MessageDigest md = java.security.MessageDigest.getInstance(algorithm); InputStream input = getInputStream(); byte[] buf = new byte[bufferSize]; int i = 0; while ((i = input.read(buf)) != -1) { md.update(buf, 0, i); } input.close(); return new javax.xml.bind.annotation.adapters.HexBinaryAdapter().marshal(md.digest()).toLowerCase(); } catch (Exception e) { e.printStackTrace(); return null; } } // ************************************************************************** // ** write // ************************************************************************** /** * Creates a new file using the given ByteArrayOutputStream. Note that this * method will convert the ByteArrayOutputStream to a byte array using the * toByteArray() method which may result in memory issues. */ public void write(ByteArrayOutputStream bas) { write(bas.toByteArray()); } // ************************************************************************** // ** write // ************************************************************************** /** * Creates a new file using the given byte array. */ public void write(byte[] bytes) { java.io.File File = getFile(); attr = null; if (File != null) { FileOutputStream output = null; try { File.getParentFile().mkdirs(); output = new FileOutputStream(File); output.write(bytes); } catch (Exception e) { } finally { try { if (output != null) output.close(); } catch (Exception e) { } } } } // ************************************************************************** // ** write // ************************************************************************** /** * Creates a new file using the given InputStream. Note that the caller is * responsible for closing the input stream after the method is complete. */ public void write(InputStream input) { java.io.File File = getFile(); attr = null; if (File != null) { FileOutputStream output = null; try { File.getParentFile().mkdirs(); output = new FileOutputStream(File); byte[] buf = new byte[bufferSize]; int i = 0; while ((i = input.read(buf)) != -1) { output.write(buf, 0, i); } } catch (Exception e) { } finally { try { if (output != null) output.close(); } catch (Exception e) { } } } } // ************************************************************************** // ** Write Text // ************************************************************************** /** * Used to write text to a file. Uses UTF-8 character encoding. Use the * other write method to specify a different character encoding (e.g. * ISO-8859-1). */ public void write(String Text) { write(Text, "UTF-8"); } // ************************************************************************** // ** Write Text // ************************************************************************** /** * Used to write text to a file. Allows users to specify character encoding. * * @param charsetName * Name of the character encoding used to read the file. Examples * include UTF-8 and ISO-8859-1. If null, the writer will use the * default character encoding defined on the host machine. */ public void write(String Text, String charsetName) { java.io.File File = getFile(); attr = null; if (File != null) { Writer output = null; try { File.getParentFile().mkdirs(); if (charsetName == null) { output = new BufferedWriter(new FileWriter(File)); } else { output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(File), charsetName)); } output.write(Text); } catch (Exception e) { } finally { try { if (output != null) output.close(); } catch (Exception e) { } } } } // ************************************************************************** // ** Write XML // ************************************************************************** /** * Used to write an XML DOM Document to a file. */ public void write(org.w3c.dom.Document xml) { write(javaxt.xml.DOM.getText(xml), xml.getXmlEncoding()); } // ************************************************************************** // ** Write Text // ************************************************************************** /** * Used to write text to a file using an array of strings. A new line is * created for each entry in the array. */ public void write(String[] Content) { java.io.File File = getFile(); attr = null; if (File != null) { Writer output = null; try { File.getParentFile().mkdirs(); output = new BufferedWriter(new FileWriter(File)); for (int i = 0; i < Content.length - 1; i++) { output.write(Content[i] + LineSeperator); } output.write(Content[Content.length - 1]); } catch (Exception e) { } finally { try { if (output != null) output.close(); } catch (Exception e) { } } } } // ************************************************************************** // ** Write Image // ************************************************************************** /** Used to write an image to a file. */ public void write(java.awt.image.BufferedImage Image) { java.io.File File = getFile(); attr = null; if (File != null) { try { File.getParentFile().mkdirs(); java.awt.image.RenderedImage rendImage = Image; javax.imageio.ImageIO.write(rendImage, getExtension(), File); } catch (Exception e) { // System.out.println(e.toString()); } } } // ************************************************************************** // ** MapPath // ************************************************************************** public String MapPath(String RelPath) { // Update currDir String currDir = getPath(); currDir = currDir.replace("\\", "/"); if (!currDir.endsWith("/")) { currDir += "/"; } RelPath = RelPath.replace("\\", "/"); if (RelPath.startsWith("/")) { return (currDir + RelPath.substring(1)).replace("/", PathSeparator); } String[] arrRelPath = RelPath.split("/"); String[] arrAbsPath = currDir.split("/"); int x = -1; RelPath = ""; String Dir = ""; for (int i = 0; i < arrRelPath.length; i++) { Dir = arrRelPath[i]; if (Dir.equals("..")) { x = x + 1; } else if (Dir.equals(".")) { // do nothing? } else { RelPath = RelPath + "\\" + arrRelPath[i]; } } // x = x + 1 'because currDir has a "\" at the end of it Dir = ""; int ubound = 0; for (int i = 0; i < arrAbsPath.length - (x + 1); i++) { // because // currDir has a // "\" at the // end of it Dir = Dir + arrAbsPath[i] + "\\"; } // trim off last "\" // Dir = left(Dir, len(Dir) - 1); Dir = Dir.substring(0, Dir.length() - 1); // replace any leftover "/" characters Dir = Dir + RelPath.replace("/", "\\"); Dir = Dir.replace("\\", PathSeparator); return Dir; } // ************************************************************************** // ** getInputStream // ************************************************************************** /** Returns a new FileInputStream Object */ public FileInputStream getInputStream() throws IOException { return new FileInputStream(getFile()); } // ************************************************************************** // ** getInputStream // ************************************************************************** /** Returns a new FileOutputStream Object */ public FileOutputStream getOutputStream() throws IOException { attr = null; return new FileOutputStream(getFile()); } // ************************************************************************** // ** toString // ************************************************************************** /** Returns the full file path (including the file name) */ @Override public String toString() { return path + name; } @Override public int hashCode() { if (isWindows) return toString().toLowerCase(Locale.ENGLISH).hashCode() ^ 1234321; // java.io.Win32FileSystem.java else return toString().hashCode() ^ 1234321; // java.io.UnixFileSystem.java } // @Override @Override public int compareTo(Object obj) { if (obj == null) return -1; else return -obj.toString().compareTo(getPath()); } // ************************************************************************** // ** equals // ************************************************************************** @Override public boolean equals(Object obj) { if (obj instanceof javaxt.io.File || obj instanceof java.io.File) { return obj.hashCode() == this.hashCode(); } return false; } // ************************************************************************** // ** clone // ************************************************************************** /** Creates a copy of this object. */ @Override public File clone() { return new File(this.toString()); } // ************************************************************************** // ** IsValidPath -- NOT USED! // ************************************************************************** /** Checks whether PathToFile is a valid */ private boolean isValidPath(String PathToFile) { if (PathToFile == null) return false; if (PathToFile.length() < 1) return false; // if (File.isDirectory()) return false; String FileName = getName(); if (FileName.length() < 1) return false; if (FileName.length() > 260) return false; PathToFile = toString(); PathToFile = PathToFile.replace("\\", "/"); String[] Path = PathToFile.split("/"); String[] arr = new String[] { "/", "?", "<", ">", "\\", ":", "*", "|", "\"" }; for (int i = 0; i < Path.length; i++) { for (int j = 0; j < arr.length; j++) { if (arr[j].equals(":") && i == 0 & Path[i].length() == 2) { // && // File.pathSeparator.equals(":") // skip check b/c we've got something like "C:\" in the path } else { if (Path[i].contains(arr[j])) return false; } } } return true; } // ************************************************************************** // ** getContentType // ************************************************************************** /** * Returns the mime type associated with the file extension found in a given * file name. This method only covers the most common/popular mime types. * The returned mime type is NOT authoritative. * * @param file * File name (e.g. hello.txt) * @return Content type (e.g. text/plain) */ public static String getContentType(String file) { // Get file extension FileExtension ext = null; if (file != null) { file = file.trim(); int x = file.lastIndexOf("."); if (x != -1) ext = new FileExtension(file.substring(x + 1)); } if (ext == null) return "application/octet-stream"; // TEXT if (ext.equals("css")) return "text/css"; if (ext.equals("dtd")) return "text/plain"; if (ext.equals("htm,html")) return "text/html"; if (ext.equals("java")) return "text/plain"; if (ext.equals("js")) return "text/javascript"; if (ext.equals("txt")) return "text/plain"; if (ext.equals("csv")) return "text/csv"; // JSON if (ext.equals("json")) return "application/json"; // IMAGE if (ext.equals("bmp")) return "image/bmp"; if (ext.equals("gif")) return "image/gif"; if (ext.equals("jp2,j2c,j2k,jpx")) return "image/jp2"; if (ext.equals("jpg,jpe,jpeg,jfif,pjpeg,pjp")) return "image/jpeg"; if (ext.equals("png")) return "image/png"; if (ext.equals("psd")) return "image/x-photoshop"; if (ext.equals("rgb")) return "image/x-rgb"; if (ext.equals("tif,tiff")) return "image/tiff"; if (ext.equals("xbm")) return "image/x-xbitmap"; if (ext.equals("xpm")) return "image/x-xpixmap"; if (ext.equals("ico")) return "image/vnd.microsoft.icon"; // MICROSOFT OFFICE APPLICATIONS if (ext.equals("doc,dot")) return "application/msword"; if (ext.equals("xls,xlw,xla,xlc,xlm,xlt,xll")) return "application/vnd.ms-excel"; if (ext.equals("ppt,pps,pot")) return "application/vnd.ms-powerpoint"; if (ext.equals("mdb")) return "application/x-msaccess"; if (ext.equals("mpp")) return "application/vnd.ms-project"; if (ext.equals("pub")) return "application/x-mspublisher"; if (ext.equals("wmz")) return "application/x-ms-wmz"; if (ext.equals("wmd")) return "application/x-ms-wmd"; if (ext.equals("one,onetoc2,onetmp,onepkg")) return "application/msonenote"; if (ext.equals("docx")) return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; if (ext.equals("dotx")) return "application/vnd.openxmlformats-officedocument.wordprocessingml.template"; if (ext.equals("xlsx")) return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; if (ext.equals("xltx")) return "application/vnd.openxmlformats-officedocument.spreadsheetml.template"; if (ext.equals("pptx")) return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; if (ext.equals("ppsx")) return "application/vnd.openxmlformats-officedocument.presentationml.slideshow"; if (ext.equals("potx")) return "application/vnd.openxmlformats-officedocument.presentationml.template"; if (ext.equals("sldx")) return "application/vnd.openxmlformats-officedocument.presentationml.slide"; // OTHER APPLICATIONS if (ext.equals("ai,eps,ps")) return "application/postscript"; if (ext.equals("gz")) return "application/x-gzip"; if (ext.equals("pdf")) return "application/pdf"; if (ext.equals("xml")) return "application/xml"; // return "text/xml"; if (ext.equals("z")) return "application/x-compress"; if (ext.equals("zip")) return "application/zip"; // AUDIO if (ext.equals("mid,midi")) return "audio/x-midi"; if (ext.equals("mp1,mp2,mp3,mpa,mpega")) return "audio/x-mpeg"; if (ext.equals("ra,ram")) return "audio/x-pn-realaudio"; if (ext.equals("wav")) return "audio/x-wav"; if (ext.equals("wma")) return "audio/x-ms-wma"; if (ext.equals("wax")) return "audio/x-ms-wax"; if (ext.equals("wmv")) return "audio/x-ms-wmv"; // VIDEO if (ext.equals("asf,asx")) return "video/x-ms-asf"; if (ext.equals("avi")) return "video/msvideo"; if (ext.equals("mov")) return "video/quicktime"; if (ext.equals("mpe,mpeg,mpg")) return "video/mpeg"; if (ext.equals("mpv2")) return "video/mpeg2"; if (ext.equals("qt,mov,moov")) return "video/quicktime"; if (ext.equals("wvx")) return "video/x-ms-wvx"; if (ext.equals("wm")) return "video/x-ms-wm"; if (ext.equals("wmx")) return "video/x-ms-wmx"; return "application/octet-stream"; } private static class FileExtension { private String ext; public FileExtension(String ext) { this.ext = ext.toLowerCase(); } /** * @param obj * Comma Separated List Of File Extensions */ @Override public boolean equals(Object obj) { if (obj instanceof String) { String[] arr = ((String) obj).split(","); for (int i = 0; i < arr.length; i++) { String str = arr[i].trim().toLowerCase(); if (str.equals(ext)) return true; } } return false; } @Override public int hashCode() { return ext.hashCode(); } } // ************************************************************************** // ** getContentType // ************************************************************************** /** * Returns the mime type associated with the file extension. This method * only covers the most common/popular mime types. The returned mime type is * NOT authoritative. */ public String getContentType() { return getContentType(this.getName()); } // ************************************************************************** // ** setLastModifiedTime // ************************************************************************** /** * Used to update the timestamp of when the file was last modified. */ public void setLastModifiedTime(java.util.Date date) { setDate(date); } // ************************************************************************** // ** getLastModifiedTime // ************************************************************************** /** * Returns a timestamp of when the file was last modified. This is identical * to the getDate() method. */ public java.util.Date getLastModifiedTime() { return getDate(); } // ************************************************************************** // ** getCreationTime // ************************************************************************** /** * Returns a timestamp of when the file was first created. Returns a null if * the timestamp is not available. */ public java.util.Date getCreationTime() { try { return getFileAttributes().getCreationTime(); } catch (Exception e) { return null; } } // ************************************************************************** // ** getLastAccessTime // ************************************************************************** /** * Returns a timestamp of when the file was last accessed. Returns a null if * the timestamp is not available. */ public java.util.Date getLastAccessTime() { try { return getFileAttributes().getLastAccessTime(); } catch (Exception e) { return null; } } // ************************************************************************** // ** getFlags // ************************************************************************** /** * Returns keywords representing file attributes (e.g. "READONLY", "HIDDEN", * etc). */ public java.util.HashSet getFlags() { try { return getFileAttributes().getFlags(); } catch (Exception e) { return new java.util.HashSet(); } } // ************************************************************************** // ** getFileAttributes // ************************************************************************** /** * Returns file attributes such as when the file was first created and when * it was last accessed. File attributes are cached for up to one second. * This provides users the ability to retrieve multiple attributes at once. * Without caching, we would have to ping the file system every time we call * getLastAccessTime(), getLastAccessTime(), getLastWriteTime(), etc. The * cached attributes are automatically updated when the file is updated or * deleted by this class. */ private FileAttributes getFileAttributes() throws java.io.FileNotFoundException { if (attr == null) lastAttrUpdate = 0; if (attr == null || (new java.util.Date().getTime() - lastAttrUpdate) > 1000) { try { // Get file attributes String pathToFile = toString(); attr = new FileAttributes(pathToFile); if (attr.isDirectory()) throw new java.io.FileNotFoundException(pathToFile); // Set lastUpdate (used to cache file attributes) lastAttrUpdate = new java.util.Date().getTime(); } catch (java.io.FileNotFoundException e) { attr = null; throw e; } catch (Exception e) { // e.printStackTrace(); attr = null; } } return attr; } // ************************************************************************** // ** loadDLL // ************************************************************************** /** * Used to load the javaxt-core.dll. Returns a boolean to indicate load * status. Note that the dll is only loaded once per JVM so it should be * safe to call this method multiple times. */ protected static synchronized boolean loadDLL() { // Try to load the dll as needed. Update the if (isWindows) { if (dllLoaded == null) { // haven't tried to load the dll yet... String jvmPlatform = System.getProperty("os.arch"); String dllName = null; if (jvmPlatform.equalsIgnoreCase("x86")) { dllName = "javaxt-core.dll"; } else if (jvmPlatform.equalsIgnoreCase("amd64")) { dllName = "javaxt-core64.dll"; } else { dllLoaded = false; return dllLoaded; } // Find dll entry in the zip/jar file Jar jar = new Jar(Jar.class); Jar.Entry entry = jar.getEntry(null, dllName); long checksum = entry.checksum(); // Construct list of possible file locations for the dll java.util.ArrayList files = new java.util.ArrayList(); files.add(new java.io.File(jar.getFile().getParentFile(), dllName)); javaxt.io.Directory dir = new javaxt.io.Directory(System.getProperty("user.home")); for (String appDir : new String[] { "AppData\\Local", "Application Data" }) { javaxt.io.Directory d = new javaxt.io.Directory(dir + appDir); java.io.File f = d.toFile(); // flip to file to prevent // infinite recursion if (f.exists() && f.canWrite()) { dir = d; break; } } files.add(new java.io.File(dir + "JavaXT\\" + dllName)); // Try to load dll for (java.io.File dll : files) { if (dll.exists()) { // Check whether the dll equals the jar entry. Extract // as needed. byte[] b = new byte[(int) dll.length()]; java.io.DataInputStream is = null; try { is = new java.io.DataInputStream(new FileInputStream(dll)); is.readFully(b, 0, b.length); is.close(); java.util.zip.CRC32 crc = new java.util.zip.CRC32(); crc.update(b); if (checksum != crc.getValue()) { dll.delete(); entry.extractFile(dll); } } catch (Exception e) { try { is.close(); } catch (Exception ex) { } } } else { // File does not exist so extract the dll entry.extractFile(dll); } // Load the dll if (dll.exists()) { try { System.load(dll.toString()); dllLoaded = true; break; } catch (Exception e) { e.printStackTrace(); } } } // Don't update the static variable to give users a chance to // fix // the load error (e.g. manually extract the dll and copy it // into // one of the directories). // dllLoaded = false; } return dllLoaded; } else {// not windows... return false; } } /** Used to determine whether the JVM is running on Mac OS X. */ private static final boolean isOSX = System.getProperty("os.name").toLowerCase().contains("os x"); private static final boolean isSolaris = System.getProperty("os.name").toLowerCase().contains("sunos"); /** * Used to track load status. Null = no load attempted, True = successfully * loaded the dll, False = failed to load dll (don't try again). Do not try * to modify the value directly. Use the loadDLL() method instead. */ private static Boolean dllLoaded; /** JNI entry point to retrieve file attributes. */ private static native long[] GetFileAttributesEx(String lpPathName) throws Exception; /** JNI entry point to retrieve link target. */ private static native String GetTarget(String lpPathName) throws Exception; /** JNI entry point to retrieve a list of shared drives on a server. */ protected static native String GetSharedDrives(String serverName) throws Exception; /** * JNI entry point to retrieve a list of network drives mounted to the host. */ protected static native String GetNetworkDrives() throws Exception; /** JNI entry point to retrieve a list of files and directories. */ protected static native String GetFiles(String lpPathName) throws Exception; // ****************************************************************************** // ** FileAttributes Class // ****************************************************************************** /** * Used to encapsulate extended file attributes. On unix and linux machines, * this class is used to parse the output from ls. On windows, this class * uses a JNI to return WIN32_FILE_ATTRIBUTE_DATA: * *
	    typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
	      DWORD dwFileAttributes;
	      FILETIME ftCreationTime;
	      FILETIME ftLastAccessTime;
	      FILETIME ftLastWriteTime;
	      DWORD nFileSizeHigh;
	      DWORD nFileSizeLow;
	    } WIN32_FILE_ATTRIBUTE_DATA;
	 * 
* ******************************************************************************/ public static class FileAttributes { private java.util.Date ftCreationTime; private java.util.Date ftLastAccessTime; private java.util.Date ftLastWriteTime; private long size; private java.util.HashSet flags = new java.util.HashSet(); private java.io.File link; public FileAttributes(String path) throws java.io.FileNotFoundException, Exception { if (isWindows) { if (loadDLL()) { // Get attributes long[] attributes = null; try { attributes = GetFileAttributesEx(path); } catch (Exception e) { if (!new java.io.File(path).exists()) { throw new java.io.FileNotFoundException(path); } else throw e; } // Parse dates java.text.SimpleDateFormat ftFormatter = new java.text.SimpleDateFormat("yyyyMMddHHmmssSSS"); ftCreationTime = ftFormatter.parse(attributes[1] + ""); ftLastAccessTime = ftFormatter.parse(attributes[2] + ""); ftLastWriteTime = ftFormatter.parse(attributes[3] + ""); // Compute file size using the nFileSizeHigh and // nFileSizeLow attributes // Note that nFileSizeHigh will be zero unless the file size // is greater // than MAXDWORD (4.2 Gig) long MAXDWORD = 4294967296L; long nFileSizeHigh = attributes[4]; long nFileSizeLow = attributes[5]; size = (nFileSizeHigh * MAXDWORD) + nFileSizeLow; // Parse misc file attributes long dwFileAttributes = attributes[0]; if (bitand(dwFileAttributes, FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) flags.add("READONLY"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN) flags.add("HIDDEN"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM) flags.add("SYSTEM"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) flags.add("DIRECTORY"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE) flags.add("ARCHIVE"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_DEVICE) == FILE_ATTRIBUTE_DEVICE) flags.add("DEVICE"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_NORMAL) == FILE_ATTRIBUTE_NORMAL) flags.add("NORMAL"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_TEMPORARY) == FILE_ATTRIBUTE_TEMPORARY) flags.add("TEMPORARY"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_SPARSE_FILE) == FILE_ATTRIBUTE_SPARSE_FILE) flags.add("SPARSE_FILE"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT) flags.add("REPARSE_POINT"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_COMPRESSED) == FILE_ATTRIBUTE_COMPRESSED) flags.add("COMPRESSED"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_OFFLINE) == FILE_ATTRIBUTE_OFFLINE) flags.add("OFFLINE"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) == FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) flags.add("NOT_CONTENT_INDEXED"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_ENCRYPTED) == FILE_ATTRIBUTE_ENCRYPTED) flags.add("ENCRYPTED"); if (bitand(dwFileAttributes, FILE_ATTRIBUTE_VIRTUAL) == FILE_ATTRIBUTE_VIRTUAL) flags.add("VIRTUAL"); // Parse symlink if (flags.contains("REPARSE_POINT")) { link = new java.io.File(GetTarget(path)); } } else { // Failed to load the javaxt-core.dll. Fall back to the // java.io.File object. java.io.File f = new java.io.File(path); if (!f.exists()) throw new java.io.FileNotFoundException(path); size = f.length(); ftLastWriteTime = new java.util.Date(f.lastModified()); if (!f.canWrite()) flags.add("READONLY"); if (f.isHidden()) flags.add("HIDDEN"); if (f.isDirectory()) flags.add("DIRECTORY"); } } else {// UNIX or LINIX Operating System java.io.File f = new java.io.File(path); if (!f.exists()) throw new java.io.FileNotFoundException(path); // Execute ls command to get last access time and creation time if (isOSX) { String[] params = new String[] { "ls", "-lauT", path }; javaxt.io.Shell cmd = new javaxt.io.Shell(params); cmd.run(); java.util.Iterator it = cmd.getOutput().iterator(); ftLastAccessTime = parseOSXDate(it); params = new String[] { "ls", "-laUT", path }; cmd = new javaxt.io.Shell(params); cmd.run(); it = cmd.getOutput().iterator(); ftCreationTime = parseOSXDate(it); } else if (isSolaris) { String[] params = new String[] { "ls", "-lauE", path }; javaxt.io.Shell cmd = new javaxt.io.Shell(params); cmd.run(); java.util.Iterator it = cmd.getOutput().iterator(); ftLastAccessTime = parseFullDate(it); } else {// Linux (e.g. Ubuntu) String[] params = new String[] { "ls", "-lau", "--full-time", path }; javaxt.io.Shell cmd = new javaxt.io.Shell(params); cmd.run(); java.util.Iterator it = cmd.getOutput().iterator(); ftLastAccessTime = parseFullDate(it); params = new String[] { "ls", "-laU", "--full-time", path }; cmd = new javaxt.io.Shell(params); cmd.run(); it = cmd.getOutput().iterator(); ftCreationTime = parseFullDate(it); } // Set other attributes including last modified date size = f.length(); ftLastWriteTime = new java.util.Date(f.lastModified()); if (!f.canWrite()) flags.add("READONLY"); if (f.isHidden()) flags.add("HIDDEN"); if (f.isDirectory()) flags.add("DIRECTORY"); try { if (!f.getCanonicalFile().equals(f.getAbsoluteFile())) { flags.add("REPARSE_POINT"); link = f.getCanonicalFile(); } } catch (Exception e) { } } // Check whether the file is a Windows shortcut (.lnk file) and // parse as needed if (!isDirectory() && link == null) { if (path.toLowerCase().endsWith(".lnk")) { try { link = new LnkParser(path).getFile(); } catch (Exception e) { } } } } /** * Used to extract a date from a ls output using the "--full-time" * option. */ private java.util.Date parseFullDate(java.util.Iterator it) { while (it.hasNext()) { String line = it.next(); if (line != null) { while (line.contains(" ")) line = line.replace(" ", " "); String[] arr = line.split(" "); if (arr.length > 7) { try { if (arr[6].length() > 8) arr[6] = arr[6].substring(0, 8); String date = arr[5] + " " + arr[6] + " " + arr[7]; return new javaxt.utils.Date(date, "yyyy-MM-dd HH:mm:ss z").getDate(); } catch (Exception e) { } } } } return null; } /** * Used to extract a date from a ls output using the "T" option on OSX. */ private java.util.Date parseOSXDate(java.util.Iterator it) { while (it.hasNext()) { String line = it.next(); if (line != null) { while (line.contains(" ")) line = line.replace(" ", " "); String[] arr = line.split(" "); if (arr.length > 10) { try { String date = arr[5] + " " + arr[6] + " " + arr[7] + " " + arr[8]; return new javaxt.utils.Date(date, "MMM dd hh:mm:ss yyyy").getDate(); } catch (Exception e) { } } } } return null; } public long getSize() { return size; } public java.util.Date getCreationTime() { return ftCreationTime; } public java.util.Date getLastAccessTime() { return ftLastAccessTime; } public java.util.Date getLastWriteTime() { return ftLastWriteTime; } public boolean isDirectory() { return flags.contains("DIRECTORY"); } public boolean isHidden() { return flags.contains("HIDDEN"); } public boolean isReadOnly() { return flags.contains("READONLY"); } public java.util.HashSet getFlags() { return flags; } public java.io.File getLink() { return link; } /** * A file that is read-only. Applications can read the file, but cannot * write to it or delete it. This attribute is not honored on * directories. For more information, see You cannot view or change the * Read-only or the System attributes of folders in Windows Server 2003, * in Windows XP, in Windows Vista or in Windows 7. */ private static final int FILE_ATTRIBUTE_READONLY = 1; /** * The file or directory is hidden. It is not included in an ordinary * directory listing. */ private static final int FILE_ATTRIBUTE_HIDDEN = 2; /** * A file or directory that the operating system uses a part of, or uses * exclusively. */ private static final int FILE_ATTRIBUTE_SYSTEM = 4; /** The handle that identifies a directory. */ private static final int FILE_ATTRIBUTE_DIRECTORY = 16; /** * A file or directory that is an archive file or directory. * Applications typically use this attribute to mark files for backup or * removal. */ private static final int FILE_ATTRIBUTE_ARCHIVE = 32; /** This value is reserved for system use. */ private static final int FILE_ATTRIBUTE_DEVICE = 64; /** * A file that does not have other attributes set. This attribute is * valid only when used alone. */ private static final int FILE_ATTRIBUTE_NORMAL = 128; /** * A file that is being used for temporary storage. File systems avoid * writing data back to mass storage if sufficient cache memory is * available, because typically, an application deletes a temporary file * after the handle is closed. In that scenario, the system can entirely * avoid writing the data. Otherwise, the data is written after the * handle is closed. */ private static final int FILE_ATTRIBUTE_TEMPORARY = 256; /** A file that is a sparse file. */ private static final int FILE_ATTRIBUTE_SPARSE_FILE = 512; /** * A file or directory that has an associated reparse point, or a file * that is a symbolic link. */ private static final int FILE_ATTRIBUTE_REPARSE_POINT = 1024; /** * A file or directory that is compressed. For a file, all of the data * in the file is compressed. For a directory, compression is the * default for newly created files and subdirectories. */ private static final int FILE_ATTRIBUTE_COMPRESSED = 2048; /** * The data of a file is not available immediately. This attribute * indicates that the file data is physically moved to offline storage. * This attribute is used by Remote Storage, which is the hierarchical * storage management software. Applications should not arbitrarily * change this attribute. */ private static final int FILE_ATTRIBUTE_OFFLINE = 4096; /** * The file or directory is not to be indexed by the content indexing * service. */ private static final int FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192; /** * A file or directory that is encrypted. For a file, all data streams * in the file are encrypted. For a directory, encryption is the default * for newly created files and subdirectories. */ private static final int FILE_ATTRIBUTE_ENCRYPTED = 16384; private static final int FILE_ATTRIBUTE_VIRTUAL = 65536; // This value // is reserved // for system // use. private long bitand(long Number1, long Number2) { try { return Number1 & Number2; } catch (Exception e) { return -1; } } }// End FileAttributes Class // ****************************************************************************** // ** LnkParser Class // ****************************************************************************** /** * Class used to parse a windows lnk files (aka shortcuts). Credit: * http://stackoverflow.com/a/672775/ * ******************************************************************************/ public static class LnkParser { private boolean isDirectory; private boolean isLocal; private String real_file; public LnkParser(String lnk) { this(new java.io.File(lnk)); } // ************************************************************************** // ** Constructor // ************************************************************************** /** * Instantiates the class by parsing the Windows shortcut (lnk) file. * * @param lnk * File representing the full path to the shortcut file. */ public LnkParser(java.io.File lnk) { byte[] link = getBytes(lnk, 1024).toByteArray(); // get the flags byte byte flags = link[0x14]; // get the file attributes byte final int file_atts_offset = 0x18; byte file_atts = link[file_atts_offset]; byte is_dir_mask = (byte) 0x10; if ((file_atts & is_dir_mask) > 0) { isDirectory = true; } else { isDirectory = false; } // if the shell settings are present, skip them final int shell_offset = 0x4c; final byte has_shell_mask = (byte) 0x01; int shell_len = 0; if ((flags & has_shell_mask) > 0) { // the plus 2 accounts for the length marker itself shell_len = bytes2short(link, shell_offset) + 2; } // get to the file settings int file_start = 0x4c + shell_len; final int file_location_info_flag_offset_offset = 0x08; int file_location_info_flag = link[file_start + file_location_info_flag_offset_offset]; isLocal = (file_location_info_flag & 2) == 0; // get the local volume and local system values // final int localVolumeTable_offset_offset = 0x0C; final int basename_offset_offset = 0x10; final int networkVolumeTable_offset_offset = 0x14; final int finalname_offset_offset = 0x18; int finalname_offset = link[file_start + finalname_offset_offset] + file_start; String finalname = getNullDelimitedString(link, finalname_offset); if (isLocal) { int basename_offset = link[file_start + basename_offset_offset] + file_start; String basename = getNullDelimitedString(link, basename_offset); real_file = basename + finalname; } else { int networkVolumeTable_offset = link[file_start + networkVolumeTable_offset_offset] + file_start; int shareName_offset_offset = 0x08; int shareName_offset = link[networkVolumeTable_offset + shareName_offset_offset] + networkVolumeTable_offset; String shareName = getNullDelimitedString(link, shareName_offset); real_file = shareName + "\\" + finalname; } } private static String getNullDelimitedString(byte[] bytes, int off) { int len = 0; // count bytes until the null character (0) while (true) { if (bytes[off + len] == 0) { break; } len++; } return new String(bytes, off, len); } /* * convert two bytes into a short note, this is little endian because * it's for an Intel only OS. */ private static int bytes2short(byte[] bytes, int off) { return ((bytes[off + 1] & 0xff) << 8) | (bytes[off] & 0xff); } public java.io.File getFile() { return new java.io.File(real_file); } }// End LnkParser Inner Class }// End File Class




© 2015 - 2025 Weber Informatics LLC | Privacy Policy