如何在Java中声明一个无限大小/动态的字节数组?

时间:2022-05-04 21:27:51

I am declaring a byte array which is of unknown size to me as it keeps on updating, so how can I declare the byte array of infinite size/variable size?

我正在声明一个字节数组,它的大小对我来说是未知的,因为它一直在更新,所以我如何声明一个无限大小/可变大小的字节数组?

10 个解决方案

#1


7  

Arrays in Java are not dynamic. You can use list instead.

Java中的数组不是动态的。你可以用list代替。

List<Byte> list = new ArrayList<Byte>();

Due to autoboxing feature you can freely add either Byte objects or primitive bytes to this list.

由于自动装箱特性,您可以*地向这个列表添加字节对象或原始字节。

#2


8  

You cannot declare an array of infinite size, as that would require infinite memory. Additionally, all the allocation calls deal with numbers, not infinite quantities.

您不能声明一个无限大小的数组,因为这需要无限内存。此外,所有的分配调用都处理数字,而不是无限数量。

You can allocate a byte buffer that resizes on demand. I believe the easiest choice would be a ByteArrayOutputStream.

您可以分配一个字节缓冲区,根据需要调整大小。我相信最简单的选择是ByteArrayOutputStream。

ByteBuffer has an API which makes manipulation of the buffer easier, but you would have to build the resize functionality yourself. The easiest way will be to allocate a new, larger array, copy the old contents in, and swap the new buffer for the old.

ByteBuffer有一个API,可以简化对缓冲区的操作,但是您必须自己构建调整大小的功能。最简单的方法是分配一个新的、更大的数组,复制旧的内容,并将新的缓冲区替换为旧的。

Other answers have mentioned using a List<Byte> of some sort. It is worth noting that if you create a bunch of new Byte() objects, you can dramatically increase memory consumption. Byte.valueOf sidesteps this problem, but you have to ensure that it is consistently used throughout your code. If you intend to use this list in many places, I might consider writing a simple List decorator which interns all the elements. For example:

其他答案也提到了使用列表 <字节> 。值得注意的是,如果您创建了一组新的Byte()对象,您可以显著地增加内存消耗。字节。valueOf回避了这个问题,但您必须确保在整个代码中始终使用它。如果您打算在许多地方使用这个列表,我可能会考虑编写一个简单的列表decorator,它将所有的元素都进行了实习生。例如:

public class InterningList extends AbstractList<Byte>
{
    ...
    @Override
    public boolean add(Byte b) {
        return super.add(Byte.valueOf(b));
    }
    ...
}

This is not a complete (or even tested) example, just something to start with...

这不是一个完整的(甚至是经过测试的)例子,只是一个开始……

#3


2  

To define a bytearray of varying length just use the apache commons.io.IOUtils library instead of assigning manual length like

要定义不同长度的bytearray,只需使用apache common .io。IOUtils类库而不是指定手工长度

byte[] b=new byte[50];

You can pass your input stream to IOUtils function which will perform a read function on this inputstream thus byte array will have exact length of bytes as required. ex.

您可以将输入流传递给IOUtils函数,该函数将在这个inputstream上执行一个read函数,因此字节数组将具有所需的精确字节长度。前女友。

byte[] b = IOUtils.toByteArray(inpustream);

Chaos..

混乱. .

#4


1  

Your best bet is to use an ArrayList. As it resizes as you fill it.

最好的办法是使用ArrayList。当你填满它时,它的大小。

List<Byte> array = new ArrayList<Byte>();

列表 array = new ArrayList ();

#5


1  

The obvious solution would be to use an ArrayList.

显而易见的解决方案是使用ArrayList。

But this is a bad solution if you need performance or are constrained in memory, as it doesn't really store bytes but Bytes (that is, objects).

但是,如果您需要性能或内存受到限制,这是一个糟糕的解决方案,因为它实际上并不存储字节,而是存储字节(即对象)。

For any real application, the answer is simple : you have to manage yourself the byte array, by using methods making it grow as necessary. You may embed it in a specific class if needed :

对于任何真正的应用程序,答案都很简单:您必须自己管理字节数组,通过使用方法使它按需要增长。如果需要,您可以将其嵌入到特定的类中:

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;
    }
}

#6


1  

ByteArrayOutputStream will allow for writing to a dynamic byte array. However, methods such as remove, replace and insert are not available. One has to extract the byte array and then manipulate it directly.

ByteArrayOutputStream将允许写入一个动态字节数组。但是,删除、替换和插入等方法不可用。必须提取字节数组,然后直接操作它。

#7


0  

Use an ArrayList of any subtype of List

使用列表的任何子类型的ArrayList

The different implementations of List can allow you to do different things on the list (eg different traversal strategy, different performance etc)

