【JavaSE 六】IO流

六、IO流

File文件对象

​ 创建一个File对象 ,可以表示文件或文件夹

​ 文件路径的连接,对于window系统使用\右斜杠连接路径,在java中可使用/或\(需要两个转义)连接

​ 三种创建方式:

File f1 = new File("F:/abc");//绝对路径
File f2 = new File("abc");//相对路径,相对于项目目录
File f3 = new File(f1,"abc");//f1的子目录

​ 文件常用的方法:

import java.io.File;
import java.io.IOException;
import java.util.Date;

public class test {
    public static void main(String[] args) throws IOException {
        File f1 = new File("F:/test/123.txt");//绝对路径
        System.out.println("判断文件或文件夹是否存在:"+f1.exists());
        System.out.println("判断是否是文件:"+f1.isFile());
        System.out.println("判断是否是文件夹:"+f1.isDirectory());
        System.out.println("获取文件长度(字节数):"+f1.length());
        System.out.println("获取文件最后修改时间:"+new Date(f1.lastModified()) );
        File f2 = new File("F:/test1/abc.txt");
        f1.renameTo(f2);

        File f3 = new File("F:/test/");//绝对路径
        // 以字符串数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
        for (String name:f3.list()) {
            System.out.print(name +"\t\t");
        }
        System.out.println();

        // 以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
        for (File f:f3.listFiles()) {
            System.out.print(f + "\t\t");
        }
        System.out.println();

        // 以字符串形式返回获取所在文件夹
        System.out.println(f3.getParent());
        // 以文件形式返回获取所在文件夹
        System.out.println(f3.getParentFile());

        File f4 = new File("F:/test1/123/");//绝对路径
        // 创建文件夹,如果父文件夹test1不存在,创建就无效
        f4.mkdir();
        // 创建文件夹,如果父文件夹test1不存在,就会创建父文件夹
        f4.mkdirs();

        File f5 = new File("F:/test/wc.txt");//绝对路径
        // 创建一个空文件,如果父文件夹test不存在,就会抛出异常
        f5.createNewFile();
        // 所以创建一个空文件之前,通常都会创建父目录
        f5.getParentFile().mkdirs();

        File f6 = new File("F:/test/wc.txt");//绝对路径

        // 列出所有的盘符c: d: e: 等等
        for (File f:File.listRoots()) {
            System.out.println(f);
        }

        // 刪除文件
        //f6.delete();

        // JVM结束的时候,刪除文件,常用于临时文件的删除
        f6.deleteOnExit();
        while (true){}//当程序死循环没有结束时,f6没有被删除,当手动结束运行时,f6被删除
    }
}

什么是流

​ 流就是一系列的数据,当不同的介质之间有数据交互时,java就使用流来实现

字节流

​ InputStream字节输入流,OutputStream字节输出流,用于以字节的形式读取或写入数据

​ ASCII码,所有的数据存储在计算机中都是以数字的形式存储的

以字节流的形式读取文件

​ InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现

​ FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class test {
    public static void main(String[] args) throws IOException {
        File f1 = new File("F:/test/123.txt");//绝对路径
        FileInputStream fis = new FileInputStream(f1);
        System.out.println(fis.read()+"\t");//一次读取一个字节。读取结尾返回-1
        byte[] b = new byte[(int) f1.length()];
        fis.read(b);//读取全部文件到字节数组
        for (byte bb : b) {
            System.out.println(bb);
        }
        fis.close();//使用完关闭流
    }
}
以字节流的形式向文件写入数据

​ OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现

​ FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class test {
    public static void main(String[] args) throws IOException {
        //如果文件不存在会创建文件,如果目录不存在,则报错
        File f1 = new File("F:/test/123.txt");//绝对路径
        FileOutputStream fos = new FileOutputStream(f1);
        //开始写时,是由文件开头进行写,会覆盖源文件
        fos.write(95);//一次写一个字节
        byte[] b = {69,70};
        fos.write(b);//写字节数组到文件
        fos.close();//使用完关闭流
    }
}

流的关闭方式

