JAVA中IO输入输出

一、File

通过调用File类提供的各种方法,能够创建,删除或者重命名文件,判断硬盘上某个文件是否存在,查询文件最后修改时间等。

构造方法

File file = new File("D:\\file\\a.txt");//绝对路劲     
File file1 = new File("src\\Hello.java");//相对路劲          
System.out.println(file);//D:\file\a.txt                          
System.out.println(file1);//src\Hello.java
//在Java中,反斜杠“\” 表示转义符,Windows中的目录符号为反斜线“\”,因此用两个斜杆表示。也可以使用“/”表示                   

常用方法

操作 

 遍历目录下文件
File file = new File("E:\\Code\\example\\demo7_example\\src\\com\\wyy\\example");     
if (file.isDirectory()){//判读是否存在该目录                                                   
    String[] list = file.list();//将该目录下的文件存放在集合中                                      
    for (String name : list){                                                         
        System.out.println(name);                                                     
    }                                                                                 
遍历目录下指定类型的文件 

File类中提供了一个重载的list(FilenameFilter filter)方法,该方法接收一个FilenameFilter类型的参数。而FilenameFilter是一个接口,被称作文件过滤器,当中定义了一个抽象方法accept(File dir,String name)

要获取指定类型的文件,需要调用list()方法,实现文件过滤器FilenameFilter,并且在accept()中做出判断。

File file = new File("com/wyy/example");                     
//过滤器对象                                                      
FilenameFilter filter = new FilenameFilter() {               
    //在accpet方法中实现                                           
    @Override                                                
    public boolean accept(File dir, String name) {
        //获取当前文件对象           
        File currFile = new File(dir, name);
        // 如果文件名以.java结尾返回true,否则返回false                 
        if (currFile.isFile() && name.endsWith(".java")) {    
            return true;                                     
        } else {                                             
            return false;                                    
        }                                                    
    }                                                        
};                                                           
if (file.exists()) { // 判断File对象对应的目录是否存在                    
    String[] lists = file.list(filter); // 获得过滤后的所有文件名数组     
    for (String name : lists) {                              
        System.out.println(name);                            
    }                                                        

整个过程中,file()文件对象调用list()方法传入上面设定好的FilenameFilter文件过滤器对象,接着取出当前Fiel对象所代表的目录下的所有的子目录和文件,而对于每一个子目录和文件,都会调用文件过滤器对象中我们重写的accept(File dir,String name)方法,并且把代表当前目录的File对象以及这个子目录或文件的名字作为参数dir和name传递给方法。最后,如果accept()方法返回true,就将当前遍历的这个子目录或文件添加到数组中,如果返回false,则不添加。

遍历目录下每一层文件包括子目录中的所有内容

如果想得到所有子目录下的File类型对象,list()方法显然不能满足要求,这时需要使用File类提供的另一个方法listFiles()。

public static void main(String[] args) {                            
    File file = new File("D:\\Computer\\tools");                    
    fileDir(file);                                                  
}                                                                   
public static void fileDir(File dir){                               
    File[] files = dir.listFiles();//获取该目录下所有文件的额属数组                
    for (File file: files){ // 遍历所有的子目录和文件                          
        if (file.isDirectory()){                                    
            fileDir(file); // 如果是目录,递归调用fileDir()                   
        }                                                           
        System.out.println(file.getAbsolutePath());// 输出文件的绝对路径     
    }                                                               
}                                                                                                                     
删除文件及目录
File file = new File("D:\\hello");         
if (file.exists()){                        
    System.out.println(file.delete());     
}                                          

 上面的代码运行结果为 false,因为delete()方法只能删除一个指定的文件,对于一个目录下存在多个文件,无法将其和删除,只能在当前目录为空的情况下,才能删除成功。若想要一次性完全删除,则需要利用递归一层层的删除。

public static void main(String[] args) {                
    File file = new File("D:\\hello\\test");            
    deleteDir(file);                                    
}                                                       
public static void deleteDir(File Dir) {                
    if (Dir.exists()) {                                 
        File[] files = Dir.listFiles();                 
        for (File file : files) {                       
            if (file.isDirectory()) {                   
                deleteDir(file);                        
            } else {                                    
                file.delete();                          
            }                                           
            Dir.delete();                               
        }                                               
    }                                                   
}                                                       

二、字节流

概述

在计算机中,所有的文件都是以二进制形式存在的,而对于字节的输入输出IO流提供了一系列的流,称为字节流。根据输入方向可以将其分为字节输入流和字节输出流。

字节流的父类——两个抽象类InputStream和OutputStream,io流中的输入输出都是相对与程序而言的。InputStream是输入,从源输入到程序,OutputStream是输出,从程序输出到目标设备。

 读写数据相关方法

InputStream读数据

OutputStream写数据

子类实例

对于Inputsteam和OutStream两个抽象父类而言,并不能被实例化,因此,这两个类提供了不同的子类。

InputStream体系

OutputStream体系

 FileIntputStream和FileOutputStream

将文件的内容输入到程序上 ——FileInputstream

public static void main(String[] args) throws Exception {
        FileInputStream inputStream = null;
        try {
             inputStream = new FileInputStream("E:\\Code\\example\\demo7_example\\src\\com\\wyy\\example\\test.txt");
//在根目录下创建一个test.txt文件,在文件中写入 “abcd”。这里的路劲最好填写绝对路劲,相对路劲容易报找不到该文件的异常错误。
            int b = 0;
            while (true){
                b = inputStream.read();
                if (b == -1){
                    break;
                }
                System.out.println(b);
            }
        } finally {
            if (inputStream != null){
                inputStream.close();
            }
        }//97 98 99 100
    }

将程序上的内容输入到文件中—— FileOutputStream

public static void main(String[] args) throws Exception {
        FileOutputStream outputStream = null;
        try {
             outputStream = new FileOutputStream("E:\\Code\\example\\demo7_example\\src\\com\\wyy\\example\\test2.txt");
            String str = "芒果披萨";
            byte[] bytes = str.getBytes();
            for (int i = 0; i < bytes.length; i++) {
                outputStream.write(bytes[i]);
            }
        } finally {
            outputStream.close();

        }
    }

结果

 在这个过程中,FileOUtStrem会创建会直接创建一个文件,在文件中输入对应的字符,若是已经存在文件,会将该文件中的内容先清空,再写入相对应的字符。

如果想要在文件后面追加,则可以使用FileOutputStream(String fileName, boolean append)来创建文件输出流对象,并把append 参数的值设置为true。

将上述代码中这两行进行修改

outputStream = new FileOutputStream("E:\\Code\\example\\demo7_example\\src\\com\\wyy\\example\\test2.txt",true);
String str = "你好";

 结果

文件复制

public static void main(String[] args) throws Exception {
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        try {
            inputStream = new FileInputStream("source/test.docx");
            outputStream = new FileOutputStream("target/test.docx");
            int len;
            long start = System.currentTimeMillis();
            while ((len = inputStream.read()) != -1) {//判断是否读到文件末尾
                outputStream.write(len);
            }
            long end = System.currentTimeMillis();
            System.out.println("消耗时间:" + (end - start) + "毫秒");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }//消耗时间:2039毫秒
    }

实际上以上方式拷贝效率十分低下,相当于外卖员送两份餐到同一单主手上,但他却跑了两次,每一次只拿一份。因此,为了提高效率,引入了缓冲区。 

FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        try {
            inputStream = new FileInputStream("E:\\Code\\example\\demo7_example\\source\\test.docx");
            outputStream = new FileOutputStream("E:\\Code\\example\\demo7_example\\src\\com\\wyy\\example\\test.docx");
            byte[] buff = new byte[1024];
            int len;
            long start = System.currentTimeMillis();
            while ((len = inputStream.read(buff)) != -1) {//判断是否读到文件末尾
                outputStream.write(buff,0,len);
                //每循环一次,就从文件读取若干字节填充字节数组,并通过变量len记住读入数组的字节数,
                // 然后从数组的第一个字节开始,将len个字节依次写入文件。
            }
            long end = System.currentTimeMillis();
            System.out.println("消耗时间:" + (end - start));
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }// 消耗时间:39毫秒
        }
    }
 缓冲区

 IO提供两个带缓冲的字节流,分别是BufferedInputStream和BufferedOutputStream,它们的构造方法中分别接收InputStream和OutputStream类型的参数作为对象,在读写数据时提供缓冲功能。

