来看一个例子:
package command.line.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFilePath
{
public static void main(String[] args)
{
// 源文件:
// D:\dev\workspace\CmdShellTools\蓝精灵1.jpg
File fromFile = new File("D:\\dev\\workspace\\CmdShellTools\\蓝精灵1.jpg");
File toFile = new File(
"D:\\dev\\workspace\\CmdShellTools\\new1\\new2\\蓝精灵2.jpg");
copyByStream(fromFile,toFile);
}
/**
* @param fromFile
* @param toFile
*/
public static void copyByStream(File fromFile, File toFile)
{
FileInputStream ins = null;
FileOutputStream out = null;
try
{
ins = new FileInputStream(fromFile);
/*
* 使用FileOutputStream写文件
* 如果目标文件不存在,则FileOutputStream会创建目标文件(前提是父路径文件对象必须存在)。
*/
out = new FileOutputStream(toFile);
byte[] buf = new byte[1024];
int size = 0;
// 每次读取1024个字节,然后写入1024自己
while ((size = ins.read(buf)) != -1)
{
out.write(buf, 0, size);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (ins != null)
{
try
{
ins.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
if (out != null)
{
try
{
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}// 方法结束
}
当前的工程目录如下:
现在我要拷贝工程目下的蓝精灵1.jpg
(路径为:D:\dev\workspace\CmdShellTools\蓝精灵1.jpg
)到当然工程路径下的new1\new2\蓝精灵2.jpg
。但是呢,从上面的图中可以看出,.\new1\new2
这个路径并不存在。这个时候因为目标文件不在当前路径下,FileOutputStream就不会创建这个文件,这样就会导致FileNotFoundException
异常:
运行上面的代码,输出结果为:
java.io.FileNotFoundException: D:\dev\workspace\CmdShellTools\new1\new2\蓝精灵1.jpg (系统找不到指定的路径。)
......
at command.line.test.TestFilePath.main(TestFilePath.java:37)
那我先创建这个文件不就行了吗?使用toFile.createNewFile()创建该文件。把上面的main方法改成:
public static void main(String[] args)
{
// 源文件:
// D:\dev\workspace\CmdShellTools\蓝精灵1.jpg
File fromFile = new File("D:\\dev\\workspace\\CmdShellTools\\蓝精灵1.jpg");
File toFile = new File(
"D:\\dev\\workspace\\CmdShellTools\\new1\\new2\\蓝精灵2.jpg");
if(!toFile.exists())
{
try
{
toFile.createNewFile();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
copyByStream(fromFile,toFile);
}
运行结果:
java.io.IOException: 系统找不到指定的路径。
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(Unknown Source)
at command.line.test.TestFilePath.main(TestFilePath.java:21)
java.io.FileNotFoundException: D:\dev\workspace\CmdShellTools\new1\new2\蓝精灵1.jpg (系统找不到指定的路径。)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at command.line.test.TestFilePath.copyByStream(TestFilePath.java:65)
at command.line.test.TestFilePath.main(TestFilePath.java:48)
可以看到这样也是不行的,File类也不到这个不存在的路径。
解决方法:
先创建.\new1\new2
这两个不存在的文件夹,然后再创建.\new1\new2\蓝精灵2.jpg
。这样就可以了,具体代码如下:
public static void main(String[] args)
{
// 源文件:
// D:\dev\workspace\CmdShellTools\蓝精灵1.jpg
File fromFile = new File("D:\\dev\\workspace\\CmdShellTools\\蓝精灵1.jpg");
File toFile = new File(
"D:\\dev\\workspace\\CmdShellTools\\new1\\new2\\蓝精灵2.jpg");
// if(!toFile.exists())
// {
// try
// {
// toFile.createNewFile();
// } catch (IOException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
//如果文件不存在
if (!toFile.exists())
{
//先创建该文件的所有上级目录
if (toFile.getParentFile().mkdirs())
{
try
{
//再创建该文件
toFile.createNewFile();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// 因为不是在同一目录下,所以必须要先创建源文件,不然FileOutputStream找不到这个文件,将会复制失败
copyByStream(fromFile,toFile);
}
这样就可以了,运行结果:
可以看到现在已经在当前工程目录(D:\dev\workspace\CmdShellTools
)下,新建了子目录new1\new2
,而且复制文件也成功了。
这里个关键操作就是
if (!toFile.exists())
{
//先创建该文件的所有上级目录
if (toFile.getParentFile().mkdirs())
{
try
{
//再创建该文件
toFile.createNewFile();
} catch (IOException e)
{
}
}
}
意思就是,如果这个系统中找不到新文件的路径,那应该是他的父目录没有建好,所以,先使用toFile.getParentFile()
获取该文件的父路径的File对象,然后再创建使用mkdirs()方法创建这些父路径。如果父路径创建成功了,我们再创建这个文件。其实这个文件不用创建也是可以的,只要文件蓝精灵2.jpg
的父目录存在,FileOutputStream就可以自动创建这个文件,所以把上面的代码改成下面的形式也是可以的。
//如果文件不存在
if (!toFile.exists())
{
toFile.getParentFile().mkdirs();
}
// 因为不是在同一目录下,所以必须要先创建源文件,不然FileOutputStream找不到这个文件,将会复制失败
copyByStream(fromFile,toFile);
最终版本:
package command.line.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFilePath
{
public static void main(String[] args)
{
File fromFile = new File(".\\蓝精灵1.jpg");
File toFile = new File(".\\new1\\new2\\蓝精灵2.jpg");
if (fromFile.exists())
{
// 如果文件不存在
if (!toFile.exists())
{
toFile.getParentFile().mkdirs();
}
// 因为不是在同一目录下,所以必须要先创建源文件,不然FileOutputStream找不到这个文件,将会复制失败
copyByStream(fromFile, toFile);
} else
{
System.out.println("源文件不存在");
}
}
/**
* @param fromFile
* @param toFile
*/
public static void copyByStream(File fromFile, File toFile)
{
FileInputStream ins = null;
FileOutputStream out = null;
try
{
ins = new FileInputStream(fromFile);
/*
* 使用FileOutputStream写文件
* 如果目标文件不存在,则FileOutputStream会创建目标文件(前提是父路径文件对象必须存在)。
*/
out = new FileOutputStream(toFile);
byte[] buf = new byte[1024];
int size = 0;
// 每次读取1024个字节,然后写入1024自己
while ((size = ins.read(buf)) != -1)
{
out.write(buf, 0, size);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (ins != null)
{
try
{
ins.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
if (out != null)
{
try
{
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}// 方法结束
}
当然,可以把上面复制文件的代码整合到一个方法中
复制文件到任意路径的方法如下:
/**
* @param fromFile
* @param toFile
*/
public static void copyByStream(File fromFile, File toFile)
{
//源文件存在才复制
if (fromFile.exists())
{
// 如果找不到目标文件
if (!toFile.exists())
{
//这说明目标文件的上级目录不存在,先新建所有的上级目录
toFile.getParentFile().mkdirs();
}
FileInputStream ins = null;
FileOutputStream out = null;
try
{
ins = new FileInputStream(fromFile);
/*
* 使用FileOutputStream写文件
* 如果目标文件不存在,则FileOutputStream会创建目标文件(前提是父路径文件对象必须存在)。
*/
out = new FileOutputStream(toFile);
byte[] buf = new byte[1024];
int size = 0;
// 每次读取1024个字节,然后写入1024自己
while ((size = ins.read(buf)) != -1)
{
out.write(buf, 0, size);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (ins != null)
{
try
{
ins.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
if (out != null)
{
try
{
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
} else
{
System.out.println("源文件不存在");
}
}
使用方式:
package command.line.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFilePath
{
public static void main(String[] args)
{
File fromFile = new File(".\\蓝精灵1.jpg");
File toFile = new File(".\\new1\\new2\\蓝精灵2.jpg");
copyByStream(fromFile, toFile);
}
/**
* @param fromFile
* @param toFile
*/
public static void copyByStream(File fromFile, File toFile)
{
//源文件存在才复制
if (fromFile.exists())
{
// 如果找不到目标文件
if (!toFile.exists())
{
//这说明目标文件的上级目录不存在,先新建所有的上级目录
toFile.getParentFile().mkdirs();
}
FileInputStream ins = null;
FileOutputStream out = null;
try
{
ins = new FileInputStream(fromFile);
/*
* 使用FileOutputStream写文件
* 如果目标文件不存在,则FileOutputStream会创建目标文件(前提是父路径文件对象必须存在)。
*/
out = new FileOutputStream(toFile);
byte[] buf = new byte[1024];
int size = 0;
// 每次读取1024个字节,然后写入1024自己
while ((size = ins.read(buf)) != -1)
{
out.write(buf, 0, size);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (ins != null)
{
try
{
ins.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
if (out != null)
{
try
{
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
} else
{
System.out.println("源文件不存在");
}
}
}