​ 1、在try中关闭,这种有弊端,当读取文件发生异常时,关闭流的语句则不会执行,这会造成资源的浪费

​ 2、在finally中关闭(标准关闭方式):

​ a、首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally

​ b、在finally关闭之前,要先判断该引用是否为空

​ c、关闭的时候,需要再一次进行try catch处理

​ 3、使用try()的方式,把流定义在try()里,try,catch或者finally结束的时候,会自动关闭。这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术。所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。

try (FileInputStream fis = new FileInputStream(f)) {}

字符流

​ 操作方式和字节流类似,只不过字符流读取时会把一个字符的所有字节都读到,字节流只读一个字节

文件编码格式

​ ISO-8859-1 包含 ASCII

​ GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。

​ unicode 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中。

​ unicode每个字符占4个字节,对存储数字和字母很不友好,造成空间浪费,所有就有utf-8。

​ UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节。

不希望byte数组输出负数,可以让结果与上0xFF,来使结果为正数

对于字节数组打印成字符,可以使用String ss = new String(c,“utf-8”);

​ FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了,而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替GBK。

缓存流

​ 以介质是硬盘为例,字节流和字符流的弊端,在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳

BufferedReader读取文件

​ 缓存字符输入流 BufferedReader 可以一次读取一行数据

FileReader fr = new FileReader(f1);
BufferedReader bis = new BufferedReader(fr);
String str =  bis.readLine();
System.out.println(str);
PrintWriter写出数据

​ PrintWriter 缓存字符输出流, 可以一次写出一行数据

FileWriter fw  = new FileWriter(f1);
PrintWriter bis = new PrintWriter(fw);
bis.println("我是第一行");
bis.println("我是第二行");
bis.println("我是第三行");
flush

​ 强制把缓存中的数据写到硬盘

数据流

​ DataInputStream 数据输入流,DataOutputStream 数据输出流

​ 使用数据流的writeUTF()和readUTF() 可以进行数据的格式化顺序读写

​ 通过DataOutputStream 向文件顺序写出 布尔值,整数和字符串。 然后再通过DataInputStream 顺序读入这些数据。

​ 要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException,因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取

对象流

​ 对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘

​ 一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口

练习

1)遍历文件夹(忽略子目录)

​ 遍历这个C:\WINDOWS目录的所有文件,找出最大最小的文件,打印他们的名字

import java.io.File;
import java.io.IOException;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/test");

        long maxFileSize = 0;
        long minFileSize = 0;
        String maxName = "";
        String minName = "";
        boolean isFirst = true;
        if (f.exists()) {
            File[] files = f.listFiles();//目录下所有文件和文件夹对象
            if (files !=null && files.length != 0) {//确保不会空指针
                for (File file : files) {
                    if (file.isFile()) {
                        if (isFirst) {//第一次查询到文件,把文件信息保存,然后后面的文件都和保存的做对比
                            maxFileSize = file.length();
                            minFileSize = file.length();
                            maxName = file.getName();
                            minName = file.getName();
                            isFirst = false;
                        }
                        if (file.length() > maxFileSize) {
                            maxName = file.getName();
                            maxFileSize = file.length();
                        }
                        if (file.length() < minFileSize) {
                            minName = file.getName();
                            minFileSize = file.length();
                        }
                    }
                }
                System.out.println("最大文件为:" + maxName + ",大小为:" + maxFileSize);
                System.out.println("最小文件为:" + minName + ",大小为:" + minFileSize);
            } else {
                System.out.println("目录中没有文件或对象为null");
            }
        } else {
            System.out.println("目录不存在");
        }
    }
}
2)遍历文件夹(包括子目录)

​ 遍历这个C:\WINDOWS目录的所有文件,找出最大最小的文件,打印他们的名字

import java.io.File;
import java.io.IOException;

/***
 * 如果抽象路径名不表示一个目录,或者发生 I/O 错误,则返回 null。
 * 在读取windows目录时发生了I/O错误,这是怎么回事呢?通过上网查阅资料,
 * 发现,存在一些文件/文件夹的访问权限很高,我们没有权限对其进行读写,
 * 此时就发生了所谓的I/O错误
 */

