标签: filechannel

Java FileChannel 的内存版本

我正在对我正在使用的库进行一些更改。为了减少内存使用,库将其临时数据写入磁盘而不是将其保存在内存中。然而,对于我的使用场景来说,将其保留在内存中会更有效。它还存在一些并发问题,因为它的临时文件具有常量名称,因此不能在不同线程中同时运行(因为线程会损坏彼此的数据)。

因此,我需要更改库,以便将所有数据保留在内存中。我最初并没有编写该库,因此我不太愿意对代码进行大幅更改。因此,我希望通过尽可能少的重构来做到这一点。写入磁盘的代码非常简单。这是一个(稍微简化的)示例:

final FileChannel fileChannel = this.randomAccessFile.getChannel();
fileChannel.position(calculatePosition());
while (blockData.hasRemaining())
{
 fileChannel.write(blockData);
}
Run Code Online (Sandbox Code Playgroud)

块的读取非常相似(即它使用从 RandomAccessFile 获取的 FileChannel)。

感觉最简单的解决方案是如果我可以使用 FileChannel 的某种实现,它映射到内存中的某个位置而不是文件。我知道我可以使用 FileChannel 的映射方法将文件映射到内存中的某个位置。然而,事实恰恰相反。这给了我一个文件的“内存API”。我想要一个针对某些内存的 FileChannel 接口。有没有可用的实现?

java nio filechannel random-access memory-mapped-files

7
推荐指数
1
解决办法
1839
查看次数

从FileChannel(Java NIO)读取GZIP文件

我需要在给定FileChannel的情况下读取/解压缩.gz文件.

我已经玩过使用GZIPInputStream提取GZIP档案,但这不会占用FileChannel.我无权访问FileChannel的原始FileInputStream.

如果有人能告诉我一个从FileChannel阅读GZIP 的好方法(或者至少是任何方式),我将非常感激.

改编自Sun Oracle论坛上的问题.

java zip gzip nio filechannel

7
推荐指数
2
解决办法
5820
查看次数

从随机访问文件中读取对象

我使用 Java 的 FileChannel 类编写了一个文件,该类使用 RandomAccessFiles。我在文件的不同位置写入了对象。这些物体大小不一,但都属于同一类别。我使用以下想法编写了对象:

ByteArrayOutputStream bos= new ByteArrayOutputStream();
        ObjectOutput out = new ObjectOutputStream(bos);
        out.writeObject(r);
        byte[] recordBytes= bos.toByteArray();

    ByteBuffer rbb= ByteBuffer.wrap(recordBytes);

    while(rbb.hasRemaining()) {
        fileChannel.write(rbb);
    }
Run Code Online (Sandbox Code Playgroud)

Run Code Online (Sandbox Code Playgroud)

现在我想读取这样的文件。我不想指定要读取的字节数。我希望能够使用对象输入流直接读取对象。如何实现这一目标?

必须使用随机访问文件,因为我需要写入文件中的不同位置。我还在一个单独的数据结构中记录对象被写入的位置。

java filechannel objectoutputstream

6
推荐指数
1
解决办法
1万
查看次数

使用FileChannel和ByteArrays读取ASCII文件

我有以下代码:

        String inputFile = "somefile.txt";
        FileInputStream in = new FileInputStream(inputFile);
        FileChannel ch = in.getChannel();
        ByteBuffer buf = ByteBuffer.allocateDirect(BUFSIZE);  // BUFSIZE = 256

        /* read the file into a buffer, 256 bytes at a time */
        int rd;
        while ( (rd = ch.read( buf )) != -1 ) {
            buf.rewind();
            for ( int i = 0; i < rd/2; i++ ) {
                /* print each character */
                System.out.print(buf.getChar());
            }
            buf.clear();
        }
Run Code Online (Sandbox Code Playgroud)

但是角色会显示在?的位置.这是否与使用Unicode字符的Java有关?我该如何纠正?

java io file-io filechannel bytearray

5
推荐指数
1
解决办法
1万
查看次数

使用java.nio.MappedByteBuffer时防止OutOfMemory

考虑应用程序,它创建5-6个线程,循环中的每个线程为5mb页面大小分配MappedByteBuffer.

MappedByteBuffer b = ch.map(FileChannel.MapMode.READ_ONLY, r, 1024*1024*5);
Run Code Online (Sandbox Code Playgroud)

迟早,当应用程序使用大文件时,会抛出oom

java.io.IOException: Map failed  at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:758)
Caused by: java.lang.OutOfMemoryError: Map failed
        at sun.nio.ch.FileChannelImpl.map0(Native Method)
        at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:755)
Run Code Online (Sandbox Code Playgroud)

根据规范,MappedBuffer应该在GC本身时立即配置直接内存.看起来问题是,MappedBuffer-s的GC编辑太晚了,后来直接内存完成了.

如何避免这种情况?可能会说MappedBuffer隐式处理或使用某种MappedBuffer池

java nio bytebuffer filechannel out-of-memory

5
推荐指数
2
解决办法
7603
查看次数

Java NIO MappedByteBuffer OutOfMemoryException

我真的遇到了麻烦:我想用FileChannels和MappedByteBuffers 读取几GB的HUGE文件- 我发现的所有文档都暗示使用该FileChannel.map()方法映射文件相当简单.当然,限制为2GB,因为所有Buffer方法都使用int来定位,限制和容量 - 但系统隐含的限制如何呢?

