37.Java中的“io流“

I/O流操作中,如何区分输入流和输出流呢?

I/O流是相对于计算机内存来说的,

输入流,就是将文件中的内容输入到内存中,让后显示出来,所以输入流可以用来读取数据。

输出流,就是讲数据从内存当中输出到文件当中,给某个文件加上内容,所以输出流可以用来添加文件的内容。


基本的字节流:一次读取一个字节/一次读取一个字节数组
字节缓冲流:一次读取一个字节/一次读取一个字节数组

 

字符转换流:InputStreamReader(InputStream in)
                  OutputStreamWriter(OutputStream out)
                  一次读取一个字符/一次读取一个字符数组
 
                  转换流的便捷类
                  FileReader(String name)
                  FileWriter(String writer)
                  一次读取一个字符/一次读取一个字符数组
 
                  BufferedReader/BufferedWriter
                  一次读取一个字符/一次读取一个字符数组
                 特有功能一次读取一行内容


成员方法:
创建/删除/重名
public boolean createNewFile()   throws IOException :表示创建文件 :如果不存在,则创建
public boolean mkdir():创建文件夹,如果不存在,则创建;否则就返回false
public boolean mkdirs():创建多个文件,如果父目录不存在,则创建
public boolean delete():删除文件或者文件夹(如果删除文件夹,文件夹必须为空目录)
public boolean renameTo(File dest):重命名

判断功能:
public boolean canRead()是否可读
public boolean canWrite()是否可写
public boolean exists():是否存在
public boolean isFile():是否是文件
public boolean isDirectory():是否是文件夹
public boolean isHidden():是否隐藏