public class Exercise {

    private static long maxFileSize = 0;
    private static long minFileSize = 0;
    private static String maxName = "";
    private static String minName = "";
    private static boolean isFirst = true;

    public static void main(String[] args) throws IOException {
        File f = new File("F:/test");
        if(f.exists()){
            for (File file : f.listFiles()) {
                MaxAndMinFile(file);
            }

            System.out.println("最大文件为:" + maxName + ",大小为:" + maxFileSize);
            System.out.println("最小文件为:" + minName + ",大小为:" + minFileSize);
        }
        else {
            System.out.println("目录不存在");
        }

    }
    public static void MaxAndMinFile(File file){
        if(file.isDirectory()) {
            try {
                if(file.listFiles().length != 0){
                    File[] files = file.listFiles();
                    for (File f : files) {
                        MaxAndMinFile(f);
                    }
                }else {
                    System.out.println("为空文件夹");
                }

            }catch (NullPointerException e){
                System.out.println(file.getAbsolutePath());
            }


        }else {
            if (isFirst) {//第一次查询到文件,把文件信息保存,然后后面的文件都和保存的做对比
                maxFileSize = file.length();
                minFileSize = file.length();
                maxName = file.getName();
                minName = file.getName();
                isFirst = false;
            }
            if (file.length() > maxFileSize) {
                maxName = file.getName();
                maxFileSize = file.length();
            }
            if (file.length() < minFileSize) {
                minName = file.getName();
                minFileSize = file.length();
            }
        }

    }

}
3)写入数据到文件,如何解决目录不存在的问题

判断父目录是否存在,不存在就创建

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Exercise {

    public static void main(String[] args) throws IOException {
        File f = new File("F:/test1/yy");
        File dir = new File(f.getParent());
        if(!dir.exists()){
            dir.mkdirs();
        }
        FileOutputStream fis = new FileOutputStream(f);
        fis.write(98);
        fis.close();
    }
}
4)练习拆分文件

​ 找到一个大于100k的文件,按照100k为单位,拆分成多个子文件,并且以编号作为文件名结束。

import java.io.*;

public class Exercise {

    public static void main(String[] args) throws IOException {
        File f = new File("F:/test1/222.exe");
        splitFile(f,100);//以100k大小拆分文件
    }
    public static void splitFile(File f ,int chunks) throws IOException {
        int readContent = 1;//每次读取源文件的内容
        int chunkCount = 0;//拆分块的数量
        File fdir = new File(f.getParent()+"/splited/");
        fdir.mkdirs();//创建一个文件夹,存放拆分的文件
        if(f.exists() && f.isFile()){
            FileInputStream fis = new FileInputStream(f);
            //计算需要拆分多少块
            if(f.length()%chunks*1024 == 0)
            {
                chunkCount =(int) f.length()/(chunks*1024);
            }
            else {
                chunkCount =(int) f.length()/(chunks*1024) +1;
            }
            //循环读取内容,并写入新文件
            for (int i = 0; i <chunkCount; i++) {
                FileOutputStream fos = new FileOutputStream(new File(f.getParent()+"/splited/"+f.getName()+"-"+i));
                for (int j = 0; j < chunks*1024; j++) {
                    readContent =  fis.read();
                    if(readContent == -1)//读取最后一个块的时候可能不是完整的块大小,需要判断
                    {
                        break;
                    }
                    fos.write(readContent);
                }
                fos.close();
            }
        }
        else {
            System.out.println("文件不存在或文件是一个目录");
        }
        fis.close();
    }
}
5)练习合并文件

​ 将上题拆分的文件合并,合并后可以正常打开

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File fileMerged = new File("F:/test1/222-副本.exe");//合并后的文件
        FileOutputStream fos = new FileOutputStream(fileMerged);
        File fdir = new File(fileMerged.getParent()+"/splited/");//合并块的目录
        File[] farray = fdir.listFiles();
        for (File files : farray) {
            FileInputStream fis = new FileInputStream(files);
            for (int i = 0; i < files.length(); i++) {
                fos.write(fis.read());
            }
            fis.close();
        }
        System.out.println("合并完成");
    }
}
6)练习加密解密文件

