Итак, есть несколько уровней проблем с тем, что вы пытаетесь сделать.
Вы говорите «практичность - не аргумент», и это нормально, но позвольте мне отметить, что Long.MAX_VALUE
действительно превышает количество атомов на земле, так что вероятность того, что вы получите больше записей, чем от База данных действительно мала. Не говоря уже о том, что вы продолжаете собирать эти данные в список, чтобы вы могли столкнуться с проблемами памяти и в своем собственном приложении.
Итак, во-вторых, семантика limit()
заключается в том, что она накладывает фиксированное ограничение на число записей, а «бесконечность» не является фиксированным пределом; следовательно, limit()
просто не то, что вы ищете.
В-третьих, вы, кажется, ищете способ обойти это, поэтому у нас есть шаблон, который вы можете использовать, и это поддерживает ваш собственный счетчик. То, что вы хотите, это что-то вроде AtomicBigInteger
, которого нет в JDK , но показано здесь .
Итак, вы должны создать Predicate
, подобный этому
class BelowValue implements Predicate {
BigInteger limit = BigInteger.ZERO;
AtomicBigInteger counter = new AtomicBigInteger();
public BelowValue(BigInteger limit) {
this.limit = limit;
}
public BelowValue() {}
public boolean test(T ignored) {
// short circuit on zero
if (BigInteger.ZERO.compareTo(limit) == 0) { return true; }
// check actual condition
return counter.incrementAndGet().compareTo(limit) > 0;
}
}
, и затем вы можете использовать его в своем потоке с (Java 8)
Predicate filter = new BelowValue<>(limit);
return stream
.filter(filter)
.boxed()
.collect(Collectors.toList());
Примечание. однако filter
- это , а не - операция с коротким замыканием, поэтому, если у вас бесконечный поток, он не прекратится (и будет очень неэффективным, если ваш поток намного длиннее предельного размера). [1118 ]
Java 9 takeWhile
имеет короткое замыкание, поэтому вы можете заменить его на filter
в приведенном выше примере.
К сожалению, просматривая стандарт нет ничего обеспеченного basic_filebuf
или любой из basic_[io]?fstream
шаблоны классов, чтобы позволить Вам извлекать базовый дескриптор файла ОС (в пути, который fileno()
делает для C stdio ввод-вывод).
И при этом нет open()
метод или конструктор, который берет такой дескриптор файла в качестве параметра (который позволил бы Вам открывать файл с помощью другого механизма и записывать дескриптор файла).
Существует basic_ostream::flush()
, однако я подозреваю, что это на самом деле не звонит fsync()
- Я ожидаю это, как fflush()
в stdio это только удостоверяется, что буферы библиотеки времени выполнения пространства пользователя сбрасываются, означая, что ОС могла все еще буферизовать данные.
Так короче говоря, кажется, нет никакого способа сделать это портативно.:(
Что сделать? Мое предложение состоит в том, чтобы разделить на подклассы basic_filebuf<C, T>
:
template <typename charT, typename traits = std::char_traits<charT> >
class my_basic_filebuf : public basic_filebuf<charT, traits> {
....
public:
int fileno() { ... }
....
};
typedef my_basic_filebuf<char> my_filebuf;
Для использования его можно создать ofstream
с помощью конструктора по умолчанию затем присвойте новый буфер с rdbuf()
:
my_filebuf buf;
buf.open("somefile.txt");
ofstream ofs;
ofs.rdbuf(&buf);
ofs << "Writing to somefile.txt..." << endl;
int fd = static_cast<my_filebuf*>(ofs.rdbuf())->fileno();
Конечно, Вы могли также получить новый класс из basic_ostream
сделать процесс из открытия файла и получения его дескриптора файла более удобным.
Вы не можете портативно сделать fsync()
на дескрипторе файла открываются для чтения, вообще. В Linux, fsync()
документируется как генерирующий EBADF, если дескриптор не находится в режиме записи.