这两个流内部都定义了一个大小为8192的字节数组,调用read()或者write()方法读写数据时,首先将读写的数据存入定义好的字节数组,然后将字节数组的数据一次性读写到文件中。

    public static void main(String[] args) throws Exception {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //带缓冲区的输入流
            bis = new BufferedInputStream(new FileInputStream("src.txt"));
            //带缓冲区的输出流
             bos = new BufferedOutputStream(new FileOutputStream("des.txt"));
            int len;
            while((len = bis.read()) != -1){
                bos.write(len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bis != null){
                bis.close();
            }
            if (bos != null){
                bos.close();
            }
        }
    }

三、字符流

概述

字符流父类——两个抽象类Reader和Writer,其中Reader是字符输入流,用于从某个源设备读取字符。Writer是字符输出流,用于向某个目标设备写入字符。

体系

 

 

字符流与字节流类似,很多方法都相同。不同的是字符流是char类型,而字节流是String类型。在缓冲区中还有一点不同的是,BufferReader中有readLine方法,BufferWriter中有newLine()方法, 写入一个换行符,该方法会根据不同的操作系统生成相应的换行符。

public static void main(String[] args) throws Exception {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
             bufferedReader = new BufferedReader(new FileReader("source.txt"));
             bufferedWriter = new BufferedWriter(new FileWriter("target.txt"));
            String str;
            while(( str = bufferedReader.readLine()) != null){//读一行
                bufferedWriter.write(str);//输入一行
                bufferedWriter.newLine();//换行
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            bufferedReader.close();
            bufferedWriter.close();
        }
    }

四、转换流

InputStreamReader是Reader的子类,它可以将一个字节输入流转换成字符输入流,方便直接读取字符。OutputStreamWriter是Writer的子类,它可以将一个字节输出流转换成字符输出流,方便直接写入字符。

public static void main(String[] args) throws Exception {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            FileInputStream fileInputStream = new FileInputStream("start.txt");//字节输入流
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);//字节流转哈为字符流
             bufferedReader = new BufferedReader(inputStreamReader);//创建字符流缓冲区

            FileOutputStream outputStream = new FileOutputStream("end.txt");//字节输出流
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);//字节流转换为字符流
             bufferedWriter = new BufferedWriter(outputStreamWriter);//创建字符流缓冲区

            String line;
            while ((line = bufferedReader.readLine()) != null){
                bufferedWriter.write(line);
                bufferedWriter.newLine();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (bufferedReader != null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                if (bufferedWriter != null){
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

针对操作文本文件的字节流进行转换,如果字节流操作的是一张图片,此时转换为字符流就会造成数据丢失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值