繁体   English   中英

字节[]的一种更节省内存的方式是什么?

[英]What's a more memory-efficient way of taking part of a byte[]?

我有一个立体声音频数据的ByteArrayOutputStream 目前,我正在这样做,我知道这很糟糕:

WaveFileWriter wfw = new WaveFileWriter();
AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 1, 2, 44100, false);
byte[] audioData = dataout.toByteArray(); //bad bad bad
int length = audioData.length;
byte[] monoData = new byte[length/2]; //bad bad bad
for(int i = 0; i < length; i+=4){
    monoData[i/2] = audioData[i];
    monoData[1+i/2] = audioData[i+1];
}
ByteArrayInputStream bais = new ByteArrayInputStream(monoData);
AudioInputStream outStream = new AudioInputStream(bais,format,length);

wfw.write(outStream, Type.WAVE,output);

有什么更好的方法? 我可以将ByteArrayOutputStream转换为ByteArrayInputStream以便从中读取吗?

编辑

好的,所以我深入研究了正在使用的ByteArrayOutputStream的类。 正在使用以下命令进行填充:

dataout.write(convbuffer, 0, 2 * vi.channels * bout);

如果有帮助,我可以将其换成其他东西,但是我应该使用什么呢?

我尝试将其替换为:

for(int j = 0;j < bout; j += 2){
  dataout.write(convbuffer,2*j,2);
}

但这不起作用,不确定为什么。

您不能一次读取一个样本的音频数据,然后在读取样本时将其写入文件吗?

同样,您当前的代码似乎毫无意义地覆盖了monoData —感谢您的纠正,@ fredley。

首先用简单的英语陈述你在做什么; 这将帮助您理解它, 然后转向代码。

这是我用的,而不是普通的ByteArrayOutputStream。 您会得到一个方便的toByteArrayInputStream() + toByteBuffer() (我倾向于使用很多ByteBuffer)

希望许多人可以找到下面的代码有用,某些方法已从原始类中删除。

干杯!

public class ByteBufStream extends ByteArrayOutputStream implements Serializable{
    private static final long serialVersionUID = 1L;

  public ByteBufStream(int initSize){
    super(initSize);
  }
//+few more c-tors, skipped here

  public ByteArrayInputStream toByteArrayInputStream(){
    return new ByteArrayInputStream(getBuf(),0, count);
  }

  public ByteBuffer toByteBuffer(){
    return ByteBuffer.wrap(getBuf(), 0 , count);
  }

  public int capacity(){
    return buf.length;
  }


  public byte[] getBuf(){
    return buf;
  } 



    public final int size() {
        return count;
    }
    private void writeObject(java.io.ObjectOutputStream out)  throws java.io.IOException{
        out.defaultWriteObject();
        out.writeInt(capacity());
        out.writeInt(size());

        writeTo(out);
    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
        in.defaultReadObject();
        int capacity = in.readInt();
        int size = in.readInt();
        byte[] b = new byte[capacity];
        for (int n=0;n<size;){
            int read = in.read(b, n, size-n);
            if (read<0) throw new StreamCorruptedException("can't read buf w/ size:"+size);
            n+=read;
        }
        this.buf = b;
        this.count = size;
    }

}

虽然我通常不讲授技巧,但这一技巧可能无害,玩得开心!

如果要从普通的ByteArrayOutputStream中窃取buf [],请查看以下方法...

public synchronized void writeTo(OutputStream out) throws IOException {
    out.write(buf, 0, count);
}

我想您知道您现在需要做什么:

class ByteArrayOutputStreamHack extends OutputStream{
  public ByteArrayInputStream in;
  public void write(byte b[], int off, int len) {
    in = new ByteArrayInputStream(b, off, len);
  }
  public void write(int b){
   throw new AssertionError();
  }
}
ByteArrayOutputStreamHack hack = new ByteArrayOutputStreamHack()
byteArrayOutputStream.writeTo(hack);
ByteArrayInputStream in = hack.in; //we done, we cool :)

new ByteArrayInputStream(dataout.toByteArray())吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM