commons-IO 包解析学习---FileUtils篇(1)
2013-03-25 07:53
323 查看
由于Android项目忙完,苦于学习方向迷失,决定开一个进度,学习解析commons-IO包,提高JAVA水平,学习JAVA IO部分。废话不多说,进入正题。1.
srcDir, File destDir,
FileFilter filter, boolean preserveFileDate) throws IOException
{
if (srcDir
== null) {
throw new NullPointerException("Source
must not be null");
[align=left] }[/align]
if (destDir
== null) {
throw new NullPointerException("Destination
must not be null");
[align=left] }[/align]
if (srcDir.exists()
== false) {
throw new FileNotFoundException("Source
'" + srcDir + "' does not exist");
[align=left] }[/align]
if (srcDir.isDirectory()
== false) {
throw new IOException("Source
'" + srcDir + "' exists but is not a directory");
[align=left] }[/align]
if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath()))
{
throw new IOException("Source
'" + srcDir + "' and destination '" +
destDir + "' are the same");
[align=left] }[/align]// Cater for destination being directory
within the source directory (see IO-141)
[align=left] List<String> exclusionList = null;[/align]
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath()))
{
File[] srcFiles = filter == null ?
srcDir.listFiles() : srcDir.listFiles(filter);
if (srcFiles
!= null && srcFiles.length >
0) {
[align=left] exclusionList = new ArrayList<String>(srcFiles.length );[/align]
for (File
srcFile : srcFiles) {
File copiedFile = new File(destDir,
srcFile.getName());
[align=left] exclusionList.add(copiedFile.getCanonicalPath());[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);[/align]
[align=left] }[/align]这个函数加入了一个filter对复制操作的file加以过滤注意:这里有一个假如destDir是srcDir的子目录的附加操作// Cater for destination being directory
within the source directory (see IO-141)
[align=left] List<String> exclusionList = null;[/align]
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath()))
{
File[] srcFiles = filter == null ?
srcDir.listFiles() : srcDir.listFiles(filter);
if (srcFiles
!= null && srcFiles.length >
0) {
[align=left] exclusionList = new ArrayList<String>(srcFiles.length );[/align]
for (File
srcFile : srcFiles) {
File copiedFile = new File(destDir,
srcFile.getName());
[align=left] exclusionList.add(copiedFile.getCanonicalPath());[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]exclusionList是要排除的文件路径String列表(因为本来就在desDir里面),要作为参数传入下一个docopy()方法中17.private static void doCopyDirectory(File srcDir ,
File destDir, FileFilter filter,
boolean preserveFileDate,
List<String> exclusionList) throws IOException
{
[align=left] // recurse[/align]
File[] srcFiles = filter == null ? srcDir.listFiles()
: srcDir.listFiles(filter);
if (srcFiles
== null) { //
null if abstract pathname does not denote a directory, or if an I/O error occurs
throw new IOException("Failed
to list contents of " + srcDir);
[align=left] }[/align]
if (destDir.exists())
{
if (destDir.isDirectory()
== false) {
throw new IOException("Destination
'" + destDir + "' exists but is not a directory");
[align=left] }[/align]
[align=left] } else {[/align]
if (!destDir.mkdirs()
&& !destDir.isDirectory()) {
throw new IOException("Destination
'" + destDir + "' directory cannot be created");
[align=left] }[/align]
[align=left] }[/align]
if (destDir.canWrite()
== false) {
throw new IOException("Destination
'" + destDir + "' cannot be written to");
[align=left] }[/align]
for (File
srcFile : srcFiles) {
File dstFile = new File(destDir,
srcFile.getName());
if (exclusionList
== null || !exclusionList.contains(srcFile.getCanonicalPath()))
{
if (srcFile.isDirectory())
{
doCopyDirectory(srcFile, dstFile, filter, preserveFileDate,
exclusionList);
[align=left] } else {[/align]
[align=left] doCopyFile(srcFile, dstFile, preserveFileDate);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]// Do this last, as the above has probably
affected directory metadata
if (preserveFileDate)
{
[align=left] destDir.setLastModified( srcDir.lastModified());[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]注意:[/align]
[align=left] 1.递归调用,反复打开子目录复制文件[/align]
[align=left] 2.排除列表的操作[/align]20.
public static void copyInputStreamToFile(InputStream
source, File destination) throws IOException
{
[align=left] try {[/align]
[align=left] FileOutputStream output = openOutputStream(destination);[/align]
[align=left] try {[/align]
[align=left] IOUtils. copy(source, output);[/align]
output.close(); // don't swallow
close Exception if copy completes normally
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(output);[/align]
[align=left] }[/align]
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(source);[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]使用 IOUtils. copy()函数复制source流到output流(目标文件输出流)[/align][align=left]21.[/align]public static void deleteDirectory(File
directory) throws IOException
{
if (!directory.exists())
{
[align=left] return;[/align]
[align=left] }[/align]if (!isSymlink(directory))
{
[align=left] cleanDirectory(directory);[/align]
[align=left] }[/align]if (!directory.delete())
{
[align=left] String message =[/align]
"Unable to delete directory
" + directory + ".";
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] }[/align]isSymlink(directory)貌似和windows没关系??暂时存疑[align=left]调用cleanDirectory清空目录,然后删除目录本身[/align][align=left]22.[/align]public static boolean deleteQuietly (File
file) {
if (file
== null) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] try {[/align]
if (file.isDirectory())
{
[align=left] cleanDirectory(file);[/align]
[align=left] }[/align]
} catch (Exception
ignored) {
[align=left] }[/align][align=left] try {[/align]
[align=left] return file.delete();[/align]
} catch (Exception
ignored) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]本身Doc的描述:[/align]Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.The difference between File.delete() and this method are:A directory to be deleted does not have to be empty. 亮点所在!!!!!!!!!
No exceptions are thrown when a file or directory cannot be deleted.[align=left]23.[/align]public static boolean directoryContains(final File
directory, final File child) throws IOException
{
[align=left] [/align]
[align=left] // Fail fast against NullPointerException[/align]
if (directory
== null) {
throw new IllegalArgumentException("Directory
must not be null");
[align=left] }[/align]
[align=left] [/align]
if (!directory.isDirectory())
{
throw new IllegalArgumentException("Not
a directory: " + directory);
[align=left] }[/align]
[align=left] [/align]
if (child
== null) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] [/align]
if (!directory.exists()
|| !child.exists()) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] [/align]
// Canonicalize paths (normalizes relative
paths)
[align=left] String canonicalParent = directory.getCanonicalPath();[/align]
[align=left] String canonicalChild = child.getCanonicalPath();[/align]
[align=left] [/align]
return FilenameUtils.directoryContains(canonicalParent,
canonicalChild);
[align=left] }[/align]使用了FilenameUtils.directoryContains(canonicalParent,
canonicalChild)这个方法判断是否目录包含目标文件(非限定父子包含,可以是祖先后代关系)[align=left]24.[/align]public static void cleanDirectory (File
directory) throws IOException
{
if (!directory.exists())
{
String message = directory + " does
not exist";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align]if (!directory.isDirectory())
{
String message = directory + " is
not a directory";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align][align=left] File[] files = directory.listFiles();[/align]
if (files
== null) { //
null if security restricted
throw new IOException("Failed
to list contents of " + directory);
[align=left] }[/align][align=left] IOException exception = null;[/align]
for (File
file : files) {
[align=left] try {[/align]
[align=left] forceDelete(file);[/align]
} catch (IOException
ioe) {
[align=left] exception = ioe;[/align]
[align=left] }[/align]
[align=left] }[/align]if (null !=
exception) {
[align=left] throw exception;[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]调用forceDelete(file);删除文件或者文件夹[/align]
[align=left]注意:[/align][align=left]IOException exception = null ;[/align]
for (File
file : files) {
[align=left] try {[/align]
[align=left] forceDelete(file);[/align]
} catch (IOException
ioe) {
[align=left] exception = ioe;[/align]
[align=left] }[/align]
[align=left] }[/align]if (null !=
exception) {
[align=left] throw exception;[/align]
[align=left] }[/align][align=left]这里是为了可以顺利抛出异常才这样写[/align][align=left]25.[/align]public static boolean waitFor(File
file, int seconds) {
int timeout
= 0;
int tick
= 0;
while (!file.exists())
{
if (tick++
>= 10) {
[align=left] tick = 0;[/align]
if (timeout++
> seconds) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] try {[/align]
[align=left] Thread. sleep(100);[/align]
} catch (InterruptedException
ignore) {
[align=left] // ignore exception[/align]
} catch (Exception
ex) {
[align=left] break;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] return true ;[/align]
[align=left] }[/align][align=left]等待一定时间,反复测试是否存在吗某一文件(可用于等待用户创建某一文件)[/align]
[align=left]注意:[/align]
[align=left] 1.采用线程sleep(100),使得1秒可以检查10次文件是否存在[/align]
[align=left] 2.这里过滤sleep操作引起的InterruptedException 异常,但是捕捉其他异常,发生则会break,这里个人觉得不太好,因为这样发生异常就会返回true[/align][align=left]34.[/align]public static void writeStringToFile(File
file, String data, Charset encoding, boolean append) throws IOException
{
[align=left] OutputStream out = null;[/align]
[align=left] try {[/align]
[align=left] out = openOutputStream(file, append);[/align]
[align=left] IOUtils. write(data, out, encoding);[/align]
out.close(); // don't swallow close
Exception if copy completes normally
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(out);[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]这里不明白的:[/align]
out.close(); // don't swallow close Exception
if copy completes normally这个什么意思?38.public static void write(File
file, CharSequence data, Charset encoding, boolean append) throws IOException
{
String str = data == null ? null :
data.toString();
writeStringToFile(file, str ,
encoding, append);
[align=left] }[/align]CharSequence 接口实现类都可以使用46.public static void writeLines (File
file, String encoding, Collection<?> lines, String lineEnding, boolean append)
throws IOException
{
[align=left] FileOutputStream out = null;[/align]
[align=left] try {[/align]
[align=left] out = openOutputStream(file, append);[/align]
final BufferedOutputStream
buffer = new BufferedOutputStream(out);
[align=left] IOUtils. writeLines(lines, lineEnding, buffer, encoding);[/align]
[align=left] buffer.flush();[/align]
out.close(); // don't swallow close
Exception if copy completes normally
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(out);[/align]
[align=left] }[/align]
[align=left] }[/align]这里使用了IOUtils. writeLines(lines,
lineEnding, buffer, encoding);写入行,并且值得注意的是,可以用lineEnding指定行分隔符49.public static void forceDelete (File
file) throws IOException {
if (file.isDirectory())
{
[align=left] deleteDirectory(file);[/align]
[align=left] } else {[/align]
boolean filePresent
= file.exists();
if (!file.delete())
{
[align=left] if (!filePresent){[/align]
throw new FileNotFoundException("File
does not exist: " + file);
[align=left] }[/align]
[align=left] String message =[/align]
"Unable to delete file:
" + file;
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]这里和刚才的deleteDirectory()有隐式递归调用,在目录和文件的区分处理上,假如是目录,就用deleteDirectory()继续打开,用以递归打开再调用forceDelete(),如此反复,可以做到删除所用文件[/align]52.private static void cleanDirectoryOnExit(File
directory) throws IOException
{
if (!directory.exists())
{
String message = directory + " does
not exist";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align]if (!directory.isDirectory())
{
String message = directory + " is
not a directory";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align][align=left] File[] files = directory.listFiles();[/align]
if (files
== null) { //
null if security restricted
throw new IOException("Failed
to list contents of " + directory);
[align=left] }[/align][align=left] IOException exception = null;[/align]
for (File
file : files) {
[align=left] try {[/align]
[align=left] forceDeleteOnExit(file);[/align]
} catch (IOException
ioe) {
[align=left] exception = ioe;[/align]
[align=left] }[/align]
[align=left] }[/align]if (null !=
exception) {
[align=left] throw exception;[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]在JVM退出时清空,目录,其中调用到了File.deleteOnExit()[/align][align=left]53.[/align]public static void forceMkdir (File
directory) throws IOException
{
if (directory.exists())
{
if (!directory.isDirectory())
{
[align=left] String message =[/align]
[align=left] "File "[/align]
[align=left] + directory[/align]
[align=left] + " exists and is "[/align]
+ "not a directory.
Unable to create directory.";
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] } else {[/align]
if (!directory.mkdirs())
{
// Double-check that some other
thread or process hasn't made
[align=left] // the directory in the background[/align]
[align=left] if (!directory.isDirectory())[/align]
[align=left] {[/align]
[align=left] String message =[/align]
"Unable to create directory
" + directory;
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]存疑:[/align][align=left]// Double-check that some other thread or process hasn't made[/align]
[align=left]// the directory in the background[/align]
[align=left]这是表达什么?[/align][align=left]54.[/align]public static long sizeOf(File
file) {if (!file.exists())
{
String message = file + " does not
exist";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align]if (file.isDirectory())
{
[align=left] return sizeOfDirectory(file);[/align]
[align=left] } else {[/align]
[align=left] return file.length();[/align]
[align=left] }[/align][align=left] }[/align][align=left]返回一个File对象的byte大小,目录会递归调用,但是不会处理受限制的子目录[/align]65.public static long checksumCRC32(File
file) throws IOException {
[align=left] CRC32 crc = new CRC32 ();[/align]
[align=left] checksum(file, crc);[/align]
[align=left] return crc.getValue();[/align]
[align=left] }[/align][align=left]存疑[/align]
[align=left]CRC32是啥?[/align]66.public static Checksum
checksum(File file, Checksum checksum) throws IOException
{
if (file.isDirectory())
{
throw new IllegalArgumentException("Checksums
can't be computed on directories");
[align=left] }[/align]
[align=left] InputStream in = null;[/align]
[align=left] try {[/align]
in = new CheckedInputStream(new FileInputStream(file),
checksum);
[align=left] IOUtils. copy(in, new NullOutputStream());[/align]
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(in);[/align]
[align=left] }[/align]
[align=left] return checksum;[/align]
[align=left] }[/align][align=left]存疑[/align]
[align=left]checksum是啥[/align]67.public static void moveDirectory (File
srcDir, File destDir) throws IOException
{
if (srcDir
== null) {
throw new NullPointerException("Source
must not be null");
[align=left] }[/align]
if (destDir
== null) {
throw new NullPointerException("Destination
must not be null");
[align=left] }[/align]
if (!srcDir.exists())
{
throw new FileNotFoundException("Source
'" + srcDir + "' does not exist");
[align=left] }[/align]
if (!srcDir.isDirectory())
{
throw new IOException("Source
'" + srcDir + "' is not a directory");
[align=left] }[/align]
if (destDir.exists())
{
throw new FileExistsException("Destination
'" + destDir + "' already exists");
[align=left] }[/align]
boolean rename
= srcDir.renameTo(destDir);
if (!rename)
{
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath()))
{
throw new IOException("Cannot
move directory: "+srcDir+ " to a subdirectory of
itself: "+destDir);
[align=left] }[/align]
[align=left] copyDirectory( srcDir, destDir );[/align]
[align=left] deleteDirectory( srcDir );[/align]
if (srcDir.exists())
{
throw new IOException("Failed
to delete original directory '" + srcDir +
"' after copy to '" +
destDir + "'" );
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]注意:[/align]
1.boolean rename
= srcDir.renameTo(destDir);使用这个renameTo的操作移动,假如未成功再进行第二种移动操作(先复制,再删除)
[align=left] 2.不能移动父目录到子目录[/align]
[align=left] 3.删除不成功要抛出异常[/align][align=left]72.[/align]public static boolean isSymlink(File
file) throws IOException {
if (file
== null) {
throw new NullPointerException("File
must not be null");
[align=left] }[/align]
if (FilenameUtils.isSystemWindows())
{
[align=left] return false;[/align]
[align=left] }[/align]
[align=left] File fileInCanonicalDir = null;[/align]
if (file.getParent()
== null) {
[align=left] fileInCanonicalDir = file;[/align]
[align=left] } else {[/align]
[align=left] File canonicalDir = file.getParentFile(). getCanonicalFile();[/align]
fileInCanonicalDir = new File(canonicalDir,
file.getName());
[align=left] }[/align]
[align=left] [/align]
if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile()))
{
[align=left] return false;[/align]
[align=left] } else {[/align]
[align=left] return true;[/align]
[align=left] }[/align]
[align=left] }[/align]存疑貌似和WINDOWS系统无关?不懂。。。
//----------------------------------------------------------------------- /** * Compares the contents of two files to determine if they are equal or not. * <p> * This method checks to see if the two files are different lengths * or if they point to the same file, before resorting to byte-by-byte * comparison of the contents. * <p> * Code origin: Avalon * * @param file1 the first file * @param file2 the second file * @return true if the content of the files are equal or they both don't * exist, false otherwise * @throws IOException in case of an I/O error */ public static boolean contentEquals(File file1, File file2) throws IOException { boolean file1Exists = file1.exists(); if (file1Exists != file2.exists()) { return false; } if (!file1Exists) { // two not existing files are equal return true; } if (file1.isDirectory() || file2.isDirectory()) { // don't want to compare directory contents throw new IOException("Can't compare directories, only files"); } if (file1.length() != file2.length()) { // lengths differ, cannot be equal return false; } if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) { // same file return true; } InputStream input1 = null; InputStream input2 = null; try { input1 = new FileInputStream(file1); input2 = new FileInputStream(file2); return IOUtils.contentEquals(input1, input2); } finally { IOUtils.closeQuietly(input1); IOUtils.closeQuietly(input2); } }这个函数用来比较两个file里面的文件是否相同。比较策略:1.判断是否有一个存在一个不存在(两个不存在也算相同)2.判断两个是不是至少一个是目录(不能比较目录内容)3.判断两个文件的长度是否相同,不同则返回false4.应用File.getCanonicalFile()这个函数返回文件路径判断是不是指向同一个文件5.最后才用inputstream导入两个文件,使用IOUtils.contentEquals(input1, input2)判断内容是否相等2.
/** * Compares the contents of two files to determine if they are equal or not. * <p> * This method checks to see if the two files point to the same file, * before resorting to line-by-line comparison of the contents. * <p> * * @param file1 the first file * @param file2 the second file * @param charsetName the character encoding to be used. * May be null, in which case the platform default is used * @return true if the content of the files are equal or neither exists, * false otherwise * @throws IOException in case of an I/O error * @since 2.2 * @see IOUtils#contentEqualsIgnoreEOL(Reader, Reader) */ public static boolean contentEqualsIgnoreEOL(File file1, File file2, String charsetName) throws IOException { boolean file1Exists = file1.exists(); if (file1Exists != file2.exists()) { return false; } if (!file1Exists) { // two not existing files are equal return true; } if (file1.isDirectory() || file2.isDirectory()) { // don't want to compare directory contents throw new IOException("Can't compare directories, only files"); } if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) { // same file return true; } Reader input1 = null; Reader input2 = null; try { if (charsetName == null) { input1 = new InputStreamReader(new FileInputStream(file1)); input2 = new InputStreamReader(new FileInputStream(file2)); } else { input1 = new InputStreamReader(new FileInputStream(file1), charsetName); input2 = new InputStreamReader(new FileInputStream(file2), charsetName); } return IOUtils.contentEqualsIgnoreEOL(input1, input2); } finally { IOUtils.closeQuietly(input1); IOUtils.closeQuietly(input2); } }本函数和上一条基本相同,区别在于:
Reader input1 = null; Reader input2 = null; try { if (charsetName == null) { input1 = new InputStreamReader(new FileInputStream(file1)); input2 = new InputStreamReader(new FileInputStream(file2)); } else { input1 = new InputStreamReader(new FileInputStream(file1), charsetName); input2 = new InputStreamReader(new FileInputStream(file2), charsetName); } return IOUtils.contentEqualsIgnoreEOL(input1, input2); } finally { IOUtils.closeQuietly(input1); IOUtils.closeQuietly(input2); }这里使用了charsetName,用以获取编码后的字符流*学习:InputStreamReader的创建(使用charsetName参数编码FileInputStream获取的字节)3.
public static File toFile(URL url) { if (url == null || !"file".equalsIgnoreCase(url.getProtocol())) { return null; } else { String filename = url.getFile().replace('/', File.separatorChar); filename = decodeUrl(filename); return new File(filename); } }一个用于把file协议的url转换为File类型的函数4.
static String decodeUrl(String url) { String decoded = url; if (url != null && url.indexOf('%') >= 0) { int n = url.length(); StringBuffer buffer = new StringBuffer(); ByteBuffer bytes = ByteBuffer.allocate(n); for (int i = 0; i < n;) { if (url.charAt(i) == '%') { try { do { byte octet = (byte) Integer.parseInt(url.substring(i + 1, i + 3), 16); bytes.put(octet); i += 3; } while (i < n && url.charAt(i) == '%'); continue; } catch (RuntimeException e) { // malformed percent-encoded octet, fall through and // append characters literally } finally { if (bytes.position() > 0) { bytes.flip(); buffer.append(UTF8.decode(bytes).toString()); bytes.clear(); } } } buffer.append(url.charAt(i++)); } decoded = buffer.toString(); } return decoded; }转换URL出现问题时的优化处理(存疑)5.
public static File[] toFiles(URL[] urls) { if (urls == null || urls.length == 0) { return EMPTY_FILE_ARRAY; } File[] files = new File[urls.length]; for (int i = 0; i < urls.length; i++) { URL url = urls[i]; if (url != null) { if (url.getProtocol().equals("file") == false) { throw new IllegalArgumentException( "URL could not be converted to a File: " + url); } files[i] = toFile(url); } } return files; }Converts each of an array of
URLto a
File.刚才函数toFile()的数组版本6.
public static URL[] toURLs(File[] files) throws IOException { URL[] urls = new URL[files.length]; for (int i = 0; i < urls.length; i++) { urls[i] = files[i].toURI().toURL(); } return urls; }Converts each of an array of
Fileto a
URL.7.
public static void copyFileToDirectory(File srcFile, File destDir) throws IOException { copyFileToDirectory(srcFile, destDir, true); }Copies a file to a directory preserving the file date.8.
public static void copyFileToDirectory(File srcFile, File destDir, boolean p 38150 reserveFileDate) throws IOException { if (destDir == null) { throw new NullPointerException("Destination must not be null"); } if (destDir.exists() && destDir.isDirectory() == false) { throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); } File destFile = new File(destDir, srcFile.getName()); copyFile(srcFile, destFile, preserveFileDate); }刚才函数7的完整版本:1.确保目标地址不是空的2.确保目标地址存在,并且不是文件3.对源文件和目标文件的保护在copyFile里做了,所以这里只做对目标目录的保护。9.
public static void copyFile(File srcFile, File destFile) throws IOException { copyFile(srcFile, destFile, true); }包装函数,重载默认保存date10.
public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { if (srcFile == null) { throw new NullPointerException("Source must not be null"); } if (destFile == null) { throw new NullPointerException("Destination must not be null"); } if (srcFile.exists() == false) { throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); } if (srcFile.isDirectory()) { throw new IOException("Source '" + srcFile + "' exists but is a directory"); } if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); } File parentFile = destFile.getParentFile(); if (parentFile != null) { if (!parentFile.mkdirs() && !parentFile.isDirectory()) { throw new IOException("Destination '" + parentFile + "' directory cannot be created"); } } if (destFile.exists() && destFile.canWrite() == false) { throw new IOException("Destination '" + destFile + "' exists but is read-only"); } doCopyFile(srcFile, destFile, preserveFileDate); }策略学习:目标文件和源文件的保护监测11.
public static long copyFile(File input, OutputStream output) throws IOException { final FileInputStream fis = new FileInputStream(input); try { return IOUtils.copyLarge(fis, output); } finally { fis.close(); } }从一个input文件中拷贝bytes进入output输出流,注意:IOUtils.copyLarge(fis, output)这个方法内部使用了buffer,所以不需要使用
BufferedInputStream
12.
private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {使用nio中的FileChannel进行复制(传输文件内容),调用IOUtils.closeQuietly()关闭filechannel和I/Ostream
if (destFile.exists() && destFile.isDirectory()) {
throw new IOException("Destination '" + destFile + "' exists but is a directory");
}FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel input = null;
FileChannel output = null;
try {
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
input = fis.getChannel();
output = fos.getChannel();
long size = input.size();
long pos = 0;
long count = 0;
while (pos < size) {
count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos;
pos += output.transferFrom(input, pos, count);
}
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(fos);
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(fis);
}if (srcFile.length() != destFile.length()) {
throw new IOException("Failed to copy full contents from '" +
srcFile + "' to '" + destFile + "'");
}
if (preserveFileDate) {
destFile.setLastModified(srcFile.lastModified());
}
}
最后用文件的length长度监测是否传输成功16.public static void copyDirectory (File
srcDir, File destDir,
FileFilter filter, boolean preserveFileDate) throws IOException
{
if (srcDir
== null) {
throw new NullPointerException("Source
must not be null");
[align=left] }[/align]
if (destDir
== null) {
throw new NullPointerException("Destination
must not be null");
[align=left] }[/align]
if (srcDir.exists()
== false) {
throw new FileNotFoundException("Source
'" + srcDir + "' does not exist");
[align=left] }[/align]
if (srcDir.isDirectory()
== false) {
throw new IOException("Source
'" + srcDir + "' exists but is not a directory");
[align=left] }[/align]
if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath()))
{
throw new IOException("Source
'" + srcDir + "' and destination '" +
destDir + "' are the same");
[align=left] }[/align]// Cater for destination being directory
within the source directory (see IO-141)
[align=left] List<String> exclusionList = null;[/align]
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath()))
{
File[] srcFiles = filter == null ?
srcDir.listFiles() : srcDir.listFiles(filter);
if (srcFiles
!= null && srcFiles.length >
0) {
[align=left] exclusionList = new ArrayList<String>(srcFiles.length );[/align]
for (File
srcFile : srcFiles) {
File copiedFile = new File(destDir,
srcFile.getName());
[align=left] exclusionList.add(copiedFile.getCanonicalPath());[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);[/align]
[align=left] }[/align]这个函数加入了一个filter对复制操作的file加以过滤注意:这里有一个假如destDir是srcDir的子目录的附加操作// Cater for destination being directory
within the source directory (see IO-141)
[align=left] List<String> exclusionList = null;[/align]
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath()))
{
File[] srcFiles = filter == null ?
srcDir.listFiles() : srcDir.listFiles(filter);
if (srcFiles
!= null && srcFiles.length >
0) {
[align=left] exclusionList = new ArrayList<String>(srcFiles.length );[/align]
for (File
srcFile : srcFiles) {
File copiedFile = new File(destDir,
srcFile.getName());
[align=left] exclusionList.add(copiedFile.getCanonicalPath());[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]exclusionList是要排除的文件路径String列表(因为本来就在desDir里面),要作为参数传入下一个docopy()方法中17.private static void doCopyDirectory(File srcDir ,
File destDir, FileFilter filter,
boolean preserveFileDate,
List<String> exclusionList) throws IOException
{
[align=left] // recurse[/align]
File[] srcFiles = filter == null ? srcDir.listFiles()
: srcDir.listFiles(filter);
if (srcFiles
== null) { //
null if abstract pathname does not denote a directory, or if an I/O error occurs
throw new IOException("Failed
to list contents of " + srcDir);
[align=left] }[/align]
if (destDir.exists())
{
if (destDir.isDirectory()
== false) {
throw new IOException("Destination
'" + destDir + "' exists but is not a directory");
[align=left] }[/align]
[align=left] } else {[/align]
if (!destDir.mkdirs()
&& !destDir.isDirectory()) {
throw new IOException("Destination
'" + destDir + "' directory cannot be created");
[align=left] }[/align]
[align=left] }[/align]
if (destDir.canWrite()
== false) {
throw new IOException("Destination
'" + destDir + "' cannot be written to");
[align=left] }[/align]
for (File
srcFile : srcFiles) {
File dstFile = new File(destDir,
srcFile.getName());
if (exclusionList
== null || !exclusionList.contains(srcFile.getCanonicalPath()))
{
if (srcFile.isDirectory())
{
doCopyDirectory(srcFile, dstFile, filter, preserveFileDate,
exclusionList);
[align=left] } else {[/align]
[align=left] doCopyFile(srcFile, dstFile, preserveFileDate);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]// Do this last, as the above has probably
affected directory metadata
if (preserveFileDate)
{
[align=left] destDir.setLastModified( srcDir.lastModified());[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]注意:[/align]
[align=left] 1.递归调用,反复打开子目录复制文件[/align]
[align=left] 2.排除列表的操作[/align]20.
public static void copyInputStreamToFile(InputStream
source, File destination) throws IOException
{
[align=left] try {[/align]
[align=left] FileOutputStream output = openOutputStream(destination);[/align]
[align=left] try {[/align]
[align=left] IOUtils. copy(source, output);[/align]
output.close(); // don't swallow
close Exception if copy completes normally
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(output);[/align]
[align=left] }[/align]
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(source);[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]使用 IOUtils. copy()函数复制source流到output流(目标文件输出流)[/align][align=left]21.[/align]public static void deleteDirectory(File
directory) throws IOException
{
if (!directory.exists())
{
[align=left] return;[/align]
[align=left] }[/align]if (!isSymlink(directory))
{
[align=left] cleanDirectory(directory);[/align]
[align=left] }[/align]if (!directory.delete())
{
[align=left] String message =[/align]
"Unable to delete directory
" + directory + ".";
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] }[/align]isSymlink(directory)貌似和windows没关系??暂时存疑[align=left]调用cleanDirectory清空目录,然后删除目录本身[/align][align=left]22.[/align]public static boolean deleteQuietly (File
file) {
if (file
== null) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] try {[/align]
if (file.isDirectory())
{
[align=left] cleanDirectory(file);[/align]
[align=left] }[/align]
} catch (Exception
ignored) {
[align=left] }[/align][align=left] try {[/align]
[align=left] return file.delete();[/align]
} catch (Exception
ignored) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]本身Doc的描述:[/align]Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.The difference between File.delete() and this method are:A directory to be deleted does not have to be empty. 亮点所在!!!!!!!!!
No exceptions are thrown when a file or directory cannot be deleted.[align=left]23.[/align]public static boolean directoryContains(final File
directory, final File child) throws IOException
{
[align=left] [/align]
[align=left] // Fail fast against NullPointerException[/align]
if (directory
== null) {
throw new IllegalArgumentException("Directory
must not be null");
[align=left] }[/align]
[align=left] [/align]
if (!directory.isDirectory())
{
throw new IllegalArgumentException("Not
a directory: " + directory);
[align=left] }[/align]
[align=left] [/align]
if (child
== null) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] [/align]
if (!directory.exists()
|| !child.exists()) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] [/align]
// Canonicalize paths (normalizes relative
paths)
[align=left] String canonicalParent = directory.getCanonicalPath();[/align]
[align=left] String canonicalChild = child.getCanonicalPath();[/align]
[align=left] [/align]
return FilenameUtils.directoryContains(canonicalParent,
canonicalChild);
[align=left] }[/align]使用了FilenameUtils.directoryContains(canonicalParent,
canonicalChild)这个方法判断是否目录包含目标文件(非限定父子包含,可以是祖先后代关系)[align=left]24.[/align]public static void cleanDirectory (File
directory) throws IOException
{
if (!directory.exists())
{
String message = directory + " does
not exist";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align]if (!directory.isDirectory())
{
String message = directory + " is
not a directory";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align][align=left] File[] files = directory.listFiles();[/align]
if (files
== null) { //
null if security restricted
throw new IOException("Failed
to list contents of " + directory);
[align=left] }[/align][align=left] IOException exception = null;[/align]
for (File
file : files) {
[align=left] try {[/align]
[align=left] forceDelete(file);[/align]
} catch (IOException
ioe) {
[align=left] exception = ioe;[/align]
[align=left] }[/align]
[align=left] }[/align]if (null !=
exception) {
[align=left] throw exception;[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]调用forceDelete(file);删除文件或者文件夹[/align]
[align=left]注意:[/align][align=left]IOException exception = null ;[/align]
for (File
file : files) {
[align=left] try {[/align]
[align=left] forceDelete(file);[/align]
} catch (IOException
ioe) {
[align=left] exception = ioe;[/align]
[align=left] }[/align]
[align=left] }[/align]if (null !=
exception) {
[align=left] throw exception;[/align]
[align=left] }[/align][align=left]这里是为了可以顺利抛出异常才这样写[/align][align=left]25.[/align]public static boolean waitFor(File
file, int seconds) {
int timeout
= 0;
int tick
= 0;
while (!file.exists())
{
if (tick++
>= 10) {
[align=left] tick = 0;[/align]
if (timeout++
> seconds) {
[align=left] return false ;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] try {[/align]
[align=left] Thread. sleep(100);[/align]
} catch (InterruptedException
ignore) {
[align=left] // ignore exception[/align]
} catch (Exception
ex) {
[align=left] break;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] return true ;[/align]
[align=left] }[/align][align=left]等待一定时间,反复测试是否存在吗某一文件(可用于等待用户创建某一文件)[/align]
[align=left]注意:[/align]
[align=left] 1.采用线程sleep(100),使得1秒可以检查10次文件是否存在[/align]
[align=left] 2.这里过滤sleep操作引起的InterruptedException 异常,但是捕捉其他异常,发生则会break,这里个人觉得不太好,因为这样发生异常就会返回true[/align][align=left]34.[/align]public static void writeStringToFile(File
file, String data, Charset encoding, boolean append) throws IOException
{
[align=left] OutputStream out = null;[/align]
[align=left] try {[/align]
[align=left] out = openOutputStream(file, append);[/align]
[align=left] IOUtils. write(data, out, encoding);[/align]
out.close(); // don't swallow close
Exception if copy completes normally
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(out);[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]这里不明白的:[/align]
out.close(); // don't swallow close Exception
if copy completes normally这个什么意思?38.public static void write(File
file, CharSequence data, Charset encoding, boolean append) throws IOException
{
String str = data == null ? null :
data.toString();
writeStringToFile(file, str ,
encoding, append);
[align=left] }[/align]CharSequence 接口实现类都可以使用46.public static void writeLines (File
file, String encoding, Collection<?> lines, String lineEnding, boolean append)
throws IOException
{
[align=left] FileOutputStream out = null;[/align]
[align=left] try {[/align]
[align=left] out = openOutputStream(file, append);[/align]
final BufferedOutputStream
buffer = new BufferedOutputStream(out);
[align=left] IOUtils. writeLines(lines, lineEnding, buffer, encoding);[/align]
[align=left] buffer.flush();[/align]
out.close(); // don't swallow close
Exception if copy completes normally
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(out);[/align]
[align=left] }[/align]
[align=left] }[/align]这里使用了IOUtils. writeLines(lines,
lineEnding, buffer, encoding);写入行,并且值得注意的是,可以用lineEnding指定行分隔符49.public static void forceDelete (File
file) throws IOException {
if (file.isDirectory())
{
[align=left] deleteDirectory(file);[/align]
[align=left] } else {[/align]
boolean filePresent
= file.exists();
if (!file.delete())
{
[align=left] if (!filePresent){[/align]
throw new FileNotFoundException("File
does not exist: " + file);
[align=left] }[/align]
[align=left] String message =[/align]
"Unable to delete file:
" + file;
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]这里和刚才的deleteDirectory()有隐式递归调用,在目录和文件的区分处理上,假如是目录,就用deleteDirectory()继续打开,用以递归打开再调用forceDelete(),如此反复,可以做到删除所用文件[/align]52.private static void cleanDirectoryOnExit(File
directory) throws IOException
{
if (!directory.exists())
{
String message = directory + " does
not exist";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align]if (!directory.isDirectory())
{
String message = directory + " is
not a directory";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align][align=left] File[] files = directory.listFiles();[/align]
if (files
== null) { //
null if security restricted
throw new IOException("Failed
to list contents of " + directory);
[align=left] }[/align][align=left] IOException exception = null;[/align]
for (File
file : files) {
[align=left] try {[/align]
[align=left] forceDeleteOnExit(file);[/align]
} catch (IOException
ioe) {
[align=left] exception = ioe;[/align]
[align=left] }[/align]
[align=left] }[/align]if (null !=
exception) {
[align=left] throw exception;[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]在JVM退出时清空,目录,其中调用到了File.deleteOnExit()[/align][align=left]53.[/align]public static void forceMkdir (File
directory) throws IOException
{
if (directory.exists())
{
if (!directory.isDirectory())
{
[align=left] String message =[/align]
[align=left] "File "[/align]
[align=left] + directory[/align]
[align=left] + " exists and is "[/align]
+ "not a directory.
Unable to create directory.";
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] } else {[/align]
if (!directory.mkdirs())
{
// Double-check that some other
thread or process hasn't made
[align=left] // the directory in the background[/align]
[align=left] if (!directory.isDirectory())[/align]
[align=left] {[/align]
[align=left] String message =[/align]
"Unable to create directory
" + directory;
[align=left] throw new IOException(message);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]存疑:[/align][align=left]// Double-check that some other thread or process hasn't made[/align]
[align=left]// the directory in the background[/align]
[align=left]这是表达什么?[/align][align=left]54.[/align]public static long sizeOf(File
file) {if (!file.exists())
{
String message = file + " does not
exist";
[align=left] throw new IllegalArgumentException(message);[/align]
[align=left] }[/align]if (file.isDirectory())
{
[align=left] return sizeOfDirectory(file);[/align]
[align=left] } else {[/align]
[align=left] return file.length();[/align]
[align=left] }[/align][align=left] }[/align][align=left]返回一个File对象的byte大小,目录会递归调用,但是不会处理受限制的子目录[/align]65.public static long checksumCRC32(File
file) throws IOException {
[align=left] CRC32 crc = new CRC32 ();[/align]
[align=left] checksum(file, crc);[/align]
[align=left] return crc.getValue();[/align]
[align=left] }[/align][align=left]存疑[/align]
[align=left]CRC32是啥?[/align]66.public static Checksum
checksum(File file, Checksum checksum) throws IOException
{
if (file.isDirectory())
{
throw new IllegalArgumentException("Checksums
can't be computed on directories");
[align=left] }[/align]
[align=left] InputStream in = null;[/align]
[align=left] try {[/align]
in = new CheckedInputStream(new FileInputStream(file),
checksum);
[align=left] IOUtils. copy(in, new NullOutputStream());[/align]
[align=left] } finally {[/align]
[align=left] IOUtils. closeQuietly(in);[/align]
[align=left] }[/align]
[align=left] return checksum;[/align]
[align=left] }[/align][align=left]存疑[/align]
[align=left]checksum是啥[/align]67.public static void moveDirectory (File
srcDir, File destDir) throws IOException
{
if (srcDir
== null) {
throw new NullPointerException("Source
must not be null");
[align=left] }[/align]
if (destDir
== null) {
throw new NullPointerException("Destination
must not be null");
[align=left] }[/align]
if (!srcDir.exists())
{
throw new FileNotFoundException("Source
'" + srcDir + "' does not exist");
[align=left] }[/align]
if (!srcDir.isDirectory())
{
throw new IOException("Source
'" + srcDir + "' is not a directory");
[align=left] }[/align]
if (destDir.exists())
{
throw new FileExistsException("Destination
'" + destDir + "' already exists");
[align=left] }[/align]
boolean rename
= srcDir.renameTo(destDir);
if (!rename)
{
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath()))
{
throw new IOException("Cannot
move directory: "+srcDir+ " to a subdirectory of
itself: "+destDir);
[align=left] }[/align]
[align=left] copyDirectory( srcDir, destDir );[/align]
[align=left] deleteDirectory( srcDir );[/align]
if (srcDir.exists())
{
throw new IOException("Failed
to delete original directory '" + srcDir +
"' after copy to '" +
destDir + "'" );
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align][align=left]注意:[/align]
1.boolean rename
= srcDir.renameTo(destDir);使用这个renameTo的操作移动,假如未成功再进行第二种移动操作(先复制,再删除)
[align=left] 2.不能移动父目录到子目录[/align]
[align=left] 3.删除不成功要抛出异常[/align][align=left]72.[/align]public static boolean isSymlink(File
file) throws IOException {
if (file
== null) {
throw new NullPointerException("File
must not be null");
[align=left] }[/align]
if (FilenameUtils.isSystemWindows())
{
[align=left] return false;[/align]
[align=left] }[/align]
[align=left] File fileInCanonicalDir = null;[/align]
if (file.getParent()
== null) {
[align=left] fileInCanonicalDir = file;[/align]
[align=left] } else {[/align]
[align=left] File canonicalDir = file.getParentFile(). getCanonicalFile();[/align]
fileInCanonicalDir = new File(canonicalDir,
file.getName());
[align=left] }[/align]
[align=left] [/align]
if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile()))
{
[align=left] return false;[/align]
[align=left] } else {[/align]
[align=left] return true;[/align]
[align=left] }[/align]
[align=left] }[/align]存疑貌似和WINDOWS系统无关?不懂。。。
相关文章推荐
- commons-IO 包解析学习---IOUtils篇(2)
- commons-IO 包解析学习---ByteArrayOutputStream篇(3)
- 通讯框架 t-io 学习——websocket 部分源码解析
- OMAPL138学习----DSPLINK DEMO解析之RING_IO
- 开源项目应用学习之Apache-commons-io
- commons-io之inputstream学习
- commons-io之filefilter学习
- apache_commons_io中的FileUtils学习
- org.apache.commons.io.FileUtils文件操作解析
- apache_commons_io中的IOUtils学习
- org.apache.commons.io.FileUtils学习
- [知了堂学习笔记]IO扩展_解析 properties文件
- Commons-IO学习之IOUtils
- Java IO流学习总结八:Commons IO 2.5-IOUtils
- Java IO流学习总结八:Commons IO 2.5-IOUtils
- commons-io 之FileUtils学习
- Java IO流学习总结八:Commons IO 2.5-IOUtils
- IO commons 学习 (- )。
- Java IO流学习总结八:Commons IO 2.5-IOUtils
- 深入学习Heritrix---解析处理器(Processor)(转)