​ 准备一个文本文件(非二进制),其中包含ASCII码的字符和中文字符。

​ 设计一个方法public static void encodeFile(File encodingFile, File encodedFile);

​ 在这个方法中把encodingFile的内容进行加密,然后保存到encodedFile文件中

​ 加密算法:

​ 数字:原数字加一,数字9变成零;字母:原字母往后移一个字母,z变成a,保留大小写

​ 设计一个方法解密public static void decodeFile(File decodingFile, File decodedFile);

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/test/encoding.txt");
        File f2 = new File("F:/test/encoded.txt");
        File f3 = new File("F:/test/decoded.txt");
        encodeFile(f, f2);
        decodeFile(f2,f3);
    }
    public static void encodeFile(File encodingFile, File encodedFile) throws IOException {
        FileReader fr = new FileReader(encodingFile);
        FileWriter fw = new FileWriter(encodedFile);
        int c;
        while ((c = fr.read()) != -1) {
            if(c<=122){
                if(Character.isLetter(c) || Character.isDigit(c)) {
                    if (c == 57) {
                        fw.write(48);
                    } else if (c == 90) {
                        fw.write(65);
                    } else if (c == 122) {
                        fw.write(97);
                    } else {
                        fw.write(c + 1);

                    }
                    fw.flush();
                }
                else {
                    fw.write(c);
                    fw.flush();
                }
            }
            else {
                fw.write(c);
                fw.flush();
            }
        }
    }
    public static void decodeFile(File decodingFile, File decodedFile) throws IOException {
        FileReader fr = new FileReader(decodingFile);
        FileWriter fw = new FileWriter(decodedFile);
        int c;
        while ((c = fr.read()) != -1) {
            if(c<=122){
                if(Character.isLetter(c) || Character.isDigit(c)) {
                    if (c == 48) {
                        fw.write(57);
                    } else if (c == 65) {
                        fw.write(90);
                    } else if (c == 97) {
                        fw.write(122);
                    } else {
                        fw.write(c - 1);

                    }
                    fw.flush();
                }
                else {
                    fw.write(c);
                    fw.flush();
                }
            }
            else {
                fw.write(c);
                fw.flush();
            }
        }
    }
}
7)练习数字对应的中文

​ 找出 E5 B1 8C 这3个十六进制对应UTF-8编码的汉字

import java.io.IOException;

public class Exercise {
    public static void main(String[] args) throws IOException {
        byte[] barray = new byte[]{(byte) 0xE5,(byte) 0xB1,(byte) 0x8C,};
        System.out.println(new String(barray,"utf-8"));
    }
}
9)练习移除utf-8编码方式中,字节前面的标识符

​ 如果用记事本根据UTF-8编码保存汉字就会在最前面生成一段标示符,这个标示符用于表示该文件是使用UTF-8编码的。找出这段标示符对应的十六进制,并且开发一个方法,自动去除这段标示符

import java.io.*;
public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/test/wbom.txt");
        FileInputStream fr = new FileInputStream(f);
        byte[] barray = new byte[(int) f.length()];
        fr.read(barray);
        System.out.print("utf-8的标识符为:");
        for (int i = 0; i < 3; i++) {
            int bom = barray[i] & 0x000000ff;
            System.out.print(Integer.toHexString(bom) + "\t");
        }
        System.out.println();
        splitBom(f);
        fr.close();
    }

    public static void splitBom(File file) throws IOException {
        FileInputStream fr = new FileInputStream(file);
        File f = new File("F:/test/wnobom.txt");
        FileOutputStream fos = new FileOutputStream(f);
        int cha;
        int flag = 0;
        while ((cha = fr.read())!=-1){
            if(flag >=3){
                fos.write(cha);
            }else {
                flag++;
            }
        }
    }
}
10)移除注释

