[英]How to Declare a Byte Array of Infinite Size/Dynamic in Java?
我聲明的字節數組在不斷更新時對我來說是未知的,那么如何聲明無限大小/可變大小的字節數組呢?
您不能聲明無限大小的數組,因為這將需要無限的內存。 此外,所有分配調用都處理數字,而不是無限數量。
您可以分配一個按需調整大小的字節緩沖區。 我相信最簡單的選擇是ByteArrayOutputStream
。
ByteBuffer
具有一個使緩沖區的操作更加容易的API,但是您必須自己構建調整大小功能。 最簡單的方法是分配一個更大的新數組,復制舊內容,並將新緩沖區替換為舊緩沖區。
其他答案提到了使用某種List<Byte>
的情況。 值得注意的是,如果創建了一堆new Byte()
對象,則可以大大增加內存消耗。 Byte.valueOf
此問題,但是您必須確保在整個代碼中始終使用它。 如果您打算在許多地方使用此列表,我可能會考慮編寫一個簡單的List
裝飾器,該裝飾器可以插入所有元素。 例如:
public class InterningList extends AbstractList<Byte>
{
...
@Override
public boolean add(Byte b) {
return super.add(Byte.valueOf(b));
}
...
}
這不是一個完整(甚至沒有經過測試)的示例,只是一些開頭...
Java中的數組不是動態的。 您可以改用列表。
List<Byte> list = new ArrayList<Byte>();
由於具有自動裝箱功能,您可以將Byte對象或原始字節自由添加到此列表中。
要定義不同長度的commons.io.IOUtils
只需使用apache commons.io.IOUtils
庫,而不是像
byte[] b=new byte[50];
您可以將輸入流傳IOUtils
函數,該函數將對該輸入流執行讀取功能,因此字節數組將具有所需的確切字節長度。 例如
byte[] b = IOUtils.toByteArray(inpustream);
混沌..
最好的選擇是使用ArrayList。 當它隨着您的填充而調整大小時。
List<Byte> array = new ArrayList<Byte>();
顯而易見的解決方案是使用ArrayList。
但是,如果您需要性能或內存受限,這將是一個糟糕的解決方案,因為它實際上並不存儲字節,而是存儲字節(即對象)。
對於任何實際應用程序,答案很簡單:您必須管理字節數組,方法是使字節數組根據需要增長。 如果需要,您可以將其嵌入特定的類中:
public class AlmostInfiniteByteArray {
private byte[] array;
private int size;
public AlmostInfiniteByteArray(int cap) {
array = new byte[cap];
size = 0;
}
public int get(int pos) {
if (pos>=size) throw new ArrayIndexOutOfBoundsException();
return array[pos];
}
public void set(int pos, byte val) {
if (pos>=size) {
if (pos>=array.length) {
byte[] newarray = new byte[(pos+1)*5/4];
System.arraycopy(array, 0, newarray, 0, size);
array = newarray;
}
size = pos+1;
}
array[pos] = val;
}
}
ByteArrayOutputStream將允許寫入動態字節數組。 但是,諸如刪除,替換和插入之類的方法不可用。 必須提取字節數組,然后直接對其進行操作。
ArrayList的初始容量為10。可以通過ArrayList(5000)進行更改。 ArrayList將在需要時將其大小加倍(它將創建新的數組並將舊的數組復制到新的數組)。
我會稍微調整其他人的答案。
創建LargeByteArray類來管理您的數組。 無論您需要什么,它都會具有get和set方法等。
在后台,該類將使用long來保持當前長度,並使用ArrayList來存儲數組的內容。
我選擇將byte [8192]或byte [16384]數組存儲在ArrayList中。 這將在浪費尺寸方面進行合理的權衡,並減少調整大小的需求。
您甚至可以使數組“稀疏”,即,如果該框中存儲的值非零,則僅分配list.get(index / 8192)條目。
在某些情況下,這種結構可以為您提供更多的存儲空間。
您可以使用的另一種策略是在寫入后壓縮byte []框,並在讀取之前解壓縮(使用LRU高速緩存進行讀取),這可以允許存儲比可用內存多兩倍或更多的內存...盡管這取決於壓縮策略。
之后,您可以查看將一些盒子分頁到磁盤上。
我可以讓你接近無限數組;-)
正如Prashant已經講過的,您可以使用塊中的IOUtils。
這是可以解決任務的一小部分(您將需要IOUtils.toByteArray):
public class IOUtils {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
copy(input, output);
return output.toByteArray();
}
public static int copy(InputStream input, OutputStream output)
throws IOException {
long count = copyLarge(input, output);
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.