博主最近一直在跟着杜老师的Java课程进行学习,最近学习到 IO流,也终于能写出些有意思的代码,在此与各位互相交流学习,如果有错误的地方,还望及时指正,以免误导他人。
题目
用IO流等相关知识做出类似于复制粘贴文件的操作。
涉及知识
1、File类的部分方法。
2、字节流的使用。
3、递归思想。
我的代码
Copy_目录_博客测试
这里是主要的代码,注释我已经尽量写的详尽,如果仍有疑问,可以在评论区留言,或者直接私信我。
package IO流;
import java.io.File;
import java.util.Scanner;
public class Copy_目录_博客测试 {
public static void main(String[] args) {
// 读入输入源与输出位置。
Scanner in = new Scanner(System.in);
File file = new File(in.next());
// 由于输出位置必然为某一目录下,所以在读入输出位置后要加上file.getName()函数进行补全文件名,以便
// 进行后续操作。
File tofile = new File(in.next()+"\\"+file.getName());
// 这里要加个判断,输入源为一个文件,也就直接复制过去即可,否则(也就是目录了)则要进行递归进行处理。
if(file.isDirectory())
{
// 能进到这里必然说明file为目录,所以输出位置自然要建一个目录了。
tofile.mkdir();
// 因为是目录,不确定目录中是否还有目录,所以递归便很容易想到要用(主要是杜老师说了。。)
digui(file,tofile);
}
else
{
// 进到这里说明file是文件,直接复制即可。
Copy_目录_字节流版.fileRW(file.getAbsolutePath(),tofile.getAbsolutePath());
}
}
// 这里是递归函数
// 主要思路,因为第一次被调用必然是一个目录被传进来,取出这个目录中的所有file,若file为目录,继续调用递归函数。
// 若file为文件,则直接复制文件即可。
private static void digui(File file,File tofile) {
// 这里要把输出位置存储下,因为在递归中,有可能在该文件中先取出来个目录,这时候又要递归了,而递归又伴随着新的文件路径
// 的产生,而此时该文件下极有可能还有其他未取出的文件,所以要保存第一次进入一个新路径下的当前路径,以便后续继续进行当
// 前路径的递归。
File ls = tofile;
// 取出目录下的所有file
File[] files = file.listFiles();
for (File filet: files) {
// 判断文件是否为目录,true:递归
// false:复制文件
if(filet.isDirectory())
{
// 进入此处说明file为目录,所以进行递归。
// 在递归时输出位置自然也要改变,否则复制的位置就对不上了。
// 要注意一定是ls.getAbsolutePath()+"\\"+filet.getName()
// 如果是tofile.getAbsolutePath()+"\\"+filet.getName()
// 那此时就犯了我在递归函数下方开头所说的错误,tofile在变!
// 所以这样复制的位置就是错误的!
tofile = new File(ls.getAbsolutePath()+"\\"+filet.getName());
// 此时tofile的路径已经改变,符合当前目录下的目录的路径,可以进行新目录的创建了。
tofile.mkdir();
// 准备工作完成,进行递归。
digui(filet,tofile);
}
else
{
// 进入这里,那就说明这个file是个文件,那就直接复制了。
Copy_目录_字节流版.fileRW(filet.getAbsolutePath(),ls.getAbsolutePath()+"\\"+filet.getName());
// Copy_目录_字节流读入类的代码见下方。
}
}
}
}
Copy_目录_字节流版
这里是一个简单的字节流读入和写出的操作。
package IO流;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
// 这里便是大家所熟悉的字节流读入了。
public class Copy_目录_字节流版 {
public static void fileRW(String read, String write) {
// 在try外面定义,因为要在结尾关掉,如果写在try中,编译器不确定是否能执行到fis、fos有对象,所以会报错。
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 接收源文件与目标位置
fis = new FileInputStream(read);
fos = new FileOutputStream(write);
// 读取准备及操作
byte[] bytes = new byte[1024 * 1024]; // 这里以1M进行传输。
int fiscount = 0;
while ((fiscount = fis.read(bytes)) != -1) {
fos.write(bytes, 0, fiscount);
}
// 别忘记了所有的输出流均需要flush()
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally { // 最后最好分别关闭流,否则如果在同一个try中关闭流
if (fos != null) { // 如果上面的一个流出现了异常,就影响到下面那个流
try { // 的关闭。
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
输入格式:
D:\java\流测试
D:
这是将 D盘的java包下的流测试包进行复制到D盘下。
总结
别看我写的多,其实将我的注释去掉,就没剩下几行了,大家可以先把我的代码复制下来,把注释去掉,看不懂再来看看我的博客上的注释。
如有谬误,请务必告知,以免误导他人
如果各位看官觉得写得不错,对你有帮助,能不能给个赞啊,这是对我最大的鼓励!