@Override
    public boolean processFileResource(FileResource fileResource) {

        ParseContext context = new ParseContext();

        //try to open outputstream first
        OutputStream os = getOutputStream(fsOSFactory, fileResource);

        if (os == null) {
            LOG.debug("Skipping: {}", fileResource
                    .getMetadata()
                    .get(FSProperties.FS_REL_PATH));
            return false;
        }

        //try to open the inputstream before the parse.
        //if the parse hangs or throws a nasty exception, at least there will
        //be a zero byte file there so that the batchrunner can skip that problematic
        //file during the next run.
        InputStream is = getInputStream(fileResource);
        if (is == null) {
            IOUtils.closeQuietly(os);
            return false;
        }

        Metadata containerMetadata = fileResource.getMetadata();
        JsonStreamingSerializer writer = new JsonStreamingSerializer(new OutputStreamWriter(os, StandardCharsets.UTF_8));

        WriteoutRPWHandler handler = new WriteoutRPWHandler(contentHandlerFactory, writer, metadataFilter);
        Throwable thrown = null;
        try {
            parse(fileResource.getResourceId(), parser, is, handler, containerMetadata, context);
        } catch (Throwable t) {
            thrown = t;
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
                //this is a stop the world kind of thing
                LOG.error("{}", getXMLifiedLogMsg(IO_OS + "json", fileResource.getResourceId(), e));
                throw new RuntimeException(e);
            } finally {
                IOUtils.closeQuietly(is);
            }
        }
        if (thrown != null) {
            if (thrown instanceof Error) {
                throw (Error) thrown;
            } else if (thrown instanceof SecurityException) {
                throw (SecurityException) thrown;
            } else {
                return false;
            }
        }
        return true;
    }
This uses the {@link JsonStreamingSerializer} to write out a
single metadata object at a time.
tika-batch/src/main/java/org/apache/tika/batch/fs/StreamOutRPWFSConsumer.java