​ 设计一个方法,用于移除Java文件中的注释,移出以//开头的注释行

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/test/comment.txt");
        removeComments(f);
    }

    public static void removeComments(File javaFile) throws IOException {
        FileReader fis =new FileReader(javaFile);
        BufferedReader br = new BufferedReader(fis);
        File f = new File("F:/test/removeComment.txt");
        FileWriter fos = new FileWriter(f);
        BufferedWriter bw = new BufferedWriter(fos);
        //完全复制原文件
        /***
         * 因为写每行字符串需要加回车,如果在每行写完在加,会在最后行多出来一行空行
         * 回车写在前,就会避免,不过会出现另外的问题,第一行会多出来空行
         * 那么就把第一行单独写了的,再写后面行
         *
         * !!!第一行如果有注释,我没有做处理!!!!
         */
        String str =br.readLine();
        bw.write(str);
        while ((str = br.readLine()) != null){
            if(str.contains("//")){
                if(!str.trim().startsWith("//")){
                    str = str.substring(0,str.indexOf("//"));
                    bw.write("\r\n"+str );
                }
            }else
            {
                bw.write("\r\n"+str );
            }
        }
        bw.flush();
        bw.close();
    }
}
11)练习-向文件中写入两个数字,然后把这两个数字分别读取出来

​ 第一种方式: 使用缓存流把两个数字以字符串的形式写到文件里,再用缓存流以字符串的形式读取出来,然后转换为两个数字。

注: 两个数字之间要有分隔符用于区分这两个数字。 比如数字是31和15如果不使用分隔符,那么就是3115,读取出来就无法识别到底是哪两个数字。 使用分隔符31@15能解决这个问题。

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/test/w.txt");
        FileWriter fw = new FileWriter(f);
        BufferedWriter bw = new BufferedWriter(fw);
        FileReader  fr = new FileReader(f);
        BufferedReader br = new BufferedReader(fr);
        bw.write(String.valueOf(3123));
        bw.write("@");
        bw.write(String.valueOf(3554));
        bw.close();
        StringBuffer sb = new StringBuffer();
        int temp;
        while ((temp=br.read()) != -1){
            if(temp != 64){
                sb.append((char)temp);
            }else {
                sb.append(' ');
            }
        }
        System.out.println(sb);
    }
}

​ 第二种方式: 使用数据流DataOutputStream向文件连续写入两个数字,然后用DataInpuStream连续读取两个数字

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/test/w.txt");

        FileOutputStream fos = new FileOutputStream(f);
        DataOutputStream dos = new DataOutputStream(fos);
        dos.writeInt(31356);
        dos.writeInt(35485);
        dos.close();

        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        System.out.println(dis.readInt());
        System.out.println(dis.readInt());
        dis.close();
    }
}
12)序列化数组

​ 准备一个长度是10,类型是Person的数组,使用10个Person对象初始化该数组

​ 然后把该数组序列化到一个文件persons.p

​ 接着使用ObjectInputStream 读取该文件,并转换为Person数组,验证该数组中的内容,是否和序列化之前一样

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File f = new File("F:/test/person.p");
        Person[] parray = new Person[10];
        for (int i = 0; i < parray.length; i++) {
            parray[i] = new Person("名字" + i, (i + 10));
        }
        FileOutputStream fos = new FileOutputStream(f);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        FileInputStream fis = new FileInputStream(f);
        ObjectInputStream ois = new ObjectInputStream(fis);
        //序列化对象
        oos.writeObject(parray);
        oos.close();
        //反序列化对象,并打印属性
        Person[] p13 = (Person[]) ois.readObject();
        for (Person p : p13) {
            System.out.println(p.getName() + "," + p.getAge());
        }
    }
}

class Person implements Serializable {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}
13)自动创建类

​ 自动创建有一个属性的类文件

​ 通过控制台,获取类名,属性名称,属性类型,根据一个模板文件,自动创建这个类文件,并且为属性提供setter和getter

