Java将大文件逐块读入字节数组

Java将大文件逐块读入字节数组,java,Java,所以我一直在尝试制作一个小程序,将一个文件输入到一个字节数组中,然后将该字节数组转换为十六进制,然后是二进制。然后,它将处理二进制值(我还没有想到在进入这个阶段时该怎么做),然后将其保存为自定义文件 我研究了很多互联网代码,我可以将一个文件转换成字节数组和十六进制,但问题是我无法将大型文件转换成字节数组(内存不足) 这不是一个完全失败的代码 public void rundis(Path pp) { byte bb[] = null; try { bb = Fi

所以我一直在尝试制作一个小程序,将一个文件输入到一个字节数组中,然后将该字节数组转换为十六进制,然后是二进制。然后,它将处理二进制值(我还没有想到在进入这个阶段时该怎么做),然后将其保存为自定义文件

我研究了很多互联网代码,我可以将一个文件转换成字节数组和十六进制,但问题是我无法将大型文件转换成字节数组(内存不足)

这不是一个完全失败的代码

public void rundis(Path pp) {
    byte bb[] = null;

    try {
        bb = Files.readAllBytes(pp); //Files.toByteArray(pathhold);
        System.out.println("byte array made");
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (bb.length != 0 || bb != null) {
        System.out.println("byte array filled");
        //send to method to turn into hex
    } else {
        System.out.println("byte array NOT filled");
    }

}
我知道这个过程应该如何进行,但我不知道如何正确地编写代码

如果您感兴趣,请执行以下过程:

  • 使用
    文件
  • 将文件逐块读取到字节数组中。例如,每个字节数组记录可容纳600个字节
  • 发送要转换为十六进制值的块-->
    Integer.tohexstring
  • 将十六进制值块发送到二进制值-->
    Integer.toBinarystring
  • 乱搞二进制值
  • 逐行保存到自定义文件
问题::我不知道如何将一个大文件逐块转换为字节数组进行处理。
感谢您阅读:)

要使用FileInputStream将您的输入分块,请执行以下操作:

    Path pp = FileSystems.getDefault().getPath("logs", "access.log");
    final int BUFFER_SIZE = 1024*1024; //this is actually bytes

    FileInputStream fis = new FileInputStream(pp.toFile());
    byte[] buffer = new byte[BUFFER_SIZE]; 
    int read = 0;
    while( ( read = fis.read( buffer ) ) > 0 ){
        // call your other methodes here...
    }

    fis.close();

要流式传输文件,您需要远离
文件.readAllBytes()
。对于小文件来说,这是一个很好的实用程序,但是正如您所注意到的,对于大文件来说,它并没有那么多

在伪代码中,它看起来像这样:

while there are more bytes available
    read some bytes
    process those bytes
    (write the result back to a file, if needed)
在Java中,您可以使用来读取文件或。假设我们想写回处理过的字节。首先,我们打开文件:

FileInputStream is = new FileInputStream(new File("input.txt"));
FileOutputStream os = new FileOutputStream(new File("output.txt"));
我们需要
FileOutputStream
来写回我们的结果-我们不想仅仅丢弃我们宝贵的处理过的数据,对吗?接下来,我们需要一个缓冲区来保存一块字节:

byte[] buf = new byte[4096];
多少字节取决于你,我有点喜欢4096字节的块。然后我们需要实际读取一些字节

int read = is.read(buf);
这将最多读取
buf.length
字节,并将它们存储在
buf
中。它将返回读取的总字节数。然后我们处理字节:

//Assuming the processing function looks like this:
//byte[] process(byte[] data, int bytes);
byte[] ret = process(buf, read);
process()
在上面的示例中是您的处理方法。它接受一个字节数组,即它应该处理的字节数,并将结果作为字节数组返回

最后,我们将结果写回文件:

os.write(ret);
我们必须在循环中执行此操作,直到文件中没有剩余字节,因此让我们为其编写一个循环:

int read = 0;
while((read = is.read(buf)) > 0) {
    byte[] ret = process(buf, read);
    os.write(ret);
}
最后关闭溪流

is.close();
os.close();
就这样。我们以4096字节的块处理该文件,并将结果写回一个文件。如何处理结果取决于您,您也可以通过TCP发送它,甚至在不需要时删除它,或者甚至从TCP而不是文件中读取,基本逻辑是相同的

这仍然需要一些适当的错误处理来处理丢失的文件或错误的权限,但这取决于您如何实现


流程方法的示例实现:

//returns the hex-representation of the bytes
public static byte[] process(byte[] bytes, int length) {
    final char[] hexchars = "0123456789ABCDEF".toCharArray();
    char[] ret = new char[length * 2];
    for ( int i = 0; i < length; ++i) {
        int b = bytes[i] & 0xFF;
        ret[i * 2] = hexchars[b >>> 4];
        ret[i * 2 + 1] = hexchars[b & 0x0F];
    }
    return ret;
}
//返回字节的十六进制表示形式
公共静态字节[]进程(字节[]字节,整数长度){
最终字符[]hexchars=“0123456789ABCDEF.tocharray();
char[]ret=新字符[长度*2];
对于(int i=0;i>>4];
ret[i*2+1]=hexchars[b&0x0F];
}
返回ret;
}

文件有多大?大约7GB看看。然后你可以指定一次读取多少字节。如果我没有要求太多,你能举一些例子吗?甚至是一个例子的链接,我读过了,但我不知道如何准确地实现它。:)谢谢你的详细解释,男:)但是你能解释一下关于“过程(buf,read)”的部分吗。究竟什么是进程?这意味着你们的处理函数,它对字节“做一些事情”。我添加了一个示例实现,它返回字节的十六进制表示形式。这太愚蠢了,所以请自行承担帮助的风险:)我尝试将从缓冲区数组获得的值分配给另一个数组,但没有成功。谢谢你不辞辛劳地帮助男人:)编辑别帮我做我前面提到的蠢事,我会想出来的。你能具体说明我如何返回字节[]别提它。;)