标签: random-access

Java中的文件流

我目前正在使用JOGL(Java OpenGL绑定)开发3D图形应用程序.简而言之,我有一个巨大的横向二进制文件.由于它的大小,我必须在运行时流式传输地形块.因此,我们明确地看到随机访问问题.我已经完成了第一个(和脏:))实现(也许它是多线程的),我正在使用一个愚蠢的方法......这是它的初始化:

dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());
Run Code Online (Sandbox Code Playgroud)

当我需要读取(流)特殊块(我已经在文件中知道它的"偏移量")时,我正在执行以下操作(对我感到羞耻:)):

dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);
Run Code Online (Sandbox Code Playgroud)

因为我没有经验,这是我能想到的第一件事:)所以,直到现在我已经阅读了3篇有用且非常有趣的文章(我建议你阅读它们,或许如果你对这个主题感兴趣的话)

  1. 字节缓冲区和非堆内存 - 格雷戈里先生似乎在Java NIO中识字.

  2. Java技巧:如何快速阅读文件 [http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly] - 这是一个有趣的基准.

  3. 文章:调优Java I/O性能 [http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/] - 简单的Sun建议,但请向下滚动并查看那里的"随机访问"部分; 它们显示了RandomAccessFile(RAF)的简单实现,具有自缓冲改进.

格雷戈里先生在他的文章末尾提供了几个*.java文件.其中之一是FileChannel + ByteBuffer + Mapping(FBM)和RAF之间的基准测试.他说,与英国皇家空军相比,他在使用FBM时注意到了4倍的加速.我在以下条件下运行此基准:

  1. 偏移量(例如访问位置)是随机生成的(在文件范围内,例如0 - file.length());
  2. 文件大小为220MB;
  3. 1 000 000次访问(75%读取和25%写入)

结果令人震惊:

英国皇家空军大约28秒! FBM约0.2秒!

但是,他在这个基准测试中实现RAF并没有自我缓冲(第3篇文章讲述了一个),所以我猜这是调用的"RandomAccessFile.seek"方法,他们如此努力地降低了性能.

好的,现在经过我所学到的所有这些事情,有1个问题和1个困境:)

问题:当我们使用"FileChannel.map"映射文件时,Java是否将整个文件内容复制到MappedByteBuffer中?或者它只是模仿它?如果它复制,那么使用FBM方法不适合我的情况,是吗?

困境:取决于你对这个问题的答案......

  1. 如果映射复制文件,那么我似乎只有2个可能的解决方案:RAF +自缓冲(第3篇文章中的那个)或者使用FileChannel中的位置(不使用映射)...哪一个会会更好?

  2. 如果映射不复制文件,那么我有3个选项:前两个和FBM本身.

编辑:这是另外一个问题.你们有些人说,映射不会将文件复制到MappedByteBuffer中.那么,为什么我不能映射1GB文件呢,我收到"无法映射"的消息......

PS我想通过建议得到满意的答案,因为我无法在互联网上找到关于此主题的一致信息.

谢谢 :)

java streaming random-access

8
推荐指数
1
解决办法
4663
查看次数

从python中具有固定数量元素的集合中快速采样

我需要从一个固定大小的集合中随机均匀地采样一个数字,进行一些计算,然后将新数字放回集合中.(所需的样本数量非常大)

我试图将数字存储在列表中并使用random.choice()来选择一个元素,将其删除,然后附加新元素.但那太慢了!

我想将数字存储在一个numpy数组中,对一个索引列表进行采样,并为每个索引执行计算.

  • 有没有更快的方法来完成这个过程?

python random performance numpy random-access

8
推荐指数
1
解决办法
1767
查看次数

随机访问文件FileLock:java.io与java.nio

我注意到,java.iojava.nio随机访问文件的实施对于略有不同如何FileLocks进行处理.

看起来好像(在Windows上)java.io为您提供强制文件锁定,并java.nio在分别请求时为您提供建议文件锁定.强制文件锁定意味着锁定适用于所有进程,并且建议适用于遵循相同锁定协议的良好行为进程.

如果我运行以下示例,我可以*.nio手动删除该文件,而*.io文件拒绝删除.

import java.io.*;
import java.lang.management.ManagementFactory;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;

public class NioIoLock {