实际上,我遇到很多关于OutOfMemoryExceptions 的问题!并没有真正定义限制的文档!那么 - 如何将一个符合int-limit的文件安全地映射到一个或几个MappedByteBuffers而不仅仅是异常?

在尝试之前,我可以问系统我可以安全地映射文件的哪个部分FileChannel.map()?怎么样?为什么关于这个功能的文档很少?

java file-io nio bytebuffer filechannel

5
推荐指数
3
解决办法
6742
查看次数

调用map方法后,Java 7文件通道未正确关闭

我正在研究一个sc2replay解析工具.我在MPQLIB http://code.google.com/p/mpqlib/之上构建它

不幸的是,该工具使用文件通道来读取bzip文件并使用 map(MapMode.READ_ONLY, hashtablePosition, hashTableSize);

调用该函数后关闭文件通道不会在该过程中释放该文件.具体来说,我无法重命名/移动文件.

问题出现在Java 7中,它在Java 6上运行良好.

这是一个复制它的简单代码片段:

    FileInputStream f = new FileInputStream("test.SC2Replay");
    FileChannel fc = f.getChannel();

    fc.map(MapMode.READ_ONLY, 0,1);

    fc.close();

    new File("test.SC2Replay").renameTo(new File("test1.SC2Replay"));
Run Code Online (Sandbox Code Playgroud)

注释掉fc.map将允许您重命名该文件.

PS从这里我应该关闭FileChannel吗?

它声明您不需要关闭文件通道和文件流,因为关闭一个将关闭另一个.我也试过关闭其中一个或两个,但仍然没有奏效.

在Java 7上使用FileChannel.map读取数据后是否有重命名文件的解决方法,因为现在每个人似乎都有Java 7?

java memory-management filechannel java-7

5
推荐指数
1
解决办法
999
查看次数

RandomAccessFile与NIO通道

我试图了解以下行为。我的旧代码,

String path = "C:/temp/sample.txt";
String mode= "rw";
FileChannel channel = new RandomAccessFile(path, mode).getChannel();
// some code to write to this file

// finally delete
File file = new File(path);
boolean isDeleted = file.delete();
System.out.println("Is Deleted - " + isDeleted);
Run Code Online (Sandbox Code Playgroud)

O / P-已删除-否

仅当我执行“ channel.close();”时 在我删除文件之前。它是否删除文件并返回true。

较新的替换代码,

String path = "C:/temp/sample.txt";
FileChannel fChannel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
// some code to write to this file

// finally delete
File file = new File(path);
boolean isDeleted = file.delete();
System.out.println("Is Deleted …
Run Code Online (Sandbox Code Playgroud)

java nio filechannel java-io java-7

5
推荐指数
1
解决办法
3218
查看次数

FileUtils.copyFile() VS FileChannel.transferTo()

正如我发现的,底层操作系统调用 is copyToFile()Libcore.os.read(fd, bytes, byteOffset, byteCount)whiletransferTo()基于内存映射文件:

MemoryBlock.mmap(fd, alignment, size + offset, mapMode);
...
buffer = map(MapMode.READ_ONLY, position, count);
return target.write(buffer);
Run Code Online (Sandbox Code Playgroud)

Q1:我的发现是对还是错?
Q2:有什么理由使用FileUtils.copyFile()asFileChannel.transferTo()似乎应该更有效吗?

谢谢

java android filechannel file-copying fileutils

5
推荐指数
1
解决办法
3529
查看次数

内存映射文件在多进程方案中如何工作?

这个问题困扰我好几天了:

假设我有两个在同一台计算机上运行的进程(p_writep_read)。

  • 过程p_write用于写入/更新mmap文件。

  • 过程p_read是使用mmap文件的过程,换句话说,就是读取mmap文件。

我的假设是,p_write首先需要为mmap文件分配一个内存空间(堆外)(该空间使用Java MappedByteBufferAPI 自动映射到文件)。

我的问题是p_read如何从mmap文件读取?我现在的假设是,p_read还需要为要映射的mmap文件分配另一个相同大小的堆外空间,但这似乎是不正确的,因为在这种情况下,内存量需要加倍。

如果p_read不需要为要映射的mmap文件分配单独的内存空间,那么如何p_read知道文件映射到的正确内存地址p_write

更新1

我发现有一个更好的问题要问,或者您可以将其视为后续问题:如果FileChannel.map()两次调用,同一文件是否将两次映射到两个不同的内存空间?

// Scenario A: In single process

try (FileChannel fc = FileChannel.open(filePath, openOptions)) {
   // First call
   fc.map(MapMode.READ_ONLY, 0, SIZE_CONSTANT);
   // Second call
   fc.map(MapMode.READ_ONLY, 0, SIZE_CONSTANT);
}
Run Code Online (Sandbox Code Playgroud)

// Scenario B: In two processes

// in first process
try (FileChannel fc = FileChannel.open(filePath, openOptions)) {
   // First …
Run Code Online (Sandbox Code Playgroud)

java memory filechannel memory-mapped-files mappedbytebuffer

5
推荐指数
0
解决办法
246
查看次数