# In-memory reading and writing in Bio-Formats

Bio-Formats readers and writers are traditionally used to handle image files from disk. However it is also possible to achieve reading and writing of files from in-memory sources. This is handled by mapping the in-memory data to a file location using Location.mapFile().

    Location.mapFile(fileName, byteArrayHandle);

This file location is not created on disk but rather maps internally to the in-memory data provided.

## Reading file from memory

In order for Bio-Formats to read a file from memory it must be available in a byte array. For this example an input file is read from disk into a byte array.

        // read in entire file
        System.out.println("Reading file into memory from disk...");
        File inputFile = new File(path);
        int fileSize = (int) inputFile.length();
        DataInputStream in = new DataInputStream(new FileInputStream(inputFile));
        byte[] inBytes = new byte[fileSize];
        in.readFully(inBytes);
        System.out.println(fileSize + " bytes read.");

This data can now be handled by a Bio-Formats reader. This is achieved by providing a mapping from the in-memory data to a suitable filename which will be used by the reader. The filename used must have the same suffix as the original data type.

        // determine input file suffix
        String fileName = inputFile.getName();
        int dot = fileName.lastIndexOf(".");
        String suffix = dot < 0 ? "" : fileName.substring(dot);

        // map input id string to input byte array
        String inId = "inBytes" + suffix;
        Location.mapFile(inId, new ByteArrayHandle(inBytes));

Once the in-memory data has been mapped to a suitable filename the data can be handled by the reader as normal.

        // read in entire file
        System.out.println("Reading file into memory from disk...");
        File inputFile = new File(path);
        int fileSize = (int) inputFile.length();
        DataInputStream in = new DataInputStream(new FileInputStream(inputFile));
        byte[] inBytes = new byte[fileSize];
        in.readFully(inBytes);
        System.out.println(fileSize + " bytes read.");

## Writing to memory

To use a writer to output to memory rather than an output file a similar process is required. First a mapping is created between a suitable output filename and the in-memory data.

        // map output id string to output byte array
        String outId = fileName + ".ome.tif";
        ByteArrayHandle outputFile = new ByteArrayHandle();
        Location.mapFile(outId, outputFile);

The mapped filename can now be passed to initialize the writer as standard.

        // write data to byte array using ImageWriter
        System.out.println();
        System.out.print("Writing planes to destination in memory: ");
        ImageWriter writer = new ImageWriter();
        writer.setMetadataRetrieve(omeMeta);
        writer.setId(outId);

The data can then be written to memory using the same read and write loop which would normally be used to write a file to disk.

        byte[] plane = null;
        for (int i=0; i<imageCount; i++) {
          if (plane == null) {
            // allow reader to allocate a new byte array
            plane = reader.openBytes(i);
          }
          else {
            // reuse previously allocated byte array
            reader.openBytes(i, plane);
          }
          writer.saveBytes(i, plane);
          System.out.print(".");
        }
        reader.close();
        writer.close();
        System.out.println();

        byte[] outBytes = outputFile.getBytes();
        outputFile.close();

If desired the data written to memory can then be flushed to disk and written to an output file location.

        // flush output byte array to disk
        System.out.println();
        System.out.println("Flushing image data to disk...");
        String outFileName = args.length > 1 ? args[1] : fileName + ".ome.tif";
        File outFile = new File(outFileName);
        DataOutputStream out = new DataOutputStream(new FileOutputStream(outFile));
        out.write(outBytes);
        out.close();

See also

`ReadWriteInMemory.java` - Full source code which is referenced here in part. You will need to have `bioformats_package.jar` in your Java `CLASSPATH` in order to compile `ReadWriteInMemory.java`.