Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一次将文件的一部分作为字节[]获取_Java_Android_File_Stream_Bytearray - Fatal编程技术网

Java 一次将文件的一部分作为字节[]获取

Java 一次将文件的一部分作为字节[]获取,java,android,file,stream,bytearray,Java,Android,File,Stream,Bytearray,我试图一次处理10MB字节数组的大文件。 我试图一次获取一个字节数组(不是获取大文件的整个字节数组,而是拆分字节数组,毕竟问题是内存造成的) 这就是我到目前为止所做的: private byte[] readFile(File file, int offset) throws IOException { BufferedInputStream inStream = null; ByteArrayOutputStream outStream = null; byte[] b

我试图一次处理10MB字节数组的大文件。 我试图一次获取一个字节数组(不是获取大文件的整个字节数组,而是拆分字节数组,毕竟问题是内存造成的)

这就是我到目前为止所做的:

private byte[] readFile(File file, int offset) throws IOException
{
    BufferedInputStream inStream = null;
    ByteArrayOutputStream outStream = null;
    byte[] buf = new byte[1048576];
    int read = 0;

    try
    {
        inStream = new BufferedInputStream(new FileInputStream(file));
        outStream = new ByteArrayOutputStream();
        long skipped = inStream.skip(offset);
        read = inStream.read(buf);
        if (read != -1)
        {
            outStream.write(buf, 0, read);
            return outStream.toByteArray();
        }
    }
    finally
    {
        if (inStream != null) {try {inStream.close();} catch (IOException e) {}}
        if (outStream != null) {try {outStream.close();} catch (IOException e) {}}
    }

    return null;
参数
offset
也将以10MB为增量

因此,我遇到的问题是,即使
skipped
long变量给了我1048576个跳过的字节,我想通过调用
readFile(file,1048576)
接收的第二个10MB与第一个10MB的第一个字节数组相同。因此,它根本没有跳过前10MB


这里有什么问题?有没有其他方法来实现这个想法?

重新设计这个方法。目前,您正在复制字节数组,就像它过时一样:一次从缓冲区复制到ByteArrayOutStream,另一次从缓冲区复制到返回值。所以你一次需要三个。更改方法的签名,以便调用者提供字节数组、偏移量和流,并让它返回计数。换句话说,完全去掉它,只需从任何调用它的地方调用FileInputStream.read(缓冲区、偏移量、长度)。

因此,根据user@EJP,我修改了代码以有效地工作。当我意识到
.tobytearrayoutputstream
实际上返回读取字节数组的副本时,我不再通过tearrayoutputstream复制到
。我也只打开一次流,这样就不需要跳过了

    int fileLength = (int) file.length();
    byte[] buffer = new byte[fileLength < FILE_UPLOAD_CHUNK_SIZE ?
            fileLength : FILE_UPLOAD_CHUNK_SIZE];
    int bytesRead;
    int readTotal = 0;
    BufferedInputStream inStream = null;
    try
    {
        inStream = new BufferedInputStream(new FileInputStream(file));
        do
        {
            bytesRead = inStream.read(buffer, 0, buffer.length);
            if (bytesRead == -1)
            {
                continue;
            }
            byte[] finalBuffer;
            if (buffer.length > bytesRead)
            {
                finalBuffer = Arrays.copyOf(buffer, bytesRead);
            }
            else
            {
                finalBuffer = buffer;
            }
            uploadChunk(
                    finalBuffer,
                    mimeType,
                    uploadPath,
                    fileLength,
                    readTotal,
                    readTotal + bytesRead - 1);
            readTotal += bytesRead;
        } while (bytesRead != -1);
    }
    finally
    {
        if (inStream != null)
        {
            inStream.close();
        }
    }
int fileLength=(int)file.length();
byte[]buffer=新字节[fileLength<文件\上传\区块\大小?
文件长度:文件\上传\区块\大小];
int字节读取;
int readTotal=0;
BufferedInputStream inStream=null;
尝试
{
inStream=new BufferedInputStream(new FileInputStream(file));
做
{
bytesRead=流内读取(缓冲区,0,缓冲区长度);
如果(字节读==-1)
{
继续;
}
字节[]finalBuffer;
if(buffer.length>字节读取)
{
finalBuffer=Arrays.copyOf(缓冲区,字节读取);
}
其他的
{
finalBuffer=缓冲区;
}
上传块(
最终缓冲,
mimeType,
上传路径,
文件长度,
readTotal,
读取总数+字节读取-1);
readTotal+=字节读取;
}while(bytesRead!=-1);
}
最后
{
如果(流内!=null)
{
流内关闭();
}
}

这段代码唯一的缺陷是,当最后一个块小于10MB时,我必须创建字节数组的新副本。应该有一种更有效的方法,但目前这对我来说还不错。

你没有用相同的数量增加偏移量,所以下一个偏移量将是2x 1048576。因此,您总是得到相同的字节。但是我正确地偏移了它,2x 1048576将是第三个块,因为第一个块的偏移量为0,对吗?因此您反复读取
文件
,并从方法外部递增
偏移量
变量?你能添加调用你的方法的代码吗?这个问题以及我选择使用输入和输出缓冲区的原因是,如果说最后一个块是5MB,我调用
FileInputStream.read(buffer,offset,length)
,长度=10MB,那么最后一个块不会返回一个只有5MB数据的10MB字节数组吗?这会影响将文件转换为json并通过http上传吗?是的,这就是为什么read()返回一个长度,这就是为什么Java中充满了带有签名(byte[],offset,length)的方法;