簡體   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