如何在JAVA中从循环中的文件中读取固定数量的字节?

如何在JAVA中从循环中的文件中读取固定数量的字节?,java,file,file-io,filereader,Java,File,File Io,Filereader,我必须读一个fie,在每次迭代中,我必须从文件中读取8个字节。例如,在第一次迭代中,我将读取前8个字节,在第二次迭代中读取下8个字节,依此类推。如何在Java中实现这一点 public static byte[] toByteArray(File file) { long length = file.length(); byte[] array = new byte[length]; InputStream in = new FileInputStream(file);

我必须读一个fie,在每次迭代中,我必须从文件中读取8个字节。例如,在第一次迭代中,我将读取前8个字节,在第二次迭代中读取下8个字节,依此类推。如何在Java中实现这一点

public static byte[] toByteArray(File file) {
    long length = file.length();
    byte[] array = new byte[length];
    InputStream in = new FileInputStream(file);
    long offset = 0;
    while (offset < length) {
        int count = in.read(array, offset, (length - offset));
        offset += length;
    }
    in.close();
    return array;
}
公共静态字节[]toByteArray(文件){
long length=file.length();
字节[]数组=新字节[长度];
InputStream in=新文件InputStream(文件);
长偏移=0;
while(偏移量<长度){
int count=in.read(数组,偏移量,(长度-偏移量));
偏移量+=长度;
}
in.close();
返回数组;
}

我发现了这一点,但我认为这段代码所做的是完全读取一个文件并生成文件数据的字节数组。但是我只需要在一次迭代中准备好所需的字节数。

您可以轻松地根据需要调整代码:添加一个偏移量和计数,然后调用
跳过
以跳过初始的
N
字节,如下所示-

public static byte[] toByteArray(File file, long start, long count) {
      long length = file.length();
      if (start >= length) return new byte[0];
      count = Math.min(count, length - start);
      byte[] array = new byte[count];
      InputStream in = new FileInputStream(file);
      in.skip(start);
      long offset = 0;
      while (offset < count) {
          int tmp = in.read(array, offset, (length - offset));
          offset += tmp;
      }
      in.close();
      return array;
}
公共静态字节[]toByteArray(文件文件、长启动、长计数){
long length=file.length();
如果(开始>=长度)返回新字节[0];
count=Math.min(count,length-start);
字节[]数组=新字节[计数];
InputStream in=新文件InputStream(文件);
in.跳过(开始);
长偏移=0;
while(偏移量<计数){
int tmp=in.read(数组,偏移量,(长度-偏移量));
偏移量+=tmp;
}
in.close();
返回数组;
}
对于这种类型的处理,请使用:

  private void process(File file) throws IOException {
    try (RandomAccessFile data = new RandomAccessFile(file, "r")) {
      byte[] eight = new byte[8];
      for (long i = 0, len = data.length() / 8; i < len; i++) {
        data.readFully(eight);
        // do something with the 8 bytes
      }
    }
  }
private void进程(文件)引发IOException{
try(RandomAccessFile数据=新的RandomAccessFile(文件,“r”)){
字节[]八=新字节[8];
for(long i=0,len=data.length()/8;i

我使用了a,但a是一种常见的替代方法。

将代码分成小块,例如,要读取一个字节块(在您的示例中为8个字节),您需要知道3件事:

  • 在哪个文件中读取
  • 从哪里开始阅读
  • 要读取的字节数/块大小
  • 将此视为一个步骤将为您提供一个返回byte[]数组的方法,将上述3点作为参数,例如:

    private byte[] readByteBlock(InputStream in, int offset, int noBytes) throws IOException {
        byte[] result = new byte[noBytes];
        in.read(result, offset, noBytes);
        return result;
    }
    
    public byte[][] toByteArray(File file, int byteBlockSize) throws IOException {
    
        InputStream in = new FileInputStream(file);
        long noOfBlocks = (long) Math.ceil((double)file.length() / (double)byteBlockSize);
        byte[][] result = new byte[(int)noOfBlocks][byteBlockSize];
        int offset = 0;
        for(int i = 0; i < result.length; i++) {
            result[i] = readByteBlock(in, offset, byteBlockSize);
        }
        return result;
    }
    
    下一步是,打开文件并为文件中的每个字节块调用此方法。从位置0开始读取文件,调用该方法一次,对结果进行处理,然后在位置=(previousPos)+blockSize处调用它。这段代码可以放在另一个方法中,例如:

    private byte[] readByteBlock(InputStream in, int offset, int noBytes) throws IOException {
        byte[] result = new byte[noBytes];
        in.read(result, offset, noBytes);
        return result;
    }
    
    public byte[][] toByteArray(File file, int byteBlockSize) throws IOException {
    
        InputStream in = new FileInputStream(file);
        long noOfBlocks = (long) Math.ceil((double)file.length() / (double)byteBlockSize);
        byte[][] result = new byte[(int)noOfBlocks][byteBlockSize];
        int offset = 0;
        for(int i = 0; i < result.length; i++) {
            result[i] = readByteBlock(in, offset, byteBlockSize);
        }
        return result;
    }
    
    在上面的示例代码中,字节[][]数组初始化如下:

    long noOfBlocks = (long) Math.ceil((double)file.length() / (double)byteBlockSize);
    byte[][] result = new byte[noOfBlocks][byteBlockSize];
    

    因此,块数是文件中的总字节数除以字节块的大小(在您的示例中为8)。假设文件有9个字节,块大小为8,则结果为1,sth,取整为1,因此最后一个字节没有空间,这就是为什么使用Math.ceil()取整为除法给出的任何值。Math.ceil(9/8)->2,这两个值足以容纳8字节的第一个块,以及第二个块中的最后一个字节。

    您可以使用以下代码读取具有起始偏移量和大小的内存块:

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class FileReadingUtilities
    {
        public static byte[] readBytes(String file, int start, int size) throws IOException
        {
            Path filePath = Paths.get(file);
            long fileSize = Files.size(filePath);
    
            if(start < 0)
            {
                throw new IllegalArgumentException("The start may not be negative!");
            }
    
            if(size < 0)
            {
                throw new IllegalArgumentException("The size may not be negative!");
            }
    
            if (start + size > fileSize)
            {
                throw new IllegalArgumentException("Interval exceeds file size!");
            }
    
            byte[] readBytes = new byte[size];
    
            try (InputStream inputStream = new FileInputStream(filePath.toFile()))
            {
                long actuallySkipped = inputStream.skip(start);
    
                if (start != actuallySkipped)
                {
                    throw new IllegalStateException("Error while skipping bytes ahead!");
                }
    
                int bytesReadCount = inputStream.read(readBytes, 0, size);
                if (bytesReadCount != size)
                {
                    throw new IllegalStateException("Not enough bytes have been read!");
                }
            }
    
            return readBytes;
        }
    }
    

    可以使用its方法从访问字节数组。

    未能检查读取的返回值是一个缺陷。您不能假设它总是填充缓冲区。请参阅:尝试读取多达len字节的数据,但可能会读取较小的数据。如果使用公共int-read(byte[]b,int-off,int-len)来读取少于可用“len”字节的数据,则上次读取字节后b中的元素不会受到影响(0)。由于总长度已知,因此可以计算要读取的最后一个字节,并忽略其他字节。该代码并非用于作为最终完美解决方案进行复制和粘贴;)所以,是的,如果,如果你有一个9字节的文件,读块为8,那么第二个字节[]将有8个元素,最后7个元素不代表文件内容。谢谢。并将该字节数组转换为字符串:string str=new string(array);在不知道编码的情况下将字节转换为字符串是一个非常糟糕的主意。你能解释一下你的答案而不仅仅是放代码片段吗?为什么不只是使用
    文件。readAllBytes
    public static void main(String[] args) {
       File dir = new File("C:\\");
       int fixedNumber = n;
       if (dir.isDirectory()) {
          for (String file : dir.list()) {
             int sum = sumByteArray(new File(dir.getAbsoluteFile() + "\\" + file),fixedNumber);
          }
       }
    }
    
    private static int sumByteArray(File file, int fixedNumber) {
       FileInputStream fileInputStream = null;
       byte[] bFile = new byte[fixedNumber];
       int sum = 0;
       try {
          fileInputStream = new FileInputStream(file);
          fileInputStream.read(bFile);
          fileInputStream.close();
          for (Byte b : bFile) {
             sum += (int) b;
          }
       } 
       catch (Exception e) {
          e.printStackTrace();
       }
       return sum;
    }