在Java中使用BufferedOutputStream

在Java中使用BufferedOutputStream,java,Java,最近,我一直在学习java中的文件I/O,我逐渐了解到,缓冲流使整个过程更加高效,它间歇性地存储数据,并且仅在缓冲区已满时才向磁盘写入(或读取) 现在,我有一个程序,其中有一个256的ArrayList布尔值和一个浮点值。 我正在尝试序列化此数据(我不希望简单地以人类可读的形式编写数据)。 因此,我目前所做的是将一个FileOutputStream链接到一个ObjectOutputStream,并使用其writeObject()方法首先写入boolean数组,然后写入float变量。当使用Fil

最近,我一直在学习java中的文件I/O,我逐渐了解到,缓冲流使整个过程更加高效,它间歇性地存储数据,并且仅在缓冲区已满时才向磁盘写入(或读取)

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

现在,由于我很好奇如何在这里使用
BufferedOutputStream
,我浏览了一下,但是它的两个重载写方法对我来说似乎不够灵活-

  • 第一个,它使用一个字节数组和多个参数来表示偏移量和长度
  • 第二个,需要一个字节
  • 那么,这是否意味着我必须将我的
    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);
                }
            }
        }
    
    公共类MySaveListener实现ActionListener{//顺便说一下,这是一个内部类
    已执行的公共无效操作(操作事件ev){
    JFileChooser fileSave=新的JFileChooser();
    显示保存对话框(框架);
    保存文件(fileSave.getSelectedFile());
    }
    }
    私有void保存文件(文件){
    boolean[]checkboxState=新布尔值[256];
    对于(int i=0;i<256;i++){
    JCheckBox check=(JCheckBox)checkboxList.get(i);
    if(检查.isSelected()){
    checkboxState[i]=真;
    }
    }
    试一试{
    FileOutputStream fileStream=新的FileOutputStream(文件);
    ObjectOutputStream os=新的ObjectOutputStream(文件流);
    os.writeObject(checkboxState);
    os.writeObject(1239.87f);
    os.close();
    }catch(异常ex){ex.printStackTrace();}
    }
    公共类MyLoadListener实现ActionListener{
    已执行的公共无效操作(操作事件ev){
    JFileChooser fileOpen=新的JFileChooser();
    文件打开。显示打开对话框(框架);
    加载文件(fileOpen.getSelectedFile());
    }
    }
    私有void加载文件(文件){
    布尔[]checkboxState=null;
    试一试{
    FileInputStream fileIn=新的FileInputStream(文件);
    ObjectInputStream is=新的ObjectInputStream(fileIn);
    checkboxState=(布尔[])为.readObject();
    float loadTempo=(float)是.readObject();
    is.close();
    }catch(异常ex){ex.printStackTrace();}
    对于(int i=0;i<256;i++){
    JCheckBox check=(JCheckBox)checkboxList.get(i);
    如果(复选框状态[i]){
    选中。设置为选中(true);
    }
    否则{
    检查。选择设置(假);
    }
    }
    }
    

    那么,为了利用
    BufferedOutputStream
    BufferedInputStream
    ,我必须在这里进行哪些更改?

    您对缓冲的理解是不正确的。如果您正在执行低效的写入/读取操作(例如逐行读取和处理),而不是试图以尽可能快的速度从流中读取数据,则流和写入/读取缓冲区非常有用。在写入方面,它意味着在一次调用中发送完整的消息,而不是在发送数据之前进行多次写入调用。如果你正在进行高效的读写,你不需要缓冲区


    至于如何序列化的问题:对象流很容易使用,但最终会留下不兼容的数据。如果您想让序列化达到最佳效果,我建议您将布尔值[]转换为字节[],您可以通过常规输出流写入该字节

    是的,我现在所做的工作正常。不过,我希望能做得更好。另外,由于方法的签名只允许字节数组,您能详细说明我如何使用布尔值吗?不要查看DataOutputStream。这是一个仅限Java的传输协议,现在已经过时几十年了。我如何使用BufferedOutputStream存储浮点变量?将其转换为字节不会导致数据丢失吗?@Ayush