IO流基本概括(压缩流除外)

1. 字节流和字符流概要:

字节流:可以参考之前写的(普通字节流)
字符流:普通字符流;
便捷字符流:也属于字符流的一种,简单易记,缺点是不能指定编码表;
高效流:能够快速的读写数据;

2.数据输入输出流: 可以直接读写基本数据类型的流,示例代码如下;

//这是写数据,向文本文件写完记得关闭流,释放资源;
	DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));
        dos.writeInt(200);
        dos.writeBoolean(false);
        dos.writeDouble(3.14);
        dos.writeUTF("你好");
        dos.close();
//这是读数据,通过输入流实现,怎么写数据就怎么读数据,顺序不能乱;
	DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
        int i = dis.readInt();
        boolean b = dis.readBoolean();
        double v = dis.readDouble();
        String s = dis.readUTF();
        System.out.println(i);
        System.out.println(b);
        System.out.println(v);
        System.out.println(s);
        dis.close();

3. 内存操作流:只操作内存中的数据,不操作文件,起中介作用;
又可以分为三种:

  1. 操作字节数组;
  2. 操作字符数组;
  3. 操作字符串;
  		//1. 内存操作流输出流,将数据写入其维护的字节数组缓冲区;
        ByteArrayOutputStream bos = new ByteArrayOutputStream(200);
        bos.write("你好".getBytes());
        bos.write("世界".getBytes());
        bos.write("hello".getBytes());
        bos.write("world".getBytes());

        //toByteArray() 取出ByteArrayOutputStream他所维护的字节数组
        byte[] bytes = bos.toByteArray();

		//把ByteArrayOutputStream字节数组缓冲区,转成字符串
        String string = bos.toString();
        System.out.println(string);

		//创建内存操作流输入流,关联写入的字节数组缓冲区,进而读取字节数组缓冲区的数据;
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        int len=0;
        byte[] bytes1 = new byte[1024];
        
        //将缓冲区的数据通过内存操作流读出来,同时用普通输出流写入指定文件;
        FileOutputStream out= new FileOutputStream("b.txt");
        while ((len=bis.read(bytes1))!=-1){
            out.write(bytes1,0,len);
        }
		bos.close();
		bis.close();
        out.close();
        
		//2. 内存操作流之操作字符数组;
        CharArrayWriter charArrayWriter = new CharArrayWriter(200);
        charArrayWriter.write("abc");
        charArrayWriter.write("abd");
        charArrayWriter.write("abc3r");

        //将维护的字符串转换成字符数组;
        char[] chars = charArrayWriter.toCharArray();
        String s = String.valueOf(chars);
        String s1 = new String(chars);
        System.out.println(s);
        System.out.println(s1);

        //也可将写入的数据直接转换成字符串
        String string = charArrayWriter.toString();
        System.out.println(string);
		//3. 操作字符串
        StringWriter stringWriter = new StringWriter();
        stringWriter.write("aaaaa");
        stringWriter.write("aaaaa");
        stringWriter.write("aaaaa");
        stringWriter.write("aaaaa");
        stringWriter.write("aaaaa");
        stringWriter.write("aaaaa");
         //也可将写入的数据直接转换成字符串
        String string = stringWriter.toString();
        System.out.println(string);

3. 打印流:PrintStream,字节打印流& PrintWriter,字符打印流;

		//1. 字节打印流:向f.txt文本文件中写入数据;
		PrintStream printStream = new PrintStream(new File("f.txt"));
        printStream.println(200);
        printStream.println(600);
        printStream.println("abc");
        printStream.write("abc".getBytes());

        printStream.close();
		
		//** 标准输出流:向控制台打印,即向显示器打印;
		PrintStream out = System.out;
        out.println(200);//打印并换行;
        out.print(200);//打印不换行
        out.print(200);
        out.print(200);
        out.print(200);
        out.close();
		//字符打印流:参数2表示自动刷新是否开启;
PrintWriter printWriter = new PrintWriter(new FileOutputStream("f.txt"),true);
		printWriter.println("abc");
        printWriter.println("abc");
        printWriter.println("abc");
        //**注意:如果开启自动刷新,就必须使用println、printf 或 format中的一个方法,才能刷新;
        //**另外,字符流没有自动刷新的情况下,必须手动刷新;
        //printer.flush();
        
        printer.close();

4. Scanner键盘扫描输入流
nextLine();//录入数据方法;
下面为简单实例:复制文件到指定文件

		//构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。
        //Scanner扫描录入可以关联从字节输入流传入的文件
        Scanner scanner = new Scanner(new FileInputStream("MyTest.java"));
        PrintWriter writer = new PrintWriter(new FileOutputStream("MyTest234.java"), true);
        //Scanner边扫描关联文件数据,边录入数据
        while (scanner.hasNextLine()){
            String s = scanner.nextLine();//录入数据
           // System.out.println(s);
            writer.println(s);
            System.out.println(s);//打印到显示器控制台
        }
        //释放资源
        scanner.close();
        writer.close();
