2012-07-06 20 views
14

Tengo que leer/escribir archivos directamente, sin ningún almacenamiento en búfer. En la antigua forma de C, hice esto mediante el uso de un método abierto con el indicador O_DIRECT.¿Cómo leer/escribir directamente el archivo desde y hacia el dispositivo (como el efecto del indicador O_DIRECT) de forma Java?

¿Es esto posible de forma Java?

Aquí es O_DIRECT Descripción

tratar de minimizar los efectos de caché de E/S hacia y desde este archivo. En en general, esto degradará el rendimiento, pero es útil en situaciones especiales , como cuando las aplicaciones hacen su propio almacenamiento en caché. La E/S de archivo se realiza directamente a/desde búferes de espacio de usuario.

ACTUALIZADO:

Aquí está mi ejemplo de código,

// write 
fos = new FileOutputStream(fileName); 
fos.write(inputData); 
fos.flush(); 
fos.close(); 

// read 
fis = new FileInputStream(fileName); 
int len = fis.read(outputData, offset, length); 
fis.close(); 

El fondo fue que escribí de datos (en realidad, el mando) a un archivo en la tarjeta SD (una especie de tarjeta inteligente) , entonces la tarjeta inteligente recibió el comando y el resultado preparado para el mismo archivo. Normalmente, puedo leer los datos (resultados) de ese archivo, pero obtuve los mismos inputData y outputData, es decir, acabo de recibir mi comando. Ese es un resultado inesperado. Estoy sospechando si el código solo escribió/leyó desde y hacia un búfer, no el archivo real. Flush no funcionó.

+1

Si no le molesta la lentitud, puede usar 'FileOutputStream' desnudo, que es prácticamente el nivel más bajo, sin almacenamiento en búfer. Por supuesto, tendrás que convertir todo en 'byte []' o 'byte', pero parece que es lo que quieres hacer. – nhahtdh

+0

Es probable que pueda hacer esto con el ndk, pero ¿por qué? –

+0

@Chris Stratton, seguro que sé que podría hacerlo NDK y jni, pero prefiero hacerlo en Java porque es conveniente para la depuración y me gustaría saber si es posible – fifth

Respuesta

2

Los documentos de android para FileOutputStream tienen en cuenta explícitamente que se trata de una secuencia no almacenada. De todos modos, flush() seguido de close() debería hacer el truco. El único paso adicional que puede desear realizar antes de close() es getFD(). Sync().

Menciona una tarjeta inteligente, por lo tanto, este dispositivo implementa su propio (falso) sistema de archivos, que aparece como una tarjeta SD o similar al host. ¿Los documentos de la tarjeta indican cuánto tiempo debe entregar la tarjeta para notificar los cambios en el archivo? En el nivel de E/S del bloque no hay una operación correspondiente 'abrir' o 'cerrar', por lo tanto, el dispositivo debe notar las escrituras de los bytes.

Alternativamente, si el dispositivo es "inteligente" y utiliza cambios en el tiempo en los metadatos del archivo, entonces puede necesitar llamar a File.setLastModified (System.currentTimeMillis()) para 'tocar' el archivo manualmente. Suponiendo que el dispositivo de tipo sd está montado con la opción 'noatime' para mejorar el rendimiento.

1

Cuando llama al close(), desaparecen todos los datos asociados con el descriptor del archivo. Como obtiene los mismos datos de entrada que los datos de salida, puede que este no sea un problema de lectura de archivos Java.

Sugiero que depure su dispositivo (controlador) desde Linux, en lugar de desde Android. Si lo prefiere, escriba un programa C para hacer lo mismo e intente ejecutarlo desde el shell adb. Debería ayudarlo a resolver el problema original.

Cuestiones relacionadas