Read binary file in C and pass it through JNI to java

5

Hello, the program that I have works but I know how it is that C can read binary files, supposedly I know that with rb it is reading binary files but in the part of C, a < strong> NewStringUTF , which makes that when you read some special characters do not send them to java, how could you make C read any type of file and pass all the bytes whatever their coding

Java

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class ReadFileJNI
{
native String[] readfile();
static
{
 System.loadLibrary("ReadFileJNI");
}
static public void main(String args[])
{
//SE CREA UN OBJETO DE LECTURA QUE TENDRÁ COMUNICACIÓN CON "C"
ReadFileJNI obj = new ReadFileJNI();
//SE CREA UN ARREGLO PARA LA LECTURA DE DATOS
String[] buffer = obj.readfile();
System.out.println(" El arreglo desde C es: \n ");
//SE ASIGNA EL ARREGLO A UNA CADENA
for(String name: buffer)
//SE IMPRIME EN PANTALLA LOS DATOS OBTENIDOS DESDE "C"
    System.out.println(name);
   try {
            //ESPECIFICAMOS LA RUTA DONDE SE CREARA EL ARCHIVO DONDE SE COPIARAN LOS DATOS
            File file = new File("D:\Users\earias\Desktop\pruebas  251016\ReadFileJNI\datos2.txt");
            //SI EL ARCHIVO NO EXISTE ENTONCES LO CREA
            if (!file.exists()) {
                file.createNewFile();
            }
            //LLAMAMOS LA FUNCIÓN QUE ESCRIBIRÁ LOS DATOS EN EL  NUEVO  ARCHIVO
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            //ESCRIBIMOS LOS DATOS EN EL ARCHIVO
            for(String name: buffer){
                    bw.write(name);
            }
            //CERRAMOS EL BUFFER DE ESCRITURA
                bw.close();
            System.out.println("Done \n");
            //SI OCURRIERA ALGÚN ERROR CON ESTA FUNCIÓN LO RECONOCERÍAMOS
            } catch (IOException e) {
                e.printStackTrace();
  }
 }
}   

C

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>

JNIEXPORT jobjectArray JNICALL Java_ReadFileJNI_readfile(JNIEnv *env,  jobject jobj)
{

//Se inicializan las variables 
jstring str;
jsize len = 1;
jobjectArray objectarray = 0;


// Crear variable tipo "File" que es apuntadora y llamar a la funsion fopen, "rb" -> leer archivo/tipo binario
FILE * flujo = fopen("Datos.txt","rb");

// Mueve el flujo al final del archivo, SEEK_END -> final del archivo  
fseek(flujo, 0 , SEEK_END);

/* Da la cantidad total de elementos ya que el ftell pregunta donde 
   se encuentra el flujo y eso se almacena en la variable 
*/
int num_elementos = ftell(flujo);

//Mueve el flujo al inicio del archivo
rewind(flujo);

/* Crear un arreglo de caracteres dinamico, calloc-> de que tamaño en bytes va a ser cada elemento del arreglo 
   se le manda cuanta cantidad de elementos quiere reservar
*/
unsigned char * cadena = (unsigned char *) calloc(sizeof(unsigned char), num_elementos);

/* fread recibe un arreglo donde metera todo el contenido del flujo y que tamaño es elemento que se quiere leer
   y cuantos se quieren leer y como se quieren leer todos se pone el # de elementos  y se le manda de donde 
   extraera la informacion
*/
int num_elemetos_leidos = fread(cadena,sizeof(unsigned char), num_elementos,flujo);

//Se realiza la asignacion del arreglo para enviarlo    
objectarray = (*env)->NewObjectArray(env,len,(*env)->FindClass(env,"java/lang/String"),0);
str = (*env)->NewStringUTF(env,cadena);
(*env)->SetObjectArrayElement(env,objectarray,0,str);

//se libera memoria dinamica de la cadena y se cierra el flujo 
free(cadena);
fclose(flujo);
return objectarray;
}
    
asked by Edu Arias 26.10.2016 в 19:02
source

1 answer

1

I already did the exercise sorry for the delay.

C

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include "ReadFileJNI.h"

JNIEXPORT jbyteArray JNICALL Java_ReadFileJNI_readfile(JNIEnv *env,  jobject jobj)
{

//Se inicializan las variables 
jstring str;
jsize len = 1;


// Crear variable tipo "File" que es apuntadora y llamar a la funsion fopen, "rb" -> leer archivo/tipo binario
FILE * flujo = fopen("Datos.txt","rb");

// Mueve el flujo al final del archivo, SEEK_END -> final del archivo  
fseek(flujo, 0 , SEEK_END);

/* Da la cantidad total de elementos ya que el ftell pregunta donde 
   se encuentra el flujo y eso se almacena en la variable 
*/
int num_elementos = ftell(flujo);

//Mueve el flujo al inicio del archivo
rewind(flujo);

/* Crear un arreglo de caracteres dinamico, calloc-> de que tamaño en bytes va a ser cada elemento del arreglo 
   se le manda cuanta cantidad de elementos quiere reservar
*/
unsigned char * cadena = (unsigned char *) calloc(sizeof(unsigned char), num_elementos);

/* fread recibe un arreglo donde metera todo el contenido del flujo y que tamaño es elemento que se quiere leer
   y cuantos se quieren leer y como se quieren leer todos se pone el # de elementos  y se le manda de donde 
   extraera la informacion
*/
int num_elemetos_leidos = fread(cadena,sizeof(unsigned char), num_elementos,flujo);

jbyteArray arr =(*env)->NewByteArray(env,num_elementos);
(*env)->SetByteArrayRegion(env,arr, 0, num_elementos, (jbyte*) cadena);

//se libera memoria dinamica de la cadena y se cierra el flujo 
free(cadena);
fclose(flujo);
return arr;
}

Java

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class ReadFileJNI {

    native byte[] readfile();

    static {
        System.loadLibrary("ReadFileJNI");
    }

    static public void main(String args[]) {
//SE CREA UN OBJETO DE LECTURA QUE TENDRÁ COMUNICACIÓN CON "C"
        ReadFileJNI obj = new ReadFileJNI();
//SE CREA UN ARREGLO PARA LA LECTURA DE DATOS
        byte[] buffer = obj.readfile();
        System.out.println(" El arreglo desde C es: \n ");
//SE ASIGNA EL ARREGLO A UNA CADENA
        System.out.println(new String(buffer));
        try {
            //ESPECIFICAMOS LA RUTA DONDE SE CREARA EL ARCHIVO DONDE SE COPIARAN LOS DATOS
            File file = new File("datos2.txt");
            //SI EL ARCHIVO NO EXISTE ENTONCES LO CREA
            if (!file.exists()) {
                file.createNewFile();
            }
            //LLAMAMOS LA FUNCIÓN QUE ESCRIBIRÁ LOS DATOS EN EL  NUEVO  ARCHIVO
            OutputStream fw = new FileOutputStream(file.getAbsoluteFile());
            fw.write(buffer);
            //CERRAMOS EL BUFFER DE ESCRITURA
            fw.close();
            System.out.println("Done \n");
            //SI OCURRIERA ALGÚN ERROR CON ESTA FUNCIÓN LO RECONOCERÍAMOS
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
    
answered by 26.10.2016 / 19:16
source