使用RandomAccessFile类

时间:2019-01-31 21:37:50

标签: java randomaccessfile

我需要将大文件(GB)复制到另一个文件(容器)中,我想知道性能和内存使用情况。

读取整个源文件,如下所示:

RandomAccessFile f = new RandomAccessFile(origin, "r");
originalBytes = new byte[(int) f.length()];
f.readFully(originalBytes);

然后,将所有内容复制到容器中,如下所示:

RandomAccessFile f2 = new RandomAccessFile(dest, "wr");
f2.seek(offset);
f2.write(originalBytes, 0, (int) originalBytes.length);

内存中的所有内容都正确吗?那么复制大文件会影响内存并导致内存不足异常吗?

最好逐个字节读取原始文件,而不是全部读取吗? 在这种情况下,我应该如何进行? 预先谢谢你。

编辑:

按照 mehdi maick 的回答,我终于找到了解决方案: 我可以根据需要使用RandomAccessFile作为目标,并且由于RandomAccessFile具有返回文件通道的方法“ getChannel ”,因此我可以将其传递给以下方法,该方法将复制文件(当时为32KB)文件放置在我想要的目标位置:

     public static void copyFile(File sourceFile, FileChannel destination, int position) throws IOException {
            FileChannel source = null;
            try {
                source = new FileInputStream(sourceFile).getChannel();
                destination.position(position);
                int currentPosition=0;
                while (currentPosition < sourceFile.length())
                    currentPosition += source.transferTo(currentPosition, 32768, destination);
            } finally {
                if (source != null) {
                    source.close();
                }

            }
        }

2 个答案:

答案 0 :(得分:2)

尝试使用异步nio Channel


    public void copyFile(String src, String target) {
        final String fileName = getFileName(src);
        try (FileChannel from = (FileChannel.open(Paths.get(src), StandardOpenOption.READ));
                FileChannel to = (FileChannel.open(Paths.get(target + "/" + fileName), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))) {
            transfer(from, to, 0l, from.size());
        }
    }

    private String getFileName(final String src) {
        File file = new File(src);
        if (file.isFile()) {
            return file.getName();
        } else {
            throw new RuntimeException("src is not a valid file");
        }
    }

    private void transfer(final FileChannel from, final FileChannel to, long position, long size) throws IOException {
        while (position < size) {
            position += from.transferTo(position, Constants.TRANSFER_MAX_SIZE, to);
        }
    }

这将创建一个读写异步通道,并有效地将数据从第一个传输到后面。

答案 1 :(得分:-1)

以块/块读取,例如使用Foo a bs = ('a','b','c') x = np.random.normal(5, 1, len(my_set)).round().astype(np.int) result = np.repeat(s, x) 一次64k。

如果需要提高性能,则可以尝试使用线程,一个线程用于读取,另一个线程用于写入。

您还可以使用直接NIO缓冲区来提高性能。
参见例如A simple rule of when I should use direct buffers with Java NIO for network I/O?