在Java中使用BufferedOutputStream

3

最近我在学习Java中的文件I/O,了解到缓冲流通过间歇性地存储数据,并仅在缓冲区充满时才将数据写入磁盘(或从磁盘读取)可以使整个过程更有效率。

现在,我有一个程序,其中有一个由256个布尔值和一个浮点数值组成的ArrayList
我正在尝试将这些数据序列化(我不希望简单地以人类可读的形式写入数据)。
所以我目前使用FileOutputStream链接到ObjectOutputStream,并使用它的writeObject()方法首先写入boolean数组,然后是float变量。当使用FileInputStreamObjectInputStream读取时,我也同样处理。

现在,由于我好奇如何在这里使用BufferedOutputStream,因此我查看了文档,但它拥有的两个重载写入方法对我来说似乎不够灵活-

  1. 第一个方法需要一个字节数组和一些额外的参数用于偏移和长度
  2. 第二个方法需要一个字节。

那么,这是否意味着我必须将我的boolean数组转换为字节数组才能使用BufferedOutputStream对象?那我该如何将我的浮点数转换为字节?我还不清楚如何使用BufferedInputStream读取数据。
在进行所有转换之后使用缓冲区是否值得?

以下是我的原始代码,没有使用缓冲区:

public class MySaveListener implements ActionListener { //this is an inner class by the way
        public void actionPerformed(ActionEvent ev) {
            JFileChooser fileSave = new JFileChooser();
            fileSave.showSaveDialog(theFrame);
            saveFile(fileSave.getSelectedFile());
        }
    }

private void saveFile(File file){
        boolean[] checkboxState = new boolean[256];

        for(int i = 0; i < 256; i++){
            JCheckBox check = (JCheckBox) checkboxList.get(i);
            if (check.isSelected()){
                checkboxState[i] = true;
            }
        }

        try{
            FileOutputStream fileStream = new FileOutputStream(file);
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(checkboxState);
            os.writeObject(1239.87f);
            os.close();
        } catch(Exception ex){ex.printStackTrace();}
    }

public class MyLoadListener implements ActionListener {
        public void actionPerformed(ActionEvent ev) {
            JFileChooser fileOpen = new JFileChooser();
            fileOpen.showOpenDialog(theFrame);
            loadFile(fileOpen.getSelectedFile());
        }
    }

private void loadFile(File file){
        boolean[] checkboxState = null;
        try{
            FileInputStream fileIn = new FileInputStream(file);
            ObjectInputStream is = new ObjectInputStream(fileIn);
            checkboxState = (boolean[]) is.readObject();
            float loadTempo = (float)is.readObject();
            is.close();
        } catch(Exception ex){ex.printStackTrace();}

        for(int i = 0; i < 256; i++){
            JCheckBox check = (JCheckBox) checkboxList.get(i);
            if (checkboxState[i]){
                check.setSelected(true);
            }
            else{
                check.setSelected(false);
            }
        }
    }

那么,我需要做哪些更改才能使用BufferedOutputStreamBufferedInputStream呢?


是的,我现在的代码可以工作。但是,我想让它更好。另外,您能否详细说明如何使用布尔值,因为该方法的签名仅允许使用字节数组? - Ayush
2
不要看DataOutputStream。这是一个仅适用于Java的传输协议,现在已经过时了几十年。 - ControlAltDel
1个回答

2
你对缓冲的理解有误。如果你进行低效的写入/读取,例如逐行读取和处理,那么流和Writer/Reader缓冲非常有用,而不是尽可能快地从流中读取。在写入方面,这意味着在发送数据之前进行完整的消息发送,而不是在发送数据之前进行多个写入调用。如果你正在进行高效的读写操作,你就不需要缓冲。
至于如何序列化的问题:对象流易于使用,但最终会让你拥有不兼容的数据。如果你想使序列化最优化,请将boolean[]转换为byte[],然后可以通过常规OutputStream进行写入。

如何使用BufferedOutputStream存储浮点变量?将其转换为字节是否会导致数据丢失? - Ayush
1
@Ayush https://dev59.com/9kjSa4cB1Zd3GeqPItTV - ControlAltDel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接