Save 3d array to file inside Android


#1

Hi guys,
I have a Boolean 3d array, I would like to save it on file and then be able to reload it inside the 3d array.

I try to not use any library for this scope.
The question is: after i produce a unique sequence of bytes like below from a 3d boolean array, can i refill the 3d array by load the file (to obtain the same array that i save before)?

To save i produced this code:

boolean pages[][][] = new boolean [8][16][8];
byte pagesConverted[][][] = new byte [8][16][8];
byte list[] = new byte[1024];
boolean gate = true;

void setup() {}

void draw(){
while(gate){
for(int x = 0; x < 8; x++){
int a = round(random(1));
for(int y = 0; y < 16; y++){
int b = round(random(1));
for(int z = 0; z < 8; z++){
int c = round(random(1));
pages[x][y][z] = pages[a][b][c];
pagesConverted[x][y][z] = byte(pages[x][y][z]);
append(list, pagesConverted[x][y][z]);
saveBytes("test.dat", list);

}}}
gate = false;
}
}

Thanks a lot!
Gian


#2

One approach is to convert from 3D to 1D, sort of what you are doing there. The key point is that when you retrieve it, you populate your 3D array it back exactly the same way as you did initially.

Kf

//Widthxheightxdepth
final int W=8;
final int H=16;
final int D=8;

boolean pages[][][] = new boolean [W][H][D];
byte[] list = new byte[W*H*D];

//FIRST: Populate array
for (int x = 0; x < W; x++) {  
  for (int y = 0; y < H; y++) {    
    for (int z = 0; z < D; z++) {
      int randomVal = round(random(1));
      pages[x][y][z] = randomVal>0.5 ? true : false;
    }
  }
}

//SEC: Convert from 3D to 1D
int idx=0;
for (int x = 0; x < W; x++) {  
  for (int y = 0; y < H; y++) {    
    for (int z = 0; z < D; z++) {
       
      list[idx++]=byte(pages[x][y][z] ? 1 : 0);
    }
  }
}

//Third: From 3D to 1D
idx=0;
for (int x = 0; x < W; x++) {  
  for (int y = 0; y < H; y++) {    
    for (int z = 0; z < D; z++) {
       
      pages[x][y][z]=list[idx++]!=0 ? true : false;
    }
  }
}

#3

Hi @kfrajer thanks for help! thats is what i need, i also like your compressed way to write!
May i ask one more thing: i try to create two void for save and load 3d array but i got some problems to get the length of each dimension of the 3d array, it seems to not work like i read around:

int W = stuff.length;
int H = stuff[0].length;
int D = stuff[1].length;

This don’t returns the correct value, may i ask whats wrong?
Thanks!

boolean pages[][][] = new boolean [8][16][8];
boolean pages2[][][] = new boolean [8][16][8];

void setup(){
  //FIRST: Populate array
  for (int x = 0; x < 8; x++) {  
    for (int y = 0; y < 16; y++) {    
      for (int z = 0; z < 8; z++) {
        int randomVal = round(random(1));
        pages[x][y][z] = randomVal>0.5 ? true : false;
        //println(pages[x][y][z]);
      }
    }
  }
save3d(pages,"page");
load3d(pages2,"page");

  for (int x = 0; x < 8; x++) {  
    for (int y = 0; y < 16; y++) {    
      for (int z = 0; z < 8; z++) {
println(pages2[x][y][z]);
      }
    }
  }
}

void save3d( boolean stuff[][][], String  what){
int W = stuff.length;
int H = stuff[0].length;
int D = stuff[1].length;
byte[] list = new byte[W*H*D];
  //SEC: Convert from 3D to 1D and save
  int idx=0;
  for (int x = 0; x < W; x++) {  
    for (int y = 0; y < H; y++) {    
      for (int z = 0; z < D; z++) {
        list[idx++]=byte(stuff[x][y][z] ? 1 : 0);
        saveBytes("save"+what+".dat", list);
      }
    }
  }
  
  println(stuff.length);
  
}

void load3d( boolean stuff[][][], String what){
byte[] list = loadBytes("save"+what+".dat");
int W = stuff.length;
int H = stuff[0].length;
int D = stuff[1].length;
  int idx=0;
  for (int x = 0; x < W; x++) {  
    for (int y = 0; y < H; y++) {    
      for (int z = 0; z < D; z++) {
        stuff[x][y][z]=list[idx++]!=0 ? true : false;
      }
    }
  }
}

#4

Try this

println(pages.length);
println(pages[0].length);
println(pages[0][0].length);

Kf


#5

Hi @kfrajer as i see your way to reduce code lines may i ask if i can reduce my code to save an 2D array Int?
Currently i need a lot passages to archive it, i trying to reduce the declared variables and use only a file.

 void sav() {
   String ch[] = new String[8];
   String nt[] = new String[8];
   for (int x = 0; x < 8; x++) { 
     ch[x] = midiSet[x][0]+"";
     nt[x] = midiSet[x][1]+"";
   }
   saveStrings("ch.txt", ch);
   saveStrings("nt.txt", nt);
 }
 
 void lod() {
   int[] ch  = new int[16];
   int[] nt  = new int[16];
   ch = int(loadStrings("ch.txt"));
   nt = int(loadStrings("nt.txt"));
   for (int x = 0; x < 8; x++) { 
     midiSet[x][0] = ch[x];
     midiSet[x][1] = nt[x];
   }
 }

This is what i trying to do:

 void sav() {
   String ch[] = new String[8];
   for (int x = 0; x < 8; x++) { 
     ch[x] = midiSet[x][0] + "\t" + midiSet[x][1];
   }
   saveStrings("ch.txt", ch);
 }
 //i not manage to spit it again into the array midiSet[8][2]
 void lod() {
   String pieces;
   pieces = loadStrings("ch.txt");
   for (int x = 0; x < 8; x++) { 
     pieces = split(pieces, '\t');
   }  
   println(int(pieces));
 }

Thanks a lot!


#6

Some of the functions you are using returns array data types. You need to modify your code to reflect that. Check the code below for changes in those specific functions. You can find more info in the reference. Notice the code below can be run, so it can easily be used to test changes.

Kf

final int NROWS=8;
final int NCOLS=2;
final int NLINES=NROWS;

final String FN="ch.txt";
final char SEP='\t';

int[][] midiset=new int[NROWS][NCOLS];


void setup() {

  //Fills array with data
  for (int i=0; i<NROWS*NCOLS; i++) {    
    //Firts col: i*100  Second col: i
    midiset[i/2][i%2]=i%2==0?i*100:i;
  }
  sav();
  lod();
}

void sav() {
  
  String ch[] = new String[NLINES];
  for (int x = 0; x < NLINES; x++) { 
    ch[x] = "" + midiset[x][0] + SEP + midiset[x][1];
  }
  saveStrings(FN, ch);
}
//i not manage to spit it again into the array midiSet[8][2]
void lod() {
  String[] input = loadStrings(FN);
  
  for (int x = 0; x < NLINES; x++) { 
    String[] pieces = split(input[x], SEP);
     println("Ctr",x,pieces[0],pieces[1]);
  }  
 
}