zoukankan      html  css  js  c++  java
  • java之不同数据流应用举例

    按操作单位的不同分为:字节流(8bit)(InputStream、OuputStream)、字符流(16bit)(Reader、Writer)

    按数据流的流向不同分为:输入流、输出流

    按角色的不同分为:节点流、处理流

    一、不带缓冲的流

    1.文件字节输入流、文件字节输出流

    package anno;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Test2 {
        public static void main(String[] args) {
            test1FileInputStream();
            test2FileInputStream();
            testFileOutputStream();
        }
        public static  void test1FileInputStream() {
            String path = "F:\test.txt";
            try {
                FileInputStream fs = new FileInputStream(path);
                //设置一个数组接收文件的内容
                //需要注意的是,如果数组设置的太小,那么可能出现读取的数据不完整或者乱码等情况
                byte[] b = new byte[30];
                //文件输入流对象有一个返回值,返回的是读取数据的长度,如果读取到一个数据了,还会向后读一个,
                //当读取完毕时会返回-1
                int len = 0;
                while((len=fs.read(b))!=-1) {
                    //参数1是缓冲数据数组,参数2是从哪个位置开始转换成字符串,参数3是总共转换的长度
                    System.out.println(new String(b, 0, len));
                }
                fs.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static  void test2FileInputStream() {
            String path = "F:\test.txt";
            File f = new File(path);
            int l = (int) f.length();
            try {
                FileInputStream fs = new FileInputStream(path);
                byte[] b = new byte[l];
                //将读取的数据存入到b中
                fs.read(b);
                //将b转换成字符串并输出
                System.out.println(new String(b));
                fs.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static  void testFileOutputStream() {
    //如果不存在该文件,则系统会新建一个 String path1
    = "F:\test2.txt"; try { FileOutputStream fo = new FileOutputStream(path1); String str = "这是我测试的输入"; fo.write(str.getBytes());//将数据写到byte中 fo.flush();//将内存中的数据写到文件中 fo.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

    在运行的过程中会遇到一些问题,比如说设置的byte数组来接收读取的数据,如果初始化长度给的比较小,那么读取的数据就不全,在进行test1FileInputStream()的实验中,即使按照:

                int len = 0;
                while((len=fs.read(b))!=-1) {
                    //参数1是缓冲数据数组,参数2是从哪个位置开始转换成字符串,参数3是总共转换的长度
                    System.out.println(new String(b, 0, len));
                }

    进行输出,如果byte设置的还是太小,就会出现:

    这是我新建的test.txt�
    ��件

    这种乱码问题,于是进行了第二种方法的尝试,即在传入数据之前首先获得要接收多少字节的数据,然后在进行接收(借鉴之前在golang中文件读取并显示的思想),然后就没有问题了,即test2FileInputStream()。

    输出结果:

    这是我新建的test.txt文件

    2.使用字节流将一个文件复制到指定的文件夹下

    public static void copyFile() {
            String path = "F:\test.txt";
            String path2 = "F:\test2.txt";
            try {
                FileInputStream fi = new FileInputStream(path);
                FileOutputStream fo = new FileOutputStream(path2);
                File f = new File(path);
                int l = (int) f.length();
                byte[] b = new byte[l];
                int len = 0;
                while((len=fi.read(b))!=-1) {
                    fo.write(b,0,len);
                }
                fo.flush();
                fo.close();
                fi.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    综合使用之前读取的方式。

    3.文件字符输入流、文件字符输出流

    public static  void testFileReader() {
            String path = "F:\test.txt";
            try {
                FileReader fr = new FileReader(path);
    //注意这里是char类型的数组了
    char[] c = new char[20]; int len = 0; while((len=fr.read(c))!=-1) { System.out.println(new String(c, 0, len)); } fr.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void testFileWriter() { String path1 = "F:\test2.txt"; try { FileWriter fw = new FileWriter(path1); String str = "这是我测试的输入";
    //注意这里可以直接写入字符串 fw.write(str);
    fw.flush();//将内存中的数据写到文件中 fw.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    需要注意的是定义char数组时仍然是需要知道数据是有多少字符的,不然长度不够,显示不全或者写入不全。(这里暂时还未了解怎么处理)

    4.使用字符流将一个文件复制到指定的文件夹下

        public static void copyFile2() {
            String path = "F:\test.txt";
            String path2 = "F:\test2.txt";
            try {
                FileReader fr = new FileReader(path);
                FileWriter fw = new FileWriter(path2);
                char[] c = new char[30];
                int len = 0;
                while((len=fr.read(c))!=-1) {
                    fw.write(c,0,len);
                }
                fw.flush();
                fw.close();
                fr.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }

    二、带缓冲的流

    为了提高数据的读写速度,java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组。

    根据数据操作单位可以把缓冲流分为:BufferedInputStream/BufferedOutputStream和BufferedReader/BufferedWriter。

    缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了些新方法。对于输出的缓冲流,写出的数据都会先在内存中缓存,使用flush()会将在内存中的数据立即写出。

    1.缓冲字节输入流、缓冲字节输出流

    package anno;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Test4 {
        public static void main(String[] args) throws IOException {
            testBufferedInputStream();
            testBufferedOutputStream();
            copyFile();
        }
        public static void testBufferedInputStream() throws IOException {
            FileInputStream fi = new FileInputStream("F:\test.txt");
            //把文件字节输入流放入到缓冲输入流中
            BufferedInputStream bi = new BufferedInputStream(fi);
            byte[] b = new byte[35];
            int len = 0;
            while((len=bi.read(b))!=-1) {
                System.out.println(new String(b, 0, len));
            }
            bi.close();
            fi.close();
        }
        public static void testBufferedOutputStream() throws IOException {
            FileOutputStream fo = new FileOutputStream("F:\test3.txt");
            //把文件字节输入流放入到缓冲输入流中
            BufferedOutputStream bo = new BufferedOutputStream(fo);
            String str = "这是我测试的内容";
            bo.write(str.getBytes());
            bo.flush();
            bo.close();
            fo.close();
        }
        
        public static void copyFile() {
            String path = "F:\test.txt";
            String path2 = "F:\test2.txt";
            try {
                FileInputStream fi = new FileInputStream(path);
                BufferedInputStream bi = new BufferedInputStream(fi);
                FileOutputStream fo = new FileOutputStream(path2);
                BufferedOutputStream bo = new BufferedOutputStream(fo);
                File f = new File(path);
                int l = (int) f.length();
                byte[] b = new byte[l];
                int len = 0;
                while((len=bi.read(b))!=-1) {
                    bo.write(b,0,len);
                }
                bo.flush();
                bo.close();
                fo.close();
                bi.close();
                fi.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }

    2.缓冲字符输入流、缓冲字符输出流

    package anno;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Test3 {
        
        public static void main(String[] args) {
            testBufferedReader();
            testBufferedWriter();
            copyFile();
        }
        
        public static  void testBufferedReader() {
            String path = "F:\test.txt";
            try {
                FileReader fr = new FileReader(path);
                BufferedReader br = new BufferedReader(fr);
                char[] c = new char[17];
                int len = 0;
                while((len=br.read(c))!=-1) {
                    System.out.println(new String(c, 0, len));
                }
                br.close();
                fr.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static  void testBufferedWriter() {
            String path1 = "F:\test2.txt";
            try {
                FileWriter fw = new FileWriter(path1);
                BufferedWriter bw = new BufferedWriter(fw);
                String str = "这是我测试的输入";
                bw.write(str);//将数据写到chars中
                bw.flush();//将内存中的数据写到文件中
                bw.close();
                fw.close();//关闭
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void copyFile() {
            String path = "F:\test.txt";
            String path2 = "F:\test2.txt";
            try {
                FileReader fr = new FileReader(path);
                BufferedReader br = new BufferedReader(fr);
                FileWriter fw = new FileWriter(path2);
                BufferedWriter bw = new BufferedWriter(fw);
                char[] c = new char[30];
                int len = 0;
                while((len=br.read(c))!=-1) {
                    bw.write(c,0,len);
                }
                bw.flush();
                bw.close();
                fw.close();
                br.close();
                fr.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    
    }

    三、转换流:用于字节流和字符流之间的转换

    java Api提供了两个转换流:InputStreamReader和OutputSreamWriter。

    当字节流中的数据都是字符时,转换成字符流操作更高效

    package anno;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    
    public class Test5 {
        public static void main(String[] args) throws IOException {
            testInputStreamReader();
            testOutputStreamWriter();
        }
        public static void testInputStreamReader() throws IOException {
            FileInputStream fi = new FileInputStream("F:\test.txt");
            //字节流转换成字符流
            //注意转换成的编码要和读取的文件一致
            InputStreamReader ir = new InputStreamReader(fi,"utf-8");
            char[] c = new char[17];
            int len = 0;
            while((len=ir.read(c))!=-1) {
                System.out.println(new String(c, 0, len));
            }
            ir.close();
            fi.close();
        }
        public static void testOutputStreamWriter() throws IOException {
            FileOutputStream fo = new FileOutputStream("F:\test3.txt");
            //转换字节输出流为字符输出流
            OutputStreamWriter ow = new OutputStreamWriter(fo,"utf-8");
            String str = "这是我测试的内容";
            ow.write(str);
            ow.flush();
            ow.close();
            fo.close();
        }
        
        public static void copyFile() {
            String path = "F:\test.txt";
            String path2 = "F:\test2.txt";
            try {
                FileInputStream fi = new FileInputStream(path);
                BufferedInputStream bi = new BufferedInputStream(fi);
                FileOutputStream fo = new FileOutputStream(path2);
                BufferedOutputStream bo = new BufferedOutputStream(fo);
                File f = new File(path);
                int l = (int) f.length();
                byte[] b = new byte[l];
                int len = 0;
                while((len=bi.read(b))!=-1) {
                    bo.write(b,0,len);
                }
                bo.flush();
                bo.close();
                fo.close();
                bi.close();
                fi.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }

    四、标准输入输出流

    package anno;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Test6 {
        public static void main(String[] args) throws IOException {
    //        testSystemIn();
            testWriterToTxt();
        }
        public static void testSystemIn() throws IOException {
            //创建一个获取键盘输入的输入流
            InputStreamReader ir = new InputStreamReader(System.in);
            //将输入流放在缓冲中
            BufferedReader br = new BufferedReader(ir);
            String str = "";
            while((str = br.readLine())!=null) {
                System.out.println(str);
            }
        }
        //将控制台的输入写入到txt文件中
        public static void testWriterToTxt() throws IOException {
            //创建一个获取键盘输入的输入流
            InputStreamReader ir = new InputStreamReader(System.in);
            //将输入流放在缓冲中
            BufferedReader br = new BufferedReader(ir);
            BufferedWriter bw = new BufferedWriter(new FileWriter("F:\test5.txt"));
            String line = "";
            while((line = br.readLine())!=null) {
                if (line.equals("over")) {
                    break;
                }
                bw.write(line);
            }
            bw.flush();
            bw.close();
            br.close();
            ir.close();
        }
    }

    五、数据流

    package anno;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Test7 {
        public static void main(String[] args) throws IOException {
            testDataOutputStream();
            testDataInputStream();
        }
        //用数据输出流写到文件中的基本类型数据是乱码,不能辨认出来,需要数据输入流读取
        public static void testDataOutputStream() throws IOException {
            DataOutputStream ds = new DataOutputStream(new FileOutputStream("F:\test6.txt"));
            ds.writeDouble(1.35d);
            ds.flush();
            ds.close();
        }
        public static void testDataInputStream() throws IOException {
            DataInputStream ds = new DataInputStream(new FileInputStream("F:\test6.txt"));
            System.out.println(ds.readDouble());
            ds.close();
        }
    }

    六、对象流

    用于存储和读取对象的处理流,它的强大之处就是可以把java中对象写入到数据源中,也能把对象从数据源中还原出来。

    序列化:用ObjectOutputStream类将一个对象下入io流中;

    反序列化:用ObjectInputStream类从io流中恢复对Java对象;

    package anno;
    
    import java.io.Serializable;
    
    public class Person implements Serializable{
        //用来标识的UID
        private static final long serialVersionUID = 1L;
        String name;
        int age;
    }
    package anno;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    public class Test8 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
    //        testSerializable();
            testDeSerializable();
        }
        //序列化
        public static void testSerializable() throws IOException {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("F:\test7.txt"));
            Person p = new Person();
            p.name = "tom";
            p.age = 12;
            oos.writeObject(p);
            oos.flush();
            oos.close();
        }
        //反序列化
        public static void testDeSerializable() throws IOException, ClassNotFoundException {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("F:\test7.txt"));
            Person p = null;
            Object obj = null;
            obj = ois.readObject();
            p = (Person) obj;
            System.out.println(p.name);
            System.out.println(p.age);
            ois.close();
        }
    }

    七、RandomAccessFile

    支持随机访问的方式,程序可以直接跳转到文件的任意位置地方来进行读写。支持只访问文件的部分内容,可以向已存在的文件后追加内容。

    RandomAccessFile对象包含一个记录指针,用以标记当前读写的位置。

    RandomAccessFile类对象可以自由地移动和记录指针:

    • long getFilePoint():获取文件记录指针的当前位置;
    • void seek(long pos):将文件记录指针移动到指定位置;
    package anno;
    
    import java.io.IOException;
    import java.io.RandomAccessFile;
    
    public class Test9 {
        public static void main(String[] args) throws IOException {
    //        testRandomAccessFileRead();
            testRandomAccessFileWrite();
        }
        public static void testRandomAccessFileRead() throws IOException {
            //构造方法有两个参数,参数一为路径,参数二为访问方式
            //r:只读
            //rw:可写可读
            //rwd:可写可读,同步内容跟新
            //rws:可写可读,同步内容和元数据跟新;
            RandomAccessFile acf = new RandomAccessFile("F:\test7.txt","r");
            //设置文件起始的读取位置
            acf.seek(5);
            byte[] b = new byte[35];
            int len = 0;
            while((len=acf.read(b))!=-1) {
                System.out.println(new String(b, 0, len));
            }
            acf.close();
        }
        public static void testRandomAccessFileWrite() throws IOException {
            //构造方法有两个参数,参数一为路径,参数二为访问方式
            //r:只读
            //rw:可写可读
            //rwd:可写可读,同步内容跟新
            //rws:可写可读,同步内容和元数据跟新;
            RandomAccessFile acf = new RandomAccessFile("F:\test7.txt","rw");
            //设置文件起始的写入位置,0代表开头,acf.length代表文件末尾
            acf.seek(acf.length());
            acf.write("你好".getBytes());
            acf.close();
        }
    }

    总结:

    流适用于处理数据的。

    处理数据时,一定要明确数据源,与数据目的地:数据源可以是文件,也可以是键盘;数据目的地可以是文件、显示器或其它设备。

    流只是帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。

  • 相关阅读:
    MySQL主从复制搭建
    CSS基本样式简单介绍
    前端代码编码规范
    Markdown语法简单介绍
    Java API 操作Redis
    Java API 操作Zookeeper
    MySQL优化
    ES 可视化工具
    消息队列MQ
    Docker基础
  • 原文地址:https://www.cnblogs.com/xiximayou/p/12069691.html
Copyright © 2011-2022 走看看