java IO 流

1.什么是java IO?
通过java一些列文件操作的API,对文件进行读取,写入等操作。即为java IO;这里的文件可以是文本文件,视频,音频,图片等等。

2.什么是IO流
java中操作文件的类,大多叫流(stream)。比如输入的类 InputStream(输入流),输出的类(OutputStream)。为什么叫流呢,其实很形象。比如我们水从一个地方流向一个地方,就形成了水流,而文件呢,是一堆字节。这些字节呢,从硬盘流向程序里面,就形成了一个字节流,即输入流。 而这些类更像一个水管,连接着文件与程序代码。

IO操作图解.png

3.java常用IO类
java中流按流向来分,可以分为两类:
3.1 InputStream:输入流,即将文件读入程序。(文件-->程序,是进入程序,所以为输入流);
3.2 OutputStream:输出流,即将程序中的内容,写入文件。(程序 -->文件 ,是离开程序,所以是输出流)。

4.java 输入流 InputStream
输入流对应的类是InputStream。java API中 ,这是一个抽象类。 其主要的方法有:

  • int read() :读取一个字节,并以int形式返回。
  • int read(byte b[]) :将数据读取入传入的byte数组中,即byte b[]中。返回值 int 为读取的字节的个数。返回-1则表示已经读取到了文件末尾。
  • int read(byte b[], int off, int len) 将数据读取到byte b[]中。起始位置为off,最大读取字节长度为len。
  • void close(); 关闭流。 对应的流是会占用系统资源的,当我们读取完后,需要调用close()方法,关闭流。

InputStram 是抽象类,刚才提到的这些方法大多是抽象方法。抽象类只是定义了方法的规范,具体的实现,可能还需要其子类来完成。

InputStream 常用的子类有:
1)FileInputStream: 文件输入流。
2)BufferedInputStream:缓冲输入流。

接下来我们将具体介绍这两个输入流的操作。

4.1 FileInputStream

FIleInputStream 主要用于读取文件内容。常用的两个构造方法为:
1)FileInputStream(String name) name为文件的全路径(包含文件名)
2)FileInputStream(File file) file为文件对象

代码示例:

/**
     * 测试read 方法
     * @throws IOException
     */

    @Test
    public  void read() throws IOException {
        //FileInputStram 的常用构造方法
        //1) FileInputStream(String name) name为文件的全路径(包含文件名)
        //2)FileInputStream(File file) file为文件对象
        //通过构造方法1)创建对象
        FileInputStream fileInputStream=new FileInputStream("E:/java.txt");
        //读取一个字节
        int i=fileInputStream.read();
        //内容为字节的int值
        System.out.println(i);
        //将字节转换为char ,如果他是英文的话(占一个字节),即可看到内容。
        char a=(char)i;
        System.out.println(a);
        //定义一个数组来存放读取到的字节
        byte[] bytes={};
        //通过read()方法读取全部内容
        int b=0;
        //当存在中文时,一个一个读取,然后打印就会出现乱码的情况
        while((b=fileInputStream.read())!=-1){
            System.out.println((char)b+":"+b);
            bytes=Arrays.copyOf(bytes,bytes.length+1);
            bytes[bytes.length-1]=(byte) b;
        }
        String str=new String(bytes);
        System.out.println(str);
        //关闭流
        fileInputStream.close();
    }

    /**
     * 通过read(byte[] b)一次性读取到byte[]数组中
     * @throws IOException
     */
    @Test
    public  void readByteArray() throws IOException {
        //通过构造方法2)创建对象
        File file=new File("E:/java.txt");
        FileInputStream fileInputStream=new FileInputStream(file);
        //创建字节数组来接收读取到的内容
        byte[] bytes=new byte[(int)file.length()];
        //一次性读取bytes.length个数组。
        fileInputStream.read(bytes);
        //如果编码不是当前项目编码,则指定编码格式
        System.out.println(new String(bytes,"GB2312"));
        //关闭流
        fileInputStream.close();
    }

5.java中输出流
输出流对应的java中的OutputStream。同InputStream类似,OutputStream同样是一个抽象类。主要作用就是写文件,将内容写入文件中。常见的方法有:

  • void write(int b):写入一个字节。
  • void write(byte b[]) :写入一个字节数组。
  • void write(byte b[], int off, int len):写入字节数组内容,开始位置为off,长度为len。
  • void close():关闭流。
  • void flush(): 清理缓冲内容,将内容全部写入文件。

