txt studio leer importar exportar desde datos como archivos archivo abrir r binary rcpp

studio - leer archivos txt en r



Lea archivos binarios en R desde un archivo comprimido y una posiciĆ³n de inicio conocida(desplazamiento de bytes) (1)

Aquí hay un truco que podría funcionar para ti. Aquí hay un archivo binario falso:

writeBin(as.raw(1:255), "file.bin") readBin("file.bin", raw(1), n = 16) # [1] 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10

Y aquí está el archivo zip producido:

zip("file.zip", "file.bin") # adding: file.bin (stored 0%) readBin("file.zip", raw(1), n = 16) # [1] 50 4b 03 04 0a 00 02 00 00 00 7b ab 45 4a 87 1f

Esto usa un archivo binario intermedio temporal.

system(''sh -c "unzip -p file.zip file.bin | dd of=tempfile.bin bs=1c skip=5c count=4c"'') # 4+0 records in # 4+0 records out # 4 bytes copied, 0.00044964 s, 8.9 kB/s file.info("tempfile.bin")$size # [1] 4 readBin("tempfile.bin", raw(1), n = 16) # [1] 06 07 08 09

Este método compensa el "gasto" de lidiar con el tamaño de los datos binarios almacenados en el shell / pipe, fuera de R.

Esto funcionó en win10, R-3.3.2. Estoy usando dd de Git para Windows (versión 2.11.0.3, aunque 2.11.1 está disponible), y unzip y sh de RTools.

Sys.which(c("dd", "unzip", "sh")) # dd # "C://PROGRA~1//Git//usr//bin//dd.exe" # unzip # "c://Rtools//bin//unzip.exe" # sh # "c://Rtools//bin//sh.exe"

Tengo un archivo binario comprimido bajo el sistema operativo Windows que estoy tratando de leer con R. Hasta ahora funciona usando la función unz () en combinación con la función readBin ().

> bin.con <- unz(zip_path, file_in_zip, open = ''rb'') > readBin(bin.con, "double", n = byte_chunk, size = 8L, endian = "little") > close(bin.con)

Donde zip_path es la ruta al archivo zip, file_in_zip es el nombre de archivo dentro del archivo zip que se debe leer y byte_chunk el número de bytes que quiero leer.

En mi caso de uso, la operación readBin es parte de un ciclo y lee gradualmente todo el archivo binario. Sin embargo, rara vez quiero leer todo y muchas veces sé exactamente qué partes quiero leer. Desafortunadamente, readBin no tiene un argumento de inicio / salto para omitir los primeros n bytes. Por lo tanto, traté de reemplazar condicionalmente readBin () con seek () para omitir la lectura real de las partes no deseadas.

Cuando pruebo esto, obtengo un error:

> bin.con <- unz(zip_path, file_in_zip, open = ''rb'') > seek(bin.con, where = bytes_to_skip, origin = ''current'') Error in seek.connection(bin.con, where = bytes_to_skip, origin = "current") : seek not enabled for this connection > close(bin.con)

Hasta el momento, no he encontrado una manera de resolver este error. Preguntas similares se pueden encontrar aquí (lamentablemente sin una respuesta satisfactoria):

Sugerencias en todo el Internet sugieren agregar el argumento open = ''r'' a unz () o descartar completamente el argumento abierto, pero eso solo funciona para archivos no binarios (ya que el valor predeterminado es ''r''). La gente también sugiere descomprimir los archivos primero, pero dado que los archivos son bastante grandes, esto es prácticamente imposible.

¿Hay algún problema para buscar en un archivo comprimido binario o leer con un desplazamiento de bytes (potencialmente usando C ++ a través del paquete Rcpp)?

Actualización :

La investigación adicional parece indicar que seek () en archivos zip no es un problema fácil. Esta pregunta sugiere una biblioteca de C ++ que, en el mejor de los casos, puede usar una búsqueda aproximada. Esta pregunta de Python indica que una búsqueda exacta es completamente imposible debido a la forma en que se implementa zip (aunque no está en contradicción con el método de búsqueda aproximada).