    public static void main(String[] args) throws IOException, InterruptedException {
        String workDir = System.getProperty("user.dir");

        FileChannel channelIo, channelNio;
        FileLock lockIo, lockNio;

        // use io
        {
            String fileName = workDir
                    + File.separator
                    + ManagementFactory.getRuntimeMXBean().getName()
                    + ".io";
            File lockFile = new File(fileName);
            lockFile.deleteOnExit();
            RandomAccessFile file = new RandomAccessFile(lockFile, "rw");            

            channelIo = file.getChannel();
            lockIo …
Run Code Online (Sandbox Code Playgroud)

java nio random-access filelock java-io

8
推荐指数
1
解决办法
1767
查看次数

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
查看次数

Java:使用缓冲输入从随机访问文件中读取字符串

我以前从未接触过Java IO API的经验,现在我真的很沮丧.我发现很难相信它有多奇怪和复杂,做一个简单的任务有多难.

我的任务:我有2个位置(起始字节,结束字节),pos1pos2.我需要读取这两个字节之间的行(包括起始字节,不包括结尾字节),并将它们用作UTF8字符串对象.

例如,在大多数脚本语言中,它将是一个非常简单的1-2-3-liner(在Ruby中,但它对于Python,Perl等基本相同):

f = File.open("file.txt").seek(pos1)
while f.pos < pos2 {
  s = f.readline
  # do something with "s" here
}
Run Code Online (Sandbox Code Playgroud)

使用Java IO API很快就会出现问题;)实际上,我看到了两种\n从常规本地文件中读取行(以...结尾)的方法:

  • RandomAccessFilegetFilePointer()seek(long pos),但它的readLine()读取非UTF8字符串(甚至不是字节数组),但非常奇怪的字符串具有破坏的编码,并且它没有缓冲(这可能意味着每个read*()调用都将被转换为单个不连续的OS read()= >相当慢).
  • BufferedReader有很好的readLine()方法,它甚至可以进行一些搜索skip(long n),但它无法确定已经读取的偶数字节数,也没有提到文件中的当前位置.

我试过用类似的东西:

    FileInputStream fis = new FileInputStream(fileName);
    FileChannel fc = fis.getChannel();
    BufferedReader br = new BufferedReader(
            new InputStreamReader(
                    fis,
                    CHARSET_UTF8
            )
    );
Run Code Online (Sandbox Code Playgroud)

...然后使用fc.position()获取当前文件读取位置并fc.position(newPosition)设置一个,但它似乎在我的情况下不起作用:看起来它返回由BufferedReader完成的缓冲区预填充的位置,或类似的东西 - …

java nio random-access fileinputstream bufferedreader

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

编译错误:请求成员不是结构或联合

编辑: 以下代码已被修改为工作,因为问题已解决.

具体来说,(*hardwareList.next_item)->next最初是在没有括号的情况下编写的(例如as *hardwareList.next_item->next),编译器也不理解它.

我正在努力解决为什么编译器与我的C代码混淆.我正在尝试创建一个存储所有项目的链接列表,以及指向最后一个"下一个"变量的地址的指针,以便于追加.

typedef struct {
  int recordNum;
  char toolName[25];
  int quantity;
  float cost;
} HardwareData;

typedef struct _HardwareListItem{
  HardwareData data;
  struct _HardwareListItem* next;
} HardwareListItem;

typedef struct _HardwareList {
  HardwareListItem* items;
  HardwareListItem** next_item;
} HardwareList;

HardwareList readFromFile(FILE* fp)
{
  char stopReading = 0;
  HardwareList hardwareList = {0};
  hardwareList.next_item = &hardwareList.items;
  do {
    *hardwareList.next_item = (HardwareListItem*)calloc(1, sizeof(HardwareData));
    if (*hardwareList.next_item == NULL)
    {
      fprintf(stderr, "OOM Reading File\n");
      fflush(stderr);
      exit(EXIT_FAILURE);
    }
    if (fread(&((*hardwareList.next_item)->data), sizeof(HardwareData), 1, fp) != …
Run Code Online (Sandbox Code Playgroud)

c linked-list random-access

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

使用RandomAccessFile到达文件中的特定行

是否可以通过RandomAccessFile将光标定位到文件中特定行的开头?

例如,我想在文件中第111行的char 10到20之间更改String.该文件具有固定长度的记录.

是否可以使用RandomAccessFile将光标直接定位到第111行的开头?

更新:

我使用了以下代码.但是,它返回null.

行长度为200个字符(如果我没有错,则为200个字节)

File f = new File(myFile); 
RandomAccessFile r = new RandomAccessFile(f,"rw"); 
r.skipBytes(200 * 99);   // linesize * (lineNum - 1) 
System.out.println(r.readLine());
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

java file random-access

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

如何实现非连续容器(例如std :: deque)的随机访问迭代器?

我理解随机访问迭代器如何对连续容器起作用std::vector:迭代器只是维护一个指向当前元素的指针,并且任何加法/减法都应用于指针.

但是,我对于如何为非连续容器实现类似的功能感到困惑.我对如何std::deque:iterator工作的第一个猜测是,它维护了一个指向它包含的连续内存组的表的指针,但我不确定.

典型的标准库如何实现这一点?

c++ iterator random-access deque

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

使用OpenGL进行高效的GPU随机存储器访问

什么是让GPU有效地计算"反功能"例程的最佳模式,这通常取决于定位的内存写入而不是读取?例如.比如计算直方图,排序,按百分比划分数字,将不同大小的数据合并到列表等中.

opengl gpu gpgpu glsl random-access

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

如何返回多个类型的对象

让我们举个例子来简化它.我构建了一个构造函数采用的列表integer和a List<Integer>.我的列表将包含给定列表的所有元素乘以integer.我的列表不存储新元素,而是动态计算它们:

class MyList extends AbstractList<Integer> implements RandomAccess {
    private final int multiplier;
    private final List<Integer> list;

    public MyList(int multiplier, List<Integer> list) {
        this.multiplier = multiplier;
        this.list = list;
    }

    @Override
    public Integer get(int index) {
        return list.get(index) * multiplier;
    }

    @Override
    public int size() {
        return list.size();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我们可以调用new MyList(3, list)list = [0, 1, 2, 3]获得[0, 3, 6, 9].

我想限制开发人员给MyList构造函数一个列表,这也是RandomAccess为了确保他不会破坏性能.

我尝试用以下方法更改构造函数:

public <E …
Run Code Online (Sandbox Code Playgroud)

java collections list random-access

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