GridFS не может прочитать ни одного из GridFSDownloadStream - PullRequest
0 голосов
/ 17 марта 2019

Я успешно получил конкретный файл от mongodb, но когда я пытаюсь прочитать данные из него, он не работает.Почему?

    @Autowired
    private MongoTemplate mongoTemplate;
    public InputStream getDownloadStream() {
        GridFSBucket gridfs = GridFSBuckets.create(mongoTemplate.getDb());
        GridFSDownloadStream st = gridfs.openDownloadStream(new ObjectId("5c891a34f2d7831638ba8fce"));
        System.out.println(st.getGridFSFile().getLength()); // output: 4422653
        System.out.println(st.available()); // output: 0
        return st;
    }

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

На самом деле данные были в состоянии читать из GridFSDownloadStream.Но когда я делаю это:

GridFSDownloadStream st = gridFSBucket.openDownloadStream(filename);
st.available();

Всегда я получаю "0".

GridFSDownloadStream не поддерживает метод available (), по крайней мере вы не можете получить правильную длину файла, сохраненного в нескольких чанках через это.Если вы хотите получить длину GridFSDownloadStream, используйте взамен getGridFSFile (). GetLength ().

GridFSDownloadStream st = gridFSBucket.openDownloadStream(filename);
st.getGridFSFile().getLength();

При чтении данных из GridFSDownloadStream с буфером стоит отметить, что размер буфера НЕ должен превышатьразмер куска.Поскольку метод read () может считывать данные только из одного чанка каждый раз.

GridFSDownloadStream st = gridFSBucket.openDownloadStream(filename);
byte[] buffer = new buffer[stream.getGridFSFile().getLength()];
st.read(buffer);

Если данные сохраняются в нескольких чанках, это может не сработать.Только данные из первого блока будут считаны в буфер!

Так что вы можете попробовать следующее, чтобы избежать этого:

GridFSDownloadStream st = gridFSBucket.openDownloadStream(filename);
int bufferSize = 1024;
int chunkSize = st.getGridFSFile().getChunkSize();
if (bufferSize > chunkSize)
    bufferSize = chunkSize;
byte[] buffer = new byte[bufferSize];
// Loop
st.read(buffer);
0 голосов
/ 17 марта 2019

Вы можете попробовать следующее:

@Autowired
private GridFsTemplate gridFsTemplate;

public InputStream getDownloadStream() throws IOException {
    Query query = new Query(Criteria.where("_id").is("5c891a34f2d7831638ba8fce"));
    GridFSFile gridFSFile = gridFsTemplate.findOne(query);
    GridFsResource gridFsResource = gridFsTemplate.getResource(gridFSFile);
    return gridFsResource.getInputStream();
}

gridFsTemplate может быть впрыснут с помощью стартера Mongodb:

implementation "org.springframework.boot:spring-boot-starter-data-mongodb"
...