列表的不同实现允许您在列表上做不同的事情(如不同的遍历策略、不同的性能等)

#8


0  

Initial capacity of ArrayList is 10. You can change it by ArrayList(5000). ArrayList will double it's size when needed (it will create new array and copy the old one to to the new one).

ArrayList的初始容量为10。可以通过ArrayList(5000)进行更改。ArrayList在需要时将其大小加倍(它将创建新数组并将旧数组复制到新数组)。

#9


0  

I would tweak slightly other people's answers.

我会稍微调整一下其他人的答案。

Create a LargeByteArray class to manage your array. It will have get and set methods, etc, whatever you will need.

创建一个LargeByteArray类来管理数组。它将得到和设置方法,等等,无论你需要什么。

Behind the scenes that class will use a long to hold the current length and use an ArrayList to store the contents of the array.

在幕后,该类将使用long保存当前长度并使用ArrayList存储数组的内容。

I would pick to store byte[8192] or byte[16384] arrays in the ArrayList. That will give a reasonable trade off in terms of size wasted and reduce the need for resizing.

我将选择在ArrayList中存储字节[8192]或字节[16384]数组。这将在尺寸浪费方面做出合理的权衡,并减少调整大小的需要。

You can even make the array 'sparse' ie only allocate the list.get(index/8192) entry if there is a non-zero value stored in that box.

你甚至可以让数组“稀疏”(也就是只分配list.get(index/8192)条目,如果这个框中有一个非零的值的话。

Such a structure can give you significantly more storage in some cases.

在某些情况下,这样的结构可以为您提供更多的存储空间。

Another strategy you can use is to compress the byte[] boxes after write and uncompress before read (use a LRU cache for reading) which can allow storing twice or more than available ram... Though that depends on the compression strategy.

您可以使用的另一种策略是在写入后压缩字节[]框,在读取前解压字节[]框(使用LRU缓存进行读取),这样可以存储比可用ram多两倍或更多的内存……尽管这取决于压缩策略。

After that you can look at paging some boxes out to disk...

在此之后,您可以查看将一些盒子分页到磁盘中……

That's as close to an infinite array as I can get you ;-)

那是接近一个无限的数组,我可以得到你;

#10


0  

You can make use of IOUtils from piece, as Prashant already told.

就像普拉山特已经说过的那样,你可以利用碎片中的IOUtils。

Here's a little piece from it which can solve the task (you will need IOUtils.toByteArray):

这里有一小段可以解决这个问题(你需要ioutil . 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;

}
}

#1


7  

Arrays in Java are not dynamic. You can use list instead.

Java中的数组不是动态的。你可以用list代替。

List<Byte> list = new ArrayList<Byte>();

Due to autoboxing feature you can freely add either Byte objects or primitive bytes to this list.

由于自动装箱特性,您可以*地向这个列表添加字节对象或原始字节。

#2


8  

You cannot declare an array of infinite size, as that would require infinite memory. Additionally, all the allocation calls deal with numbers, not infinite quantities.

您不能声明一个无限大小的数组,因为这需要无限内存。此外,所有的分配调用都处理数字,而不是无限数量。

You can allocate a byte buffer that resizes on demand. I believe the easiest choice would be a ByteArrayOutputStream.

您可以分配一个字节缓冲区,根据需要调整大小。我相信最简单的选择是ByteArrayOutputStream。

ByteBuffer has an API which makes manipulation of the buffer easier, but you would have to build the resize functionality yourself. The easiest way will be to allocate a new, larger array, copy the old contents in, and swap the new buffer for the old.

ByteBuffer有一个API,可以简化对缓冲区的操作,但是您必须自己构建调整大小的功能。最简单的方法是分配一个新的、更大的数组,复制旧的内容,并将新的缓冲区替换为旧的。

Other answers have mentioned using a List<Byte> of some sort. It is worth noting that if you create a bunch of new Byte() objects, you can dramatically increase memory consumption. Byte.valueOf sidesteps this problem, but you have to ensure that it is consistently used throughout your code. If you intend to use this list in many places, I might consider writing a simple List decorator which interns all the elements. For example:

其他答案也提到了使用列表 <字节> 。值得注意的是,如果您创建了一组新的Byte()对象,您可以显著地增加内存消耗。字节。valueOf回避了这个问题,但您必须确保在整个代码中始终使用它。如果您打算在许多地方使用这个列表,我可能会考虑编写一个简单的列表decorator,它将所有的元素都进行了实习生。例如:

public class InterningList extends AbstractList<Byte>
{
    ...
    @Override
    public boolean add(Byte b) {
        return super.add(Byte.valueOf(b));
    }
    ...
}

