📄 fileutils.java
字号:
if (trans < extent) { result = false; } result = true; } catch (IOException e) { // Add more info to the exception. Preserve old stacktrace. // We get 'Invalid argument' on some file copies. See // http://intellij.net/forums/thread.jsp?forum=13&thread=63027&message=853123 // for related issue. String message = "Copying " + src.getAbsolutePath() + " to " + dest.getAbsolutePath() + " with extent " + extent + " got IOE: " + e.getMessage(); if (e.getMessage().equals("Invalid argument")) { LOGGER.severe("Failed copy, trying workaround: " + message); workaroundCopyFile(src, dest); } else { LOGGER.log(Level.SEVERE,message,e); // rethrow throw e; } } finally { // finish up if (fcin != null) { fcin.close(); } if (fcout != null) { fcout.close(); } if (fis != null) { fis.close(); } if (fos != null) { fos.close(); } } return result; } protected static void workaroundCopyFile(final File src, final File dest) throws IOException { FileInputStream from = null; FileOutputStream to = null; try { from = new FileInputStream(src); to = new FileOutputStream(dest); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = from.read(buffer)) != -1) { to.write(buffer, 0, bytesRead); } } finally { if (from != null) { try { from.close(); } catch (IOException e) { e.printStackTrace(); } } if (to != null) { try { to.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** Deletes all files and subdirectories under dir. * @param dir * @return true if all deletions were successful. If a deletion fails, the * method stops attempting to delete and returns false. */ public static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i=0; i<children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // The directory is now empty so delete it return dir.delete(); } /** * Utility method to read an entire file as a String. * * @param file * @return File as String. * @throws IOException */ public static String readFileAsString(File file) throws IOException { StringBuffer sb = new StringBuffer((int) file.length()); String line; BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(file))); try { line = br.readLine(); while (line != null) { sb.append(line); sb.append("\n"); line = br.readLine(); } } finally { br.close(); } return sb.toString(); } /** * Get a list of all files in directory that have passed prefix. * * @param dir Dir to look in. * @param prefix Basename of files to look for. Compare is case insensitive. * * @return List of files in dir that start w/ passed basename. */ public static File [] getFilesWithPrefix(File dir, final String prefix) { FileFilter prefixFilter = new FileFilter() { public boolean accept(File pathname) { return pathname.getName().toLowerCase(). startsWith(prefix.toLowerCase()); } }; return dir.listFiles(prefixFilter); } /** Get a @link java.io.FileFilter that filters files based on a regular * expression. * * @param regexp the regular expression the files must match. * @return the newly created filter. */ public static FileFilter getRegexpFileFilter(String regexp) { // Inner class defining the RegexpFileFilter class RegexpFileFilter implements FileFilter { Pattern pattern; protected RegexpFileFilter(String re) { pattern = Pattern.compile(re); } public boolean accept(File pathname) { return pattern.matcher(pathname.getName()).matches(); } } return new RegexpFileFilter(regexp); } /** * Use for case where files are being added to src. Will break off copy * when tgt is same as src. * @param src Source directory to copy from. * @param tgt Target to copy to. * @param filter Filter to apply to files to copy. * @throws IOException */ public static void syncDirectories(final File src, final FilenameFilter filter, final File tgt) throws IOException { Set<String> srcFilenames = null; do { srcFilenames = new HashSet<String>(Arrays.asList(src.list(filter))); List<String> tgtFilenames = Arrays.asList(tgt.list(filter)); srcFilenames.removeAll(tgtFilenames); if (srcFilenames.size() > 0) { int count = FileUtils.copyFiles(src, srcFilenames, tgt); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Copied " + count); } } } while (srcFilenames != null && srcFilenames.size() > 0); } /** * Test file exists and is readable. * @param f File to test. * @exception IOException If file does not exist or is not unreadable. */ public static File isReadable(final File f) throws IOException { if (!f.exists()) { throw new FileNotFoundException(f.getAbsolutePath() + " does not exist."); } if (!f.canRead()) { throw new FileNotFoundException(f.getAbsolutePath() + " is not readable."); } return f; } /** * @param f File to test. * @return True if file is readable, has uncompressed extension, * and magic string at file start. * @exception IOException If file does not exist or is not readable. */ public static boolean isReadableWithExtensionAndMagic(final File f, final String uncompressedExtension, final String magic) throws IOException { boolean result = false; FileUtils.isReadable(f); if(f.getName().toLowerCase().endsWith(uncompressedExtension)) { FileInputStream fis = new FileInputStream(f); try { byte [] b = new byte[magic.length()]; int read = fis.read(b, 0, magic.length()); fis.close(); if (read == magic.length()) { StringBuffer beginStr = new StringBuffer(magic.length()); for (int i = 0; i < magic.length(); i++) { beginStr.append((char)b[i]); } if (beginStr.toString(). equalsIgnoreCase(magic)) { result = true; } } } finally { fis.close(); } } return result; } /** * Turn path into a File, relative to context (which may be ignored * if path is absolute). * * @param context File context if path is relative * @param path String path to make into a File * @return File created */ public static File maybeRelative(File context, String path) { File f = new File(path); if(f.isAbsolute()) { return f; } return new File(context, path); } /** * Delete the file now -- but in the event of failure, keep trying * in the future. * * VERY IMPORTANT: Do not use with any file whose name/path may be * reused, because the lagged delete could then wind up deleting the * newer file. Essentially, only to be used with uniquely-named temp * files. * * Necessary because some platforms (looking at you, * JVM-on-Windows) will have deletes fail because of things like * file-mapped buffers remaining, and there's no explicit way to * unmap a buffer. (See 6-year-old Sun-stumping Java bug * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 ) * We just have to wait and retry. * * (Why not just File.deleteOnExit? There could be an arbitrary, * unbounded number of files in such a situation, that are only * deletable a few seconds or minutes after our first attempt. * Waiting for JVM exist could mean disk exhaustion. It's also * unclear if the native FS class implementations of deleteOnExit * use RAM per pending file.) * * @param fileToDelete */ public static synchronized void deleteSoonerOrLater(File fileToDelete) { pendingDeletes.add(fileToDelete); // if things are getting out of hand, force gc/finalization if(pendingDeletes.size()>50) { LOGGER.warning(">50 pending Files to delete; forcing gc/finalization"); System.gc(); System.runFinalization(); } // try all pendingDeletes Iterator<File> iter = pendingDeletes.listIterator(); while(iter.hasNext()) { File pending = iter.next(); if(pending.delete()) { iter.remove(); } } // if things are still out of hand, complain loudly if(pendingDeletes.size()>50) { LOGGER.severe(">50 pending Files to delete even after gc/finalization"); } } static LinkedList<File> pendingDeletes = new LinkedList<File>(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -