栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

IO流的学习

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

IO流的学习

IO流 一、IO简介 java四大IO抽象类 字节输入输出流

InputStream

此抽象类(不能被实例化)表示字节输入流的所有类的父类

常用方法:

  • int read():读取一个字节的数据,并将字节的值作为int类型返回(0-255之间),如果没有读出或者读取结束返回-1
  • void close():关闭输入流对象,释放相关系统资源

OutputStream

此抽象类(不能被实例化)表示字节输出流的所有类的父类

常用方法:

  • void write(int n):向目的地中写入一个字节
  • void close():关闭输出流对象,释放相关系统资源
字符输入输出流

Reader

用于读取字符流的抽象类,数据单位为字符

常用方法:

  • int reader():读取一个字符的数据,并将字符的值作为int类型返回(0-65535)如果读取失败或者读取结束返回-1
  • void close():关闭流对象,释放相关系统资源

Writer

用于输出的字符流抽象,数据单位为字符

常用方法:

  • void write(int n):向输出流中写入一个字符

  • void close():关闭流对象,释放相关系统资源

二、IO流入门案例

第一个简单的IO流程序

public class Demo1 {
    public static void main(String[] args) {
        
        //创建字节输入流对象
        FileInputStream fis=null;
        try {
            fis=new FileInputStream("d:/a.txt");//注意不要加多余的回车或者空格
            int s1=fis.read();//对应一个字符a的Ascll码
            int s2=fis.read();
            int s3=fis.read();
            int s4=fis.read();
            int read = fis.read();
            
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3);
            System.out.println(s4);
            System.out.println(read);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//上述是一个一个读取,因此需要改进

改进样例,使得一次输出全部

public class Demo2 {
    public static void main(String[] args) {
        //创建字节输入流对象
        FileInputStream fis=null;
        try {
            fis=new FileInputStream("d:/a.txt");
            //如果想要输出字符
            StringBuilder s1=new StringBuilder();
            //借助循环实现一次多个读取
            int temp=0;
            while((temp=fis.read())!=-1){
                System.out.println(temp);
                s1.append((char)temp);
            }
            System.out.println(  s1.toString());
        } catch (Exception e) {

            e.printStackTrace();
        }finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//输出:
	97
	98
	99
	abc
三、File类的使用 1.file类的作用:

File是java提供的针对磁盘中的文件或目录转换文件或目录的包装类,一个file类对象可以代表一个文件或者目录,File对象可以实现获取文件和目录属性等功能,可以实现对文件和目录的创建和删除

2.File类操作目录与文件的常用方法 2.1针对文件的操作方法
  • creatNewFile():创建新文件
  • delete():直接从磁盘上删除
  • excits():查询磁盘中文件是否存在
  • getAbsoultPath():获取绝对路径
  • getPath():获取相对路径
  • getName():获取文件名
  • isFile():判断是否是文件
  • length():查看文件中的字节数、
  • isHidden:判断抽象路径名是不是隐藏文件
2.2针对目录(文件夹)操作的方法
  • exists():查询目录是否存在
  • isDirectory:判断当前路径是否为目录
  • mkdir():创建目录
  • getParentFile():获取当前目录的父级目录
  • list():返回一个字符串数组,包含目录中的文件和目录的路径名
  • listFiles():返回一个File数组,表示用此抽象路径名表示目录中的文件
3.File类的使用
public class Demo1 {
    public static void main(String[] args) throws Exception{
        //创建一个File类对象
        File file=new File("d:/1.txt");//'/'=='\'
        //创建成功返回true,已经创建后返回false
        System.out.println(file.createNewFile());
        System.out.println(file.getAbsoluteFile());
        System.out.println(file.getName());
        //删除
        System.out.println(file.delete());
        //判断是否存在
        System.out.println(file.exists());
    }
}

public class Demo2 {
    public static void main(String[] args) {
        File file=new File("d:/newFile");
        //System.out.println(file.mkdir());//创建单级目录,若若要创建多级目录则使用mkdirs
        System.out.println(file.exists());
        System.out.println(file.getParentFile().getName());
        String[] arr=file.list();
        for(String s:arr){
            System.out.println(s);
        }
        System.out.println("----------");
        //与上面不同的是输出绝对路径
        File[] file2=file.listFiles();
        for(File f:file2){
            System.out.println(f);
        }
    }
}
输出:
true

1
2
b
----------
d:newFile1
d:newFile2
d:newFileb
四、常用流对象 1.文件字节流

FileInputStream通过字节的方式读取文件,适合读取所有类型的文件(如图像,视屏,文本)。java也提供了FileReader专门读取文本文件

FileoutStream通过字节的方式写数据到文件中,适合所有类型的文件。java也提供了FileWriter专门写入文本文件

文件字节输出流读取图片
public class Demo3 {
    public static void main(String[] args) {
        FileInputStream file=null;
        try {
             file=new FileInputStream("d:/15.jpg");
             int temp=0;
             while((temp=file.read())!=-1){
                 System.out.println(temp);
             }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(file!=null){
                try {
                    file.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

文件字节输出流将一个文件读取后重写到新的文件
public class Demo3 {
    public static void main(String[] args) {
        FileInputStream file=null;
        FileOutputStream fos=null;
        try {
            //创建文件字节输入流对象
             file=new FileInputStream("d:/15.jpg");
             //创建文件字节输出流对象
             fos=new FileOutputStream("d:/new.jpg");
             int temp=0;
             while((temp=file.read())!=-1){
                // System.out.println(temp);
                 //将读入的信息写到新的文件中
                 fos.write(temp);
             }
             //将数据从内存中写入到磁盘中
            fos.flush();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(file!=null){
                try {
                    file.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

通过缓冲区提高提高读写效率 方式一

通过创建一个指定长度的字节数组作为缓冲区,来提高IO流的读写效率,适用于读取较大图片时的缓冲区定义。如何理解呢?就好比之前运送十斤米是一粒一粒(字节)运送,现在将十斤米打包成若干份,这样就提高运送效率。

注意点:

  • 缓冲区长度一定是2的整数幂,一般情况下1024长度比较合适。
public class FileStreamBufferDemo {
    public static void main(String[] args) throws Exception {
        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
           fis=new FileInputStream("d:/15.jpg");
           fos=new FileOutputStream("d:/new.jpg");
           //创建字节数组==创建缓冲区,提高读写效率
            byte[] buff=new byte[1024];
           int temp=0;
           while((temp=fis.read(buff))!=-1){//read(数组)返回读取长度
                fos.write(buff,0,temp);//一次拿一整包(数组名,开始下标,结束结束下标)
           }
        } catch (FileNotFoundException e) {
            e.printStackTrace();

        }finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

方式二

通过创建一个字节数组作为缓冲区,但是这个数组长度使用过输入流对象的available()返回当前文件的预估长度来定义的,在读写文件时,是在一次读写操作中完成文件读写操作的。(可以理解为空间换时间,提高效率但是占用内存)

注意点:

  • 如果文件过大,那么对内存的占用也是比较大的。因此大文件使用方法一
public class FileStreamBuffer2 {
    public static void main(String[] args) {
        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
            //创建文件输入流(读取)对象
            fis=new FileInputStream("d:/15.jpg");
            fos=new FileOutputStream("d:/new1.jpg");
            byte[] buff=new byte[fis.available()];
            fos.write(buff);
            fos.flush();//将残留的数据强制输出
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(fos!=null){
                try {
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

通过字节缓冲流提高读写效率

java缓冲流实在别的流上加缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。可以提高效率。

缓冲字节流:

通过内部缓存数组提高操作流的效率

  • BufferedInputStream
  • BufferedOutStream
public class FileStreamBufferDemo3 {
    public static void main(String[] args) {
        FileInputStream fis=null;
        FileOutputStream fos=null;
        BufferedInputStream bis=null;
        BufferedOutputStream bos=null;
        try{
            fis=new FileInputStream("d:/15.jpg");
            bis=new BufferedInputStream(fis);
            fos=new FileOutputStream("d:/aa.jpg");
            bos=new BufferedOutputStream(fos);
            //缓冲区中默认长度为8192
            int temp=0;
            while((temp=bis.read())!=-1){
               bos.write(temp);
            }
            bos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流的顺序:后开的先关闭
                if(bis!=null){
                    bis.close();
                }
                if (bos!=null){
                    bos.close();
                }
                if (fos!=null){
                    bos.close();
                }
                if (fis!=null){
                    fis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

定义文件拷贝工具类
public class FileTool {
    public static void main(String[] args) {
        fileCopy("d:/15.jpg","d:/123.jpg");
    }
    public static void fileCopy(String src,String des){
        FileInputStream fis=null;
        BufferedInputStream bis=null;
        FileOutputStream fos=null;
        BufferedOutputStream bos=null;
        try{
            bis=new BufferedInputStream(new FileInputStream(src));
            bos=new BufferedOutputStream(new FileOutputStream(des));
            int temp=0;
            while((temp=bis.read())!=-1){
                bos.write(temp);
            }
            bos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(bos!=null){
                    bos.close();
                }
                if(fos!=null){
                    fos.close();
                }
                if(bis!=null){
                    bis.close();
                }
                if(fis!=null){
                    fis.close();
                }


            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}


2.文件字符流(基本与字节流格式一样) 文件字符输入流
public class Demo4 {
    public static void main(String[] args) {
        FileReader frd=null;
        try{
            //创建字符输入流对象
            frd=new FileReader("d:/a.txt");
            int temp=0;
            while((temp=frd.read())!=-1){//返回Unocode值
                System.out.println((char) temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(frd!=null){
                    frd.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

文件字符输出流
public class Demo4 {
    public static void main(String[] args) {
        FileReader frd=null;
        FileWriter fwt=null;
        try{
            //创建字符输入流对象
            frd=new FileReader("d:/a.txt");
            fwt=new FileWriter("d:/new.txt");
            int temp=0;
            while((temp=frd.read())!=-1){
                fwt.append((char)temp);
            }
            fwt.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(frd!=null){
                    frd.close();
                }
                if (fwt!=null){
                    frd.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

使用字符流实现文件的拷贝
public class Demo4 {
    public static void main(String[] args) {
        FileReader frd=null;
        FileWriter fwt=null;
        try{
            //创建字符输入流对象
            frd=new FileReader("d:/a.txt");
            fwt=new FileWriter("d:/new.txt");
            char[] buffer=new char[1024];
            int temp=0;
            while((temp=frd.read(buffer))!=-1){
                fwt.write(buffer,0,temp);
            }
            fwt.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(frd!=null){
                    frd.close();
                }
                if (fwt!=null){
                    frd.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

字符缓冲流

提高了读取文本文件的效率

  • BufferedReader
  • BufferedWriter

复制文本并添加行号的工具类

public class Demo4 {
    public static void main(String[] args) {
        copyFile("d:/a.txt","d:/new1111.txt");
    }
    public static void copyFile(String src,String des){
        BufferedReader br=null;
        BufferedWriter bw=null;
        try {
            br=new BufferedReader(new FileReader(src));
            bw=new BufferedWriter(new FileWriter(des));
            String temp="";
            int i=0;
            while ((temp=br.readLine())!=null){
                bw.write(++i+"."+temp);
                bw.newLine();//实现换行
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                bw.close();
                br.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

3.转换流

InputStreamReader/OutputStreamWriter用来实现将字节转换为字符流

  • System.in是字节流对象,代表键盘的输入,如果我们想要按行接受用户的输入,就必须使用缓冲字符流BufferReader特有的方法readLIne(),但是BufferReader的构造方法必须是一个Reader对象,这时就要使用InputStreamReader
  • System.out是字节流对象,代表输出到显示器,按行读取用户的输入后,并且要将读取的一行字符串直接显示到控制台,就需要用字符流write(String str)方法,使用OutputStreamWriter将字节流转换为字符流
public class ConvertStream {
    public static void main(String[] args) {
        BufferedReader br=null;
        BufferedWriter bw=null;
        try{
            br=new BufferedReader(new InputStreamReader(System.in));
            bw=new BufferedWriter(new OutputStreamWriter(System.out));

            //System.out.println(input);
            while(true){
                bw.write("请输入:");
                String input=br.readLine();

                if("exit".equals(input)){
                    break;
                }
                bw.write("您输入的是"+input);
                bw.newLine();
                bw.flush();
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(bw!=null){
                    bw.close();
                }
                if (br!=null){
                    br.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

通过字节流读取文本文件并添加行号

public class ConvertStream {
    public static void main(String[] args) {
        BufferedReader br=null;
        BufferedWriter bw=null;
        try{
            br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/a.txt")));
            bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/newone.txt")));
            String temp="";
            int i=0;
            while((temp=br.readLine())!=null){
                bw.write(++i+"."+temp);
                bw.newLine();
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(bw!=null){
                    bw.close();
                }
                if (br!=null){
                    br.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

4字符输出流

在Java的IO包中专门提供了用于字符输出的流对象—PrintWriter。该对象具有自动行刷新缓冲字符输入流,特点是可以按行写出字符串,并可以通过println()方法实现自动换行

public class ConvertStream {
    public static void main(String[] args) {
        BufferedReader br=null;
       PrintWriter pw=null;
        try{
           br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/a.txt")));
            pw=new PrintWriter("d:/newtwo.txt");
            String temp=null;
            int i=0;
            while((temp=br.readLine())!=null){
                pw.println(++i+"."+temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(pw!=null){
                    pw.close();
                }
                if (br!=null){
                    br.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

5.字节数组流

ByteArrayInputStream和ByteArrayOutStream经常用在需要流和数组之间转化的情况

字节数组输入流

ByteArrayInputStream是将内存中字节数组当作数据源

public class Demo5 {
    public static void main(String[] args) {
        //获取byte数组
        byte[] arr="abcdefg".getBytes();
        ByteArrayInputStream bis=null;
        StringBuilder sb=new StringBuilder();
        try{
            //该构造方法的参数是一个字节数组,这个字节数组就是数据源
            bis=new ByteArrayInputStream(arr);
            int temp=0;
            while((temp=bis.read())!=-1){
                sb.append((char)temp);
            }
            System.out.println(sb.toString());
        }finally {
            try {

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

字节数组输出流

ByteArrayOutputStream流对象是将流中的数据写入到字节数组中

package IO.File;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

public class Demo6 {
    public static void main(String[] args) {
        ByteOutputStream bos=null;
        try{
            bos=new ByteOutputStream();
            bos.write('a');
            bos.write('a');
            bos.write('a');
            bos.write('a');
            //将字节数组输出流转换为字节数组
            byte[] bytes = bos.toByteArray();
            for(int i=0;i
                System.out.println((char)bytes[i]);
            }
        }finally {
            try {

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
6.数据流

数据流将“基本数据类型与字符串类型”作为数据源,允许程序以机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型

DateInputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型

数据输出流

public class Demo7 {
    public static void main(String[] args) {
        DataOutputStream dos=null;
        try{
            dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/a.txt")));
            dos.writeChar('a');
            dos.writeInt(10);
            dos.writeDouble(Math.random());
            dos.writeBoolean(true);
            dos.writeUTF("hello world");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(dos!=null){
                    dos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

数据输入流

public class Demo7 {
    public static void main(String[] args) {
        DataInputStream dis=null;
        try{
            dis=new DataInputStream(new BufferedInputStream(new FileInputStream("d:/a.txt")));
            //读取的顺序和写入的顺序一致
            System.out.println("char "+dis.readChar());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(dis!=null){
                    dis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

7.对象流

对象的本质还是数据

java的序列化和反序列化

当两个进程远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。

对象的序列化:将java对象转换为字节序列的过程称为对象的序列化。

对象的反序列化:把字节序列恢复为java对象的过程

序列化的作用

  • 持久化
  • 网络通信

序列化涉及的类和接口

ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中

ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把他们反序列化为一个对象,并将其返回

只有实现了Serializeble接口(空接口,只起到标记作用)的类的对象才能被序列化

操作基本数据类型

//和上述操作代码类似,这里简写
//创建对象
ObjectOutputStream oos=new  ObjectOutputStream(~~~);
oos.writeInt();
...
//读取
ObjectInputStream ois=new  ObjectInputStream(~~~);
sout(ois.readInt());//按顺序
8.随机访问流

RandomAccessFile作用:

  • 实现对一个文件做读和写的操作
  • 可以访问文件的任意位置

9.File类在IO中的作用

当文件作为数据源或者目标时,可以使用File类指定文件以及文件的位置

五、Apache IO包

Apache-commons工具包提供了IOUtils/FileUtils,方便对文件和目录进行操作

FileUtils的常用方法

  • cleanDirectory:清空目录,但不删除目录

  • contentEquals:比较两个文件的内容是否相同

  • copyDierctory:将一个目录内容拷贝到另一个目录。可以通过FileFilter过滤需要拷贝的文件

  • copyFile:将一个文件拷贝到一个新地址

  • copyFileToDirectoryL将一个文件拷贝到某个目录下

  • copyInputStreamToFile:将输入流的内容拷贝某个文件

  • readFileToString:将文件内容作为字符串返回

    package IO.File;
    
    import org.apache.commons.io.FileUtils;
    
    import java.io.File;
    import java.io.IOException;
    
    public class FileUtilDemo {
        public static void main(String[] args) throws IOException {
            String s=FileUtils.readFileToString(new File("d:/a.txt"),"utf-8");
            System.out.println(s);
        }
    }
    
    

文件拷贝

package IO.File;

import org.apache.commons.io.FileUtils;

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

public class FileUtilUtilDemo2 {
    public static void main(String[] args) throws IOException {
        FileUtils.copyDirectory(new File("d:/a"), new File("E:/a"), new FileFilter() {
            //匿名内部类,实现接口
            //文件拷贝时的过滤文件

            @Override
            public boolean accept(File pathname) {
                if(pathname.isDirectory()||pathname.getName().endsWith("html")){
                    return true;
                }
                return false;
            }
        });
    }
}

IOUtil的使用

它大部分方法都是重载的

常见方法:

  • buffer:将传入的方法进行包装,变成缓冲流,并可以通过参数指定缓冲流大小

  • contentEquals:比较两个流的内容是否一致

    ····查看文档

public class IOUtilDemo {
    public static void main(String[] args) throws IOException {
        String s=IOUtils.toString(new FileInputStream("d:/a.txt"),"utf-8");
        System.out.println(s);
    }
}

六、总结

按照流的分类方向

  • 输入流:数据源到程序
  • 输出流:程序到目的地

按照流的处理数据单元分类

  • 字节流
  • 字符流

按照流的功能分类

  • 结点流:可以直接从数据源或者目的地读取数据
  • 处理流:不直接连接到数据源或者目的地,通过对其他流的处理提高程序的性能

IO的四个基本抽象类

InputStream,OutputStream,Reader,Writer

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1002855.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号