我正在尝试在C程序中处理DNG文件(从DngCreator获得)。
我不想将其保存到Java中的磁盘中,然后再从C中加载它,因为它浪费时间并且消耗了闪存(每个会话大约需要40个DNG,因此超过800 MB)。
我对Java不太熟悉,但是有没有一种方法可以覆盖OutputStream并添加自己的JNI调用?

最佳答案

假设您具有可以与OutputStream一起使用的DNG创建函数,则可以实例化ByteArrayOutputStream,将其作为参数传递给DNG创建函数,然后再通过方法调用toByteArray()获得字节数组。

然后可以将其传递给本机C库。

在代码中,可能看起来像这样:

package com.software7.jni;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {
    private native void transferDng(byte[] data);

    private void someDNGCreationFunction(OutputStream outputStream)
            throws IOException {
        outputStream.write("hello world!".getBytes(UTF_8));
    }

    private void test() throws IOException {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            someDNGCreationFunction(baos);
            transferDng(baos.toByteArray());
        }
    }

    public static void main(String[] args) {
        System.loadLibrary("Native");
        Main m = new Main();
        try {
            m.test();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


然后本机端可以从字节数组中检索数据,例如看到这个很好的答案https://stackoverflow.com/a/38787614/2331445

#include <string.h>
#include <stdlib.h>
#include <jni.h>
#include "com_software7_jni_Main.h"


JNIEXPORT void JNICALL Java_com_software7_jni_Main_transferDng
  (JNIEnv *env, jobject obj, jbyteArray dng) {
    jsize num_bytes = (*env)->GetArrayLength(env, dng);
    jbyte *b = (*env)->GetByteArrayElements(env, dng, 0);
    char *buffer = malloc(num_bytes);
    memcpy(buffer, b, num_bytes);
    (*env)->ReleaseByteArrayElements(env, dng, b, 0);
    //do something with the buffer, here a printf only for testing
    printf("%.*s", num_bytes, buffer);
    free(buffer);
    return;
}

09-11 18:30