public class FileDemo2 {
    public static void main(String[] args) {

        //创建File对象,描述当前项目下的aaa.txt文件
        File file = new File("aaa.txt") ;
        System.out.println(file.canRead());
        System.out.println(file.canWrite());
        System.out.println(file.exists());
        System.out.println(file.isDirectory());//false
        System.out.println(file.isFile());
        System.out.println(file.isHidden());
        System.out.println(file.length());
        System.out.println(file.getName());

高级获取功能:
public long length()
public String getName():获取抽象路径 名所表示的文件或者目录的名称
public File[] listFiles():获取某个目录下的所有的文件以及文件夹的File数组
public String[] list():获取某个抽象路径名所表示的文件以及目录的字符串数组

需求:

获取D盘下的所有的文件夹以及文件的名称....

public class FileDemo2 {
    public static void main(String[] args) {

        // public File[] listFiles():获取某个目录下的所有的文件以及文件夹的File数组
        //描述D盘
        File file2 = new File("d://") ;
        File[] fileArray = file2.listFiles();
        //防止空指针异常
        if(fileArray!=null){
            for(File f :fileArray){
                System.out.println(f.getName());
            }
        }
        System.out.println("----------------------------------");

        //public String[] list():获取某个抽象路径名所表示的文件以及目录的字符串数组
        String[] strArray = file2.list();
        if(strArray!=null){
            for(String s:strArray){
                System.out.println(s);
            }
        }


需求:

1.获取D盘下所有的以.jpg结尾的文件
  分析:
      (1)描述下D盘
      (2)public File[] listFiles():获取D盘下的所有的文件以及文件夹的File数组
      (3)对获取到的数组进行非判断,如果不为null,再去判断
      (4)判断File是一个文件
      (5)判断:文件必须以.jpg结尾;String类 endsWith(".jpg")

public class FileTest {
    public static void main(String[] args) {
        //1)描述D盘
        File file = new File("D://") ;

        //2)获取盘符下的所有的文件以及文件夹的File数组
        File[] fileArray = file.listFiles();//这一步并没有直接获取到要的.jpg文件
        //后面一些判断
        if(fileArray!=null){
            for(File f:fileArray){

                //判断f是文件
                if(f.isFile()){
                    //是文件
                    //判断它的名称是否以.jpg结尾
                    if(f.getName().endsWith(".jpg")){
                        System.out.println(f.getName());
                    }
                }
            }
        }
    }
}

2.使用过滤器[文件名称过滤器FilenameFilter:接口]

成员方法:

boolean accept(File dir,String name):测试指定文件是否包含在文件列表中,返回如果true,将文件添加到文件列表中.

(1)描述下D盘
(2) public File[] listFiles(FilenameFilter filenamefilter):
     获取D盘下的File数组的时候,就已经指定文件进行过滤.

public class FileTest {
    public static void main(String[] args) {
        File srcFile = new File("D://") ;

        //获取当前D盘下的所有文件以及文件夹File数组,并进行文件名过滤
        //public File[] listFiles(FilenameFilter filter)
        File[] files = srcFile.listFiles(new FilenameFilter() {//接口的匿名内部类
            @Override
            public boolean accept(File dir, String name) {
                //返回true:表示将指定文件添加列表文件中
                //描述文件所表示抽象路径File
                File file = new File(dir, name);

                //两个条件:file是文件并且file的文件名称以".jpg结尾"
                return file.isFile() && file.getName().endsWith(".jpg");
            }
        });
        if(files!=null){
            for(File f :files){
                System.out.println(f.getName());
            }
        }
    }
}

二.方法递归:方法调用方法本身的一种现象(并非是方法嵌套方法 )

前提条件
(1)必须有一个成员方法
(2)必须有方法递归的出口条件(结束条件),如果没有出口条件,就是死递归...
(3)还存在一定的规律

注意事项:构造方法不存在递归

需求:

使用递归方式去删除D盘某个demo文件夹中有很多个目录,每个目录中可能还有目录,删除这些所有目录中的带.java文件的文件

分析:
(1)描述下D盘下demo文件夹  File srcFile = new File("d://demo")
(2)调用递归删除方法
递归删除多级目录中的java文件
public void  deleteSrcFile(File srcFile){
获取srcFile的所有的文件夹以及文件的File数组
非空判断
判断如果是文件夹
回到到2)继续调用递归删除
否则,是文件
判断是否以.java文件
最终删除文件即可 } 

public class DiGuiTest {
    public static void main(String[] args) {

         //描述D盘的demo文件夹
         File srcFloder = new File("d://demo") ;
         //调用递归删除的方法
        deleteFloder(srcFloder) ;
    }


    public static void deleteFloder(File srcFloder) {
        //获取srcFloder下的所有的文件以及文件的File数组
        File[] fileArray = srcFloder.listFiles();
        if(fileArray!=null){
            for(File file:fileArray){
                //获取到每一个file对象
                //如果file是文件夹,继续回到deleteFloder(srcFloder) ; 删除文件夹
                if(file.isDirectory()){
                    deleteFloder(file) ;
                }else{
                    //判断是文件,必须以.java结尾 文件
                    if(file.getName().endsWith(".java")){
                        //删除的同时----获取名称
                        System.out.println(file.getName()+"------------"+file.delete());
                    }
                }

            }
            //删除文件夹
            System.out.println(srcFloder.getName()+"----"+srcFloder.delete());
        }
    }
}

 三.

1.文件数据读入(FileInputStream)----->文件中的内容读入到内存(一个字节一个字节读取)

public class test1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("F:\\Ideaproject\\Day28\\src\\lhb.txt");

            int by = 0;
            while ((by=fis.read()) != -1){
                System.out.print((char)by);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.文件数据读入(FileInputStream)----->文件中的内容读入到内存(字节数组读取)

public class test1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("F:\\Ideaproject\\Day28\\src\\lhb.txt");

            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len=fis.read(bytes))!= -1){
                System.out.println(new String(bytes,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

四.缓冲流的特点:提供缓冲区大写:1024的8倍  还是通过底层流提高读速度(FileInputStream)

字节缓冲输入流(BufferedInputStream)
构造方法
BufferedInputStream(InputStream in) :默认缓冲区大写 (足够大了)
提供一个指定的缓冲区大小
BufferedInputStream(InputStream in, int size)

(1)一个字节一个字节读取

public class test1 {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedInputStream  bis = null;
        try {
             bis = new BufferedInputStream(new FileInputStream("F:\\Ideaproject\\Day28\\src\\lhb.txt"));
            //字节读取
            int by = 0;
            while ((by = bis.read())!=-1){
                System.out.print((char) by);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

(2)字节数组读取

public class test1 {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedInputStream  bis = null;
        try {
             bis = new BufferedInputStream(new FileInputStream("F:\\Ideaproject\\Day28\\src\\lhb.txt"));
            //字节数组读取
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = bis.read(bytes))!=-1){
                System.out.print(new String(bytes,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字节缓冲输出流(BufferedOutputStream)

 BufferedOutputStream(OutputStream out)      

 推荐使用这个:默认缓冲区大小 足够大了  8kb
 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
 BufferedOutputStream(OutputStream out, int size)

public class test1 {
    public static void main(String[] args) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("xaiona.txt"));
        bos.write("我爱你".getBytes());
        bos.close();
    }
}

 五.

FileInputStream,FileOutputStream

基本的字节流一次读取一个字节数组------共耗时116毫秒

基本的字节流一次读取一个字节-----共耗时89021毫秒

BufferedInputStream,BufferedOutputStream

缓冲流一次读取一个字节数组------共耗时47毫秒

缓冲流一次读取一个字节-------共耗时348毫秒

需求:读取D://a.mp4,将这个文件内容复制到 当前项目下的copy.mp4中(先开的后关)

public class CopyMp4 {
    public static void main(String[] args) {
        //起始时间
        long start = System.currentTimeMillis() ;

         //copyMp4("D://a.mp4","copy.mp4") ;
        //copyMp4_2("D://a.mp4","copy.mp4") ;
        //copyMp4_3("D://a.mp4","copy.mp4") ;
          copyMp4_4("D://a.mp4","copy.mp4") ;

        //结束时间
        long end = System.currentTimeMillis() ;
        System.out.println("共耗时"+(end-start)+"毫秒");
    }

    //缓冲流一次读取一个字节数组
    private static void copyMp4_4(String srcFile, String destFile) {
        BufferedInputStream bis  = null ;
        BufferedOutputStream bos = null ;
        try {
            bis = new BufferedInputStream(new FileInputStream(srcFile)) ;
            bos = new BufferedOutputStream(new FileOutputStream(destFile)) ;
            //读写操作
            byte[] bytes = new byte[1024] ;
            int len = 0 ;
            while((len=bis.read(bytes))!=-1){
                bos.write(bytes,0,len);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bos.close();
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //缓冲流一次读取一个字节
    private static void copyMp4_3(String srcFile, String destFile) {
        BufferedInputStream bis  = null ;
        BufferedOutputStream bos = null ;
        try {
            bis = new BufferedInputStream(new FileInputStream(srcFile)) ;
            bos = new BufferedOutputStream(new FileOutputStream(destFile)) ;
            //读写操作
            int by = 0 ;
            while((by=bis.read())!=-1){
                bos.write(by);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bos.close();
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //基本的字节流一次读取一个字节数组
    public static void copyMp4_2(String srcFile,String destFile){
        //封装源文件和目的地文件
        FileInputStream fis = null ;
        FileOutputStream fos = null ;
        try {
            fis = new FileInputStream(srcFile) ;
            fos = new FileOutputStream(destFile) ;
            //读写复制
            byte[] bytes = new byte[1024] ;
            int len = 0 ;//实际字节数
            while((len=fis.read(bytes))!=-1){
                fos.write(bytes,0,len);
                //强制输出流将缓冲的这字节数写出来
                fos.flush();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fos.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //基本的字节流一次读取一个字节
    public static void copyMp4(String srcFile, String destFile) {
        //封装源文件和目的地文件
        FileInputStream fis = null ;
        FileOutputStream fos = null ;
        try {
             fis = new FileInputStream(srcFile) ;
             fos = new FileOutputStream(destFile) ;

             //读写复制
            int by = 0 ;
            while((by=fis.read())!=-1){
                fos.write(by);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fos.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

六.字符流的出现是在字节流的后面,可以解决中文乱码问题

Writer:抽象类
提供子类:字符转换输出流: 字节输出流通向字符输出流的桥梁
构造方法
OutputStreamWriter(OutputStream out) :使用平台默认编码集写入数据
OutputStreamWriter(OutputStream out, String charsetName) :使用指定的字符集进行编码 写入数据

public class WriterDemo {
    public static void main(String[] args) throws Exception {
        //创建字符缓冲输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt")) ;//使用平台的默认编码集(utf-8)

        //写入数据
        /**
         * write(String str)
         * write(int ch):写入字符: 字符--->对应的ASCII码表
         * write(char[] ch)
         * write(char[] ch,int off,int len)
         * write(String str,int off,int len)
         */
        osw.write("hello,字符流我来了");
        osw.write(97);
        char[] chs = {'A','B','C','D','E'} ;
        osw.write(chs);
        osw.write(chs,2,2);
        //使用flush():刷新字符输出流
        osw.flush();

        //关闭资源,释放相关的资源
        osw.close();  //关闭之前,flush

    }
}

Reader:抽象类
具体的子类:字符转换输入流 InputStreamReader
构造方法
InputStreamReader(InputStream in) :使用平台默认解码集进行读
InputStreamReader(InputStream in,String charset) :使用指定的解码集进行读

public class test1 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("f:\\lhb.txt"));
        char[] chars = new char[1024];
        int len = 0;
        while ((len=isr.read(chars))!=-1){
            System.out.println(new String(chars,0,len));
        }
        isr.close();
    }
}

需求:
当f盘的lhb.txt文件  复制到 当前项目下的lhb2.txt
针对文本文件:优先采用字符流

public class test1 {
    public static void main(String[] args) throws IOException {
        FileReader srcfile = new FileReader("f:\\lhb.txt");
        FileWriter targerfile = new FileWriter("lhb2.txt");

        /*int by = 0;
        while ((by=srcfile.read())!=-1){
            targerfile.write(by);
            targerfile.flush();
        }*/
        char[] chars = new char[1024];
        int len = 0;
        while((len = srcfile.read(chars))!=-1){
            targerfile.write(chars,0,len);
            targerfile.flush();

        }
        targerfile.close();
        srcfile.close();
    }
}

 BufferedReaer/BufferedWriter  :读写复制操作
一次读取一个字符
一次读取一个字符数组
特有功能:
利用BufferedReader的readLine()读取一行
利用BufferedWriter写一行,然后换行

一个文本文件读写复制:
阻塞流 (传统的IO流)
当一个线程如果操作的是读的动作, read(byte[] byte/char[] ..)/readLine():都属于阻塞式方法
另一个线程如果操作的是写的动作, 读的线程如果开始读,这边写的线程才能开始进行写的复制操作

需求:

当f盘的lhb.txt文件  复制到 当前项目下的lhb2.txt

public class test1 {
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;

        try {
            br = new BufferedReader(new FileReader("f://lhb.txt"));
            bw = new BufferedWriter(new FileWriter("lhb2.txt"));

            String line = null;
            while ((line=br.readLine())!=null){
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bw.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

七. 将两个以上的文件进行读取

public SequenceInputStream(Enumeration<? extends InputStream> e) 
                Vector<InputStream>
                add(添加多个字节输入流对象)


需求:将f盘下的lhb.txt   lhb2.txt   lhb3.txt  文件进行读取,复制到当前目录下的lhb4.txt             

public class test1 {
    public static <vector> void main(String[] args) throws IOException {
        InputStream is1 = new FileInputStream("f:\\lhb.txt");
        InputStream is2 = new FileInputStream("f:\\lhb2.txt");
        InputStream is3 = new FileInputStream("f:\\lhb3.txt");

        Vector<InputStream> vector = new Vector<>();
        vector.add(is1);
        vector.add(is2);
        vector.add(is3);

        Enumeration<InputStream> enumeration = vector.elements();

        //创建合并流对象  封装源文件
        SequenceInputStream sis = new SequenceInputStream(enumeration);

        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("lhb4.txt"));
        int by = 0;
        while((by=sis.read())!=-1){
            bos.write(by);
            bos.flush();
        }
        bos.close();
        sis.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值