@Voicu имеет правильное решение и спасибо за подсказку.
Для будущих посетителей: в новом HttpClient (Angular 4.3+) объектом ответа по умолчанию является JSON, поэтому вам больше не нужно выполнять response.json (). Data. Просто используйте ответ напрямую.
вы можете украсить InputStream, передаваемый в POIFSFileSystem , версией, которая при вызове close () отвечает с помощью reset ():
class ResetOnCloseInputStream extends InputStream {
private final InputStream decorated;
public ResetOnCloseInputStream(InputStream anInputStream) {
if (!anInputStream.markSupported()) {
throw new IllegalArgumentException("marking not supported");
}
anInputStream.mark( 1 << 24); // magic constant: BEWARE
decorated = anInputStream;
}
@Override
public void close() throws IOException {
decorated.reset();
}
@Override
public int read() throws IOException {
return decorated.read();
}
}
static void closeAfterInputStreamIsConsumed(InputStream is)
throws IOException {
int r;
while ((r = is.read()) != -1) {
System.out.println(r);
}
is.close();
System.out.println("=========");
}
public static void main(String[] args) throws IOException {
InputStream is = new ByteArrayInputStream("sample".getBytes());
ResetOnCloseInputStream decoratedIs = new ResetOnCloseInputStream(is);
closeAfterInputStreamIsConsumed(decoratedIs);
closeAfterInputStreamIsConsumed(decoratedIs);
closeAfterInputStreamIsConsumed(is);
}
вы можете прочитать весь файл в байтах [] (режим slurp), а затем передать его в ByteArrayInputStream
Что именно вы имеете в виду под "кешем"? Вы хотите, чтобы другая система POIFSFileSystem запускалась в начале потока? Если это так, то нет никакого смысла кэшировать что-либо в вашем Java-коде; это будет сделано ОС, просто откройте новый поток.
Или вы хотите продолжить чтение с точки, где остановилась первая система POIFSFileSystem? Это не кеширование, и это очень сложно сделать. Единственный способ, который я могу придумать, если вы не можете избежать закрытия потока, - это написать тонкую оболочку, которая подсчитывает, сколько байтов было прочитано, а затем открывает новый поток и пропускает это количество байтов. Но это может потерпеть неудачу, если POIFSFileSystem внутренне использует что-то вроде BufferedInputStream.
Если файл не такой большой, считайте его в массив byte []
и присвойте POI ByteArrayInputStream
, созданный из этого массива.
Если файл большой, тогда вам не стоит беспокоиться, так как ОС сделает кеширование за вас как можно лучше.
[РЕДАКТИРОВАТЬ] Используйте Apache commons-io для эффективного считывания файла в массив байтов. Не используйте int read ()
, так как он читает файл побайтно, что на очень медленно!
Если вы хотите сделать это самостоятельно, используйте File
, чтобы получить длину, создать массив и цикл, который читает байты из файла. Вы должны выполнить цикл, так как read (byte [], int offset, int len)
может читать меньше len
байтов (и обычно так и есть).
Я разбиваю проект на мельчайшие отдельные задачи, которые могу. Затем я просматриваю список трижды.
Когда я впервые просматриваю список, я ищу вещи, с которыми у меня большой опыт. Это вещи, в которых, основываясь на моем предыдущем опыте, я могу очень точно оценить время, которое потребуется.
Затем я просматриваю список в поисках вещей, в которых я не уверен, и боюсь, что они займут много времени. Я провожу некоторое время, исследуя каждую из них, и разбиваю их на еще более мелкие задачи. Это позволяет мне получить лучшее представление о том, что именно задействовано, и облегчит подойти к этому позже.
В последний раз, когда я просматриваю список, я предполагаю, что каждая задача займет у одного программиста один день работы завершить. Иногда кто-то может сделать целую группу за один день. Замечательно. Но иногда в одной задаче есть всевозможные скрытые неприятности, которых никто никогда не ожидал, и кому-то понадобится неделя, чтобы разобраться в ней. В конце концов, все уравняется.
Это не даст вам очень точной оценки. Вы не можете иметь точную оценку. Вы никогда не сможете точно предсказать, в какой день вы что-то закончите. Однако это даст вам очень хорошую консервативную и точную оценку. Точность и точность - разные вещи.
это даст вам очень хорошую консервативную и точную оценку. Точность и точность - разные вещи. это даст вам очень хорошую консервативную и точную оценку. Точность и точность - разные вещи.Попробуйте BufferedInputStream, который добавляет функции отметки и сброса в другой входной поток и просто переопределяет его метод закрытия:
public class UnclosableBufferedInputStream extends BufferedInputStream {
public UnclosableBufferedInputStream(InputStream in) {
super(in);
super.mark(Integer.MAX_VALUE);
}
@Override
public void close() throws IOException {
super.reset();
}
}
Итак:
UnclosableBufferedInputStream bis = new UnclosableBufferedInputStream (inputStream);
и используйте bis
везде, где раньше использовался inputStream.