OutputStream中常用的子类有:

  • FileOutputStream :文件输出流,用于写文件。
  • BufferedOutputStream:字节缓冲输出流。

5.1 FileOutputStream 文件输出流

代码示例:

/**
     * write方法:向文件中写单个字节
     */
    @Test
    public void write() throws IOException {
        File file=new File("E:/a.txt");
        FileOutputStream out=new FileOutputStream(file);
        //写入单个字节
        char a='a';
        out.write(a);
        out.write(97);
        out.write(98);
        char num=49;
        out.write(num);

        //写一段话的话 需要循环写
        String str="hello!你好。\n我是FileOutputStream 写入的一段话";
        byte[] bytes=str.getBytes();
        for(byte b:bytes){
            out.write(b);
        }
        //清理缓存
        out.flush();
        //关闭流
        out.close();
    }

    /**
     * 写入byte数组
     */
    @Test
    public void writeByteArray() throws IOException {

        String str="我是通过write(byte[]b)写入的内容";
        FileOutputStream fos=new FileOutputStream("E:/a.txt");
        fos.write(str.getBytes());
        fos.flush();
        fos.close();
    }

    @Test
    public void writeByArrayWidthParam() throws IOException {
        String str="我是通过write(byte[]b,int offset,int len)方法写入的内容";
        File file=new File("E:/a.txt");
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(str.getBytes(),10,str.getBytes().length-10);
        fos.flush();
        fos.close();
    }

OK! 相信通过FileInputStream 和FileOutputStream的例子呢,大家应该都大概知道了文件的输入操作,输出操作该怎么弄啦,大致的方法是什么。
我们接下来呢,就通过FileInputStream 和FileOutputStream来实现一个文件的复制操作。

public static void fileCopy(String from,String to){
        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
            fis=new FileInputStream(from);
            fos=new FileOutputStream(to);
            byte[] buffer=new byte[1024];

            int size=0;
            while((size=fis.read(buffer))!=-1){
                fos.write(buffer,0,size);
                fos.flush();
            }

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

    }

    public static void main(String[] args) {
        fileCopy("D://a//test.java","D://a//a.java");
    }

6.字符流

前面讲到的字节流,处理文本文件还是不是很方便。于是java提供了Reader和Writer。字符输入和输出流,来完善文本文件的读取与写入操作。
字符流是以字符为单位读取文件的。
6.1 InputStreamReader

public class FileReaderAndWriterTest {
    public static void readFile(String filePath){
        FileReader fr=null;
        try {

            fr=new FileReader(filePath);
            char [] buffer=new char[1024];
            int size=0;

            while ((size=fr.read(buffer))!=-1){
                for (int i=0;i<=size;i++){
                    System.out.println(buffer[i]);
                }
            }

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

    }

    public static void fileWriter(String filePath){
        FileWriter writer= null;
        try {
            writer = new FileWriter(filePath,true);
            writer.write("\r\n我是FileWriter写入的内容第三行");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void bufferedReaderTest(String path){
        BufferedReader br=null;
        try {
            br=new BufferedReader(new FileReader(path));
            String str=null;
            while ((str=br.readLine())!=null){
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (br!=null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
//        readFile("D://a//b.txt");
//        fileWriter("D://a//b.txt");
        bufferedReaderTest("D://a//b.txt");
    }
}

7.序列化与反序列化
把对象转换为字节序列的过程称为对象的序列化。
  把字节序列恢复为对象的过程称为对象的反序列化。
  对象的序列化主要有两种用途:
  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上传送对象的字节序列。

transient 修饰的属性和static修饰的属性不会被序列化

在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

  public static void serziableTest(){
        User user=new User();
        user.setName("张三");
        user.setAge(12);
        user.setBirthday(new Date());
        try {
            ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D://a//c.txt"));
            oos.writeObject(user);
            oos.writeObject(user);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void readObject() {
        try {
            FileInputStream fis = new FileInputStream("D://a//c.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            //判断是否到文件末尾
            while (fis.available() > 0) {
                User u = (User) ois.readObject();
                System.out.println(u);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        serziableTest();
        readObject();
    }

你可能感兴趣的:(java IO 流)