import java.io.*;
import java.util.Scanner;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File templet = new File("F:/test/templet.txt");
        String classN;
        String type;
        String property = null;
        String Uproperty;
        Scanner s = new Scanner(System.in);
        System.out.println("输入类名:");
        classN = s.nextLine();
        System.out.println("输入属性类型:");
        type = s.nextLine();
        boolean flag = true;
        while (flag){
            System.out.println("输入属性名:");
            property = s.nextLine();
            if(Character.isLowerCase(property.charAt(0))){
                flag = false;
            }else {
                System.out.println("属性名首字母应该小写");
            }
        }

        Uproperty = property.replace(property.charAt(0),Character.toUpperCase(property.charAt(0)));

        FileReader fr = new FileReader(templet);
        FileWriter fw = new FileWriter(templet.getParent()+"/"+classN+".java");
        BufferedReader br = new BufferedReader(fr);
        BufferedWriter bw = new BufferedWriter(fw);
        String str;
        while ((str = br.readLine()) != null){
           str =  str.replace("@class@",classN);
           str = str.replace("@type@",type);
           str = str.replace("@property@",property);
           str = str.replace("@Uproperty@",Uproperty);
           bw.write(str+"\r\n");
        }
        bw.close();
    }
}
14)复制文件

​ 实现复制源文件srcFile到目标文件destFile

​ public static void copyFile(String srcFile, String destFile){}

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        String srcFilePath = "F:/test/test.exe";
        String destFilePath= "F:/test/test-copy.exe";
        copyFile(srcFilePath,destFilePath);
    }
    public static void copyFile(String srcFile, String destFile) throws IOException {
        File srcf = new File(srcFile);
        File destf = new File(destFile);
        FileInputStream fis = new FileInputStream(srcf);
        FileOutputStream fos = new FileOutputStream(destf);
        int c;
        //使用数组缓冲一下,速度会快一些
        while ((c = fis.read()) != -1){
            fos.write(c);
        }
    }
}
15)复制文件夹

​ 把源文件夹下所有的文件 复制到目标文件夹下(包括子文件夹)

​ public static void copyFolder(String srcFolder, String destFolder){}

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        String srcFolderPath = "F:/test";
        String destFolderPath= "F:/test1";
        copyFolder(srcFolderPath,destFolderPath);
    }
    public static void copyFile(String srcFile, String destFile) throws IOException {
        File srcf = new File(srcFile);
        File destf = new File(destFile);
        FileInputStream fis = new FileInputStream(srcf);
        BufferedInputStream bis = new BufferedInputStream(fis);
        if(!destf.exists()){
            destf.getParentFile().mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(destf);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        int c;
        //使用缓冲流,速度会快很多
        while ((c = bis.read()) != -1){
            bos.write(c);
        }
        bos.close();
        bis.close();         
    }
    public static void copyFolder(String srcFolder, String destFolder) throws IOException {
        File srcf = new File(srcFolder);
        File destf = new File(destFolder);

        for (File f : srcf.listFiles()) {

            if(f.isFile()){
                copyFile(f.getAbsolutePath(),destFolder+"/"+f.getName());
            }else{
                //复制空文件夹
                if(f.listFiles().length == 0){
                    new File(destFolder+"/"+f.getName()).mkdirs();
                }
                copyFolder(f.getAbsolutePath(),destFolder+"/"+f.getName());
            }
        }
    }
}
16)查找文件内容

​ 假设你的项目目录是 e:/project,遍历这个目录下所有的java文件(包括子文件夹),找出文件内容包括 Magic的那些文件,并打印出来。

​ public static void search(File folder, String search);

import java.io.*;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File f = new File("F:/Java/JavaProject");
        search(f,"Magic");
    }
    public static void search(File folder, String search) throws IOException {
        String str;
        for (File f : folder.listFiles()) {
            if (f.isFile()){
                FileReader  fr = new FileReader(f);
                BufferedReader br = new BufferedReader(fr);
                while ((str = br.readLine()) != null){
                    if(str.contains(search)){
                        System.out.println(f.getAbsolutePath());
                        break;
                    }
                }
                br.close();

            }else {
                search(f,search);
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值