This is not a complete (or even tested) example, just something to start with...

这不是一个完整的(甚至是经过测试的)例子,只是一个开始……

#3


2  

To define a bytearray of varying length just use the apache commons.io.IOUtils library instead of assigning manual length like

要定义不同长度的bytearray,只需使用apache common .io。IOUtils类库而不是指定手工长度

byte[] b=new byte[50];

You can pass your input stream to IOUtils function which will perform a read function on this inputstream thus byte array will have exact length of bytes as required. ex.

您可以将输入流传递给IOUtils函数,该函数将在这个inputstream上执行一个read函数,因此字节数组将具有所需的精确字节长度。前女友。

byte[] b = IOUtils.toByteArray(inpustream);

Chaos..

混乱. .

#4


1  

Your best bet is to use an ArrayList. As it resizes as you fill it.

最好的办法是使用ArrayList。当你填满它时,它的大小。

List<Byte> array = new ArrayList<Byte>();

列表 array = new ArrayList ();

#5


1  

The obvious solution would be to use an ArrayList.

显而易见的解决方案是使用ArrayList。

But this is a bad solution if you need performance or are constrained in memory, as it doesn't really store bytes but Bytes (that is, objects).

但是,如果您需要性能或内存受到限制,这是一个糟糕的解决方案,因为它实际上并不存储字节,而是存储字节(即对象)。

For any real application, the answer is simple : you have to manage yourself the byte array, by using methods making it grow as necessary. You may embed it in a specific class if needed :

对于任何真正的应用程序,答案都很简单:您必须自己管理字节数组,通过使用方法使它按需要增长。如果需要,您可以将其嵌入到特定的类中:

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;
    }
}

#6


1  

ByteArrayOutputStream will allow for writing to a dynamic byte array. However, methods such as remove, replace and insert are not available. One has to extract the byte array and then manipulate it directly.

ByteArrayOutputStream将允许写入一个动态字节数组。但是,删除、替换和插入等方法不可用。必须提取字节数组,然后直接操作它。

#7


0  

Use an ArrayList of any subtype of List

使用列表的任何子类型的ArrayList

The different implementations of List can allow you to do different things on the list (eg different traversal strategy, different performance etc)

列表的不同实现允许您在列表上做不同的事情(如不同的遍历策略、不同的性能等)

#8


0  

Initial capacity of ArrayList is 10. You can change it by ArrayList(5000). ArrayList will double it's size when needed (it will create new array and copy the old one to to the new one).

ArrayList的初始容量为10。可以通过ArrayList(5000)进行更改。ArrayList在需要时将其大小加倍(它将创建新数组并将旧数组复制到新数组)。

#9


0  

I would tweak slightly other people's answers.

我会稍微调整一下其他人的答案。

Create a LargeByteArray class to manage your array. It will have get and set methods, etc, whatever you will need.

创建一个LargeByteArray类来管理数组。它将得到和设置方法,等等,无论你需要什么。

Behind the scenes that class will use a long to hold the current length and use an ArrayList to store the contents of the array.

在幕后,该类将使用long保存当前长度并使用ArrayList存储数组的内容。

I would pick to store byte[8192] or byte[16384] arrays in the ArrayList. That will give a reasonable trade off in terms of size wasted and reduce the need for resizing.

我将选择在ArrayList中存储字节[8192]或字节[16384]数组。这将在尺寸浪费方面做出合理的权衡,并减少调整大小的需要。

You can even make the array 'sparse' ie only allocate the list.get(index/8192) entry if there is a non-zero value stored in that box.

你甚至可以让数组“稀疏”(也就是只分配list.get(index/8192)条目,如果这个框中有一个非零的值的话。

Such a structure can give you significantly more storage in some cases.

在某些情况下,这样的结构可以为您提供更多的存储空间。

Another strategy you can use is to compress the byte[] boxes after write and uncompress before read (use a LRU cache for reading) which can allow storing twice or more than available ram... Though that depends on the compression strategy.

您可以使用的另一种策略是在写入后压缩字节[]框,在读取前解压字节[]框(使用LRU缓存进行读取),这样可以存储比可用ram多两倍或更多的内存……尽管这取决于压缩策略。

After that you can look at paging some boxes out to disk...

在此之后,您可以查看将一些盒子分页到磁盘中……

That's as close to an infinite array as I can get you ;-)

那是接近一个无限的数组,我可以得到你;

#10


0  

You can make use of IOUtils from piece, as Prashant already told.

就像普拉山特已经说过的那样,你可以利用碎片中的IOUtils。

Here's a little piece from it which can solve the task (you will need IOUtils.toByteArray):

这里有一小段可以解决这个问题(你需要ioutil . 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;

}
}