Как я могу реализовать OutputStream, который я могу перемотать?

Предполагая, что ваши объекты в базе данных mongo выглядят следующим образом:

{
   "city": "New York City",
   "job": "Assistent"
}

Вы можете сделать запрос вроде:

Jobs.find({
   $and: [
      {
         city: { $in: ["NYC", "Paris"] }
      }, {
         job: { $in: ["Assistent"] }
      }
   ]
})

Это вернет любой объект, у которого есть город среди массив городов, И работа среди массива вакансий.

8
задан Chris R 5 May 2009 в 16:24
поделиться

4 ответа

Here's a random access file output stream.

Note that if using it for a large amount of streamed output you can temporarily wrap it in a BufferedOutputStream to avoid lots of small writes (just be very sure to flush it before discarding the wrapper or using the underlying stream directly).

import java.io.*;

/**
 * A positionable file output stream.
 * <p>
 * Threading Design : [x] Single Threaded  [ ] Threadsafe  [ ] Immutable  [ ] Isolated
 */

public class RandomFileOutputStream
extends OutputStream
{

// *****************************************************************************
// INSTANCE PROPERTIES
// *****************************************************************************

protected RandomAccessFile              randomFile;                             // the random file to write to
protected boolean                       sync;                                   // whether to synchronize every write

// *****************************************************************************
// INSTANCE CONSTRUCTION/INITIALIZATON/FINALIZATION, OPEN/CLOSE
// *****************************************************************************

public RandomFileOutputStream(String fnm) throws IOException {
    this(fnm,false);
    }

public RandomFileOutputStream(String fnm, boolean syn) throws IOException {
    this(new File(fnm),syn);
    }

public RandomFileOutputStream(File fil) throws IOException {
    this(fil,false);
    }

public RandomFileOutputStream(File fil, boolean syn) throws IOException {
    super();

    File                                par;                                    // parent file

    fil=fil.getAbsoluteFile();
    if((par=fil.getParentFile())!=null) { IoUtil.createDir(par); }
    randomFile=new RandomAccessFile(fil,"rw");
    sync=syn;
    }

// *****************************************************************************
// INSTANCE METHODS - OUTPUT STREAM IMPLEMENTATION
// *****************************************************************************

public void write(int val) throws IOException {
    randomFile.write(val);
    if(sync) { randomFile.getFD().sync(); }
    }

public void write(byte[] val) throws IOException {
    randomFile.write(val);
    if(sync) { randomFile.getFD().sync(); }
    }

public void write(byte[] val, int off, int len) throws IOException {
    randomFile.write(val,off,len);
    if(sync) { randomFile.getFD().sync(); }
    }

public void flush() throws IOException {
    if(sync) { randomFile.getFD().sync(); }
    }

public void close() throws IOException {
    randomFile.close();
    }

// *****************************************************************************
// INSTANCE METHODS - RANDOM ACCESS EXTENSIONS
// *****************************************************************************

public long getFilePointer() throws IOException {
    return randomFile.getFilePointer();
    }

public void setFilePointer(long pos) throws IOException {
    randomFile.seek(pos);
    }

public long getFileSize() throws IOException {
    return randomFile.length();
    }

public void setFileSize(long len) throws IOException {
    randomFile.setLength(len);
    }

public FileDescriptor getFD() throws IOException {
    return randomFile.getFD();
    }

} // END PUBLIC CLASS
10
ответ дан 5 December 2019 в 13:01
поделиться

Если вы знаете размер заголовка, вы можете сначала написать пустой заголовок, а затем вернуться, чтобы исправить его с помощью RandomAccessFile в конце. Если вы не знаете размер заголовка, то у вас есть основополагающий факт, что файловые системы обычно не позволяют вставлять данные. Поэтому вам нужно записать во временный файл, а затем записать реальный файл.

2
ответ дан 5 December 2019 в 13:01
поделиться

У Lucene, похоже, есть реализация; и API выглядит хорошо. ]

1
ответ дан 5 December 2019 в 13:01
поделиться

Одним из способов было бы сначала записать начальное содержимое в буфер памяти, затем заголовки в «реальный» выходной поток с последующей очисткой буферизованного содержимого, а затем просто записать в не- буферизованный поток. Похоже, начальный сегмент не будет таким длинным, чтобы сделать буферизацию разумной. Что касается его реализации, вы можете использовать ByteArrayOutputStream для буферизации, а затем сделать так, чтобы ваш класс OutputStream принял «реальный» выходной поток в качестве аргумента; и просто переключайтесь между двумя при необходимости. Вам может потребоваться расширить API-интерфейс OutputStream, чтобы можно было определять, какие метаданные следует записывать, так как эти триггеры переключаются из буферизованного режима.

Как упоминалось в другом ответе, RandomAccessFile также будет работать, хотя и не будет реализовывать OutputStream.

0
ответ дан 5 December 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: