美文网首页
java IO 流

java IO 流

作者: bigpeng个人博客 | 来源:发表于2018-07-16 13:04 被阅读11次

    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 流

          本文链接:https://www.haomeiwen.com/subject/adnasftx.html