//**高效的流也可以关联键盘录入:
 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            System.out.println("请输入内容");
            String s = bufferedReader.readLine();//读取键盘录入的数据;
            //自己定义一个结束标记
            if ("886".equals(s)) {//若键盘录入为指定内容,结束录入;
                break;
            }
            System.out.println(s);//打印键盘录入的数据
        }

5. 随机访问流:RandomAccessFile
此流最大的特点是可读可写,创建流对象时,可以在参数二声明“rw”,即可;
此流有文件指针,可以定位到指定位置,继续读取文件数据;

//向文本文件中写入不同类型的数据
RandomAccessFile rw = new RandomAccessFile(new File("hi.txt"), "rw");
        rw.writeInt(100); //4
        rw.writeBoolean(true);
        rw.writeDouble(3.14);
        rw.writeUTF("你好");
        rw.close();

将一个mp3文件,拆分成多个小文件,再将多个小文件,合并成一个mp3文件
比如 :大海.mp3 大小是 3.8M 切成多份小的mp3 每份文件1M 切割4份,当然最后一份是 0.8M,然后将4分小的mp3文件再合并回成一首歌。

package org.westos.demo1102;

import java.io.*;
import java.util.ArrayList;

public class Test3 {
    public static void main(String[] args) throws IOException {
        //封装要拆分的源文件
        File file1 = new File("许巍 - 曾经的你.mp3");
		//封装要写入的文件夹;
        File file2 = new File("C:\\Users\\Administrator\\Desktop\\test");

        ChaiFen(file1,file2);
        HeCheng(file2);



    }

    private static void ChaiFen(File file1,File file2) throws IOException {
        long filePointer=0;
        //计算文件相对大小,可以判断需要循环几次才可将文件分别读完
        long length = file1.length();
        System.out.println((length/(1024*1024))+"MB");
        for (int i = 1; i <=length+1 ; i++) {
        	
            RandomAccessFile readfile = new RandomAccessFile(file1,"rw");
            File file = new File(file2+"\\"+i+"许巍 - 曾经的你.mp3");
            RandomAccessFile writefile = new RandomAccessFile(file, "rw");


            int len=0;

            byte[] bytes=new byte[0];
            bytes = new byte[1024*1024];
			//每次重新写出文件数据时,必须将文件指针录入到读取文件的位置;
			//并且将写的指针置0,才能写出1024KB数据;
            readfile.seek(filePointer);
            writefile.seek(0);
            len=readfile.read(bytes);
            writefile.write(bytes,0,len);
            if ((len=readfile.read())==-1) {
                break;
            }
            //录入读取到的文件指针;
            filePointer = readfile.getFilePointer();
            System.out.println(filePointer);

            writefile.close();
            readfile.close();
        }

    }

    private static void HeCheng(File file) throws IOException {

        File[] files = file.listFiles();
        ArrayList<File> list = new ArrayList<>();
        for (File f : files) {
            if (f.isFile()&&f.getName().endsWith(".mp3")){
                File filemusic = new File(file + "\\" + f.getName());
                list.add(filemusic);
            }
        }
        File[] files1 = file.listFiles();
        FileOutputStream out = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\test\\music.mp3");
        for (File f : files) {
            int len=0;
            byte[] bytes=new byte[0];
            bytes = new byte[1024*1024];
            FileInputStream in = new FileInputStream(f);
            while ((len=in.read(bytes))!=-1){
                out.write(bytes,0,len);
                out.flush();
            }
            in.close();
        }
        out.close();
        System.out.println(list);
    }
}

6. 序列化流和反序列流:将一个对象保存到文件中或将对象读取回来;

public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file = new File("data.txt");
        WriteObj(file);
        ReadObj(file);
    }

    private static void ReadObj(File file) throws IOException, ClassNotFoundException {
        //将文本文件关联序列化输入流读取
        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(file));
        //依次读取学生对象,并输出
        Object obj = objIn.readObject();
        Student student = (Student) obj;
        String name = student.getName();
        int age = student.getAge();
        System.out.println(name + "====" + age);

        obj = objIn.readObject();
        student = (Student) obj;
        name = student.getName();
        age = student.getAge();

        System.out.println(name + "====" + age);

        obj = objIn.readObject();
        student = (Student) obj;
        name = student.getName();
        age = student.getAge();

        System.out.println(name + "====" + age);
    }

    private static void WriteObj(File file) throws IOException {
        Student student = new Student();
        student.setName("张三");
        student.setAge(23);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(24);

        Student student3 = new Student();
        student3.setName("王五");
        student3.setAge(25);

        //NotSerializableException
        //将文本文件关联序列化输出流;
        ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(file));
        //将学生对象写入文本文件中;
        objOut.writeObject(student);
        objOut.writeObject(student2);
        objOut.writeObject(student3);

        objOut.close();
    }

//学生类:一个类对象,要想序列化成功,该类要实现 Serializable 这个标记接口

public class Student implements Serializable {
	 //这个类,实现了Serializable接口最好再生成一个serialVersionUID
    public static final long serialVersionUID = 8490232753105806755L;
   
    private String name;
     //transient 排除这个字段不要序列化
    //private transient int age;

   private  int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

7. 属性集合Properties:
无法指定泛型,键值都是字符串类型,继承自Hashtable集合

 		//用特有的方法,来存键值,键值的数据类型,已经规定为字符串类型
         map.setProperty("张三", "25");
        map.setProperty("王五", "26");

        //通过键找值,如果没找到返回null
        String value = map.getProperty("李四");
        System.out.println(value);

        //如果这个键没有找到对应的值,则返回默认值;参数2:就是默认值
        String value2= map.getProperty("文章","姚笛");
        System.out.println(value2);

//举例更改键对应的值:
public static void main(String[] args) throws IOException {
        //一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
        //请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
        Properties map = new Properties();

        //向文件中写入数据
        SetProperties(map);

       //修改键值对中,指定键的值
        ChangeProperties(map);


    }
    private static void ChangeProperties(Properties map) throws IOException {
        map.load(new FileInputStream("datanew.properties"));
        String property = map.getProperty("lisi");
        //获得"lisi"键对应的值后,判断值只要非空,就更改值为100
        while (property!=null){
           map.setProperty("lisi","100");
           break;
       }

        Set<Object> obj = map.keySet();
        for (Object keyobj : obj) {
            Object valueobj = map.get(keyobj);
            String key= (String) keyobj;
            String value= (String) valueobj;
            System.out.println(key+"\t"+value);
        }
    }

    private static void SetProperties(Properties map) throws IOException {
        map.setProperty("zhangsan","90");
        map.setProperty("lisi","80");
        map.setProperty("wangwu","85");
		//把对象数据通过属性集合,存在指定的文件中;
        map.store(new FileWriter("datanew.properties"),null);
    }

**顺序流SequenceInputStream **
可以将其他流逻辑串联;
它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

File file1 = new File("许巍 - 曾经的你.mp3");
        File file2 = new File("许巍 - 蓝莲花.mp3");
        File file3 = new File("许巍-歌曲大联唱.mp3");

        FileInputStream in1 = new FileInputStream(file1);
        FileInputStream in2 = new FileInputStream(file2);
        FileInputStream in3 = new FileInputStream(file3);

		//串联输入流
        SequenceInputStream allIn = new SequenceInputStream(in1, in2);
        SequenceInputStream allIn2 = new SequenceInputStream(allIn, in3);

        File targetFile = new File("C:\\Users\\Administrator\\Desktop\\test1\\歌曲合并all.mp3");
        FileOutputStream out = new FileOutputStream(targetFile);
        //将所有流所关联的文件数据依次读取,并输出写到到目标文件中去
        int len = 0;
        byte[] bytes = new byte[1024 * 8];
        while ((len = allIn2.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }

        allIn2.close();
        allIn.close();
        out.close();

同样可以吧输入流存入集合,将集合迭代器关联顺序流,同样可以完成串联复制文件;

File file1 = new File("许巍 - 曾经的你.mp3");
        File file2 = new File("许巍 - 蓝莲花.mp3");
        File file3 = new File("许巍-歌曲大联唱.mp3");

        FileInputStream in1 = new FileInputStream(file1);
        FileInputStream in2 = new FileInputStream(file2);
        FileInputStream in3 = new FileInputStream(file3);
        //将三个流对象存入集合
        Vector<FileInputStream> vector = new Vector<>();
        vector.add(in1);
        vector.add(in2);
        vector.add(in3);
        //创建集合的迭代器,迭代遍历集合中的流对象元素;
        Enumeration<FileInputStream> elements = vector.elements();
        //将迭代器对象关联进顺序流中
        SequenceInputStream all = new SequenceInputStream(elements);


    
        File targetFile = new File("歌曲合并all22222.mp3");
        FileOutputStream out = new FileOutputStream(targetFile);
        //顺序流读取迭代器进而读取集合中流对象所关联的文件,边读取边写出数据到目标文件中;
        int len = 0;
        byte[] bytes = new byte[1024 * 8];
        while ((len = all.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
        all.close();
        out.close();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值