Search code examples
javaarraysvariablesmerge

Merge more than 100 json files to one file using java code


I try to put more than 100 similar jsonArray to one file, but I cannot resolve how I can name jsonArray`s name as variable in "for cycle" in java. Please, help me. All questions that I found here about 2-3 jsonArrays with final names.


for (int j=1; j<10; j++) {
    

        //StringEntity json2 = new StringEntity("c:/test/test.txt");

        FileInputStream fileInputStream = null;
        String data="";
        StringBuffer stringBuffer = new StringBuffer("");
        try{
            br = new BufferedReader(new InputStreamReader(
             new FileInputStream("c:/test1/jsonparser" + j +".json"), "UTF-8"));
            
            
            int i;
            while((i=br.read())!=-1)
            {
                stringBuffer.append((char)i);
            }
            data = stringBuffer.toString();
        }
        catch(Exception e){
                //LoggerUtil.printStackTrace(e);
        }
        finally{
            if(fileInputStream!=null){  
                fileInputStream.close();
            }
        }
      

       JSONTokener tokener1 = new JSONTokener(data);
       JSONObject json1 = new JSONObject(tokener1);
     
       JSONArray sourceArray = new JSONArray(json1);
        JSONArray destinationArray = new JSONArray();

        for (int i = 0; i < sourceArray.length(); i++) {
        destinationArray.put(sourceArray.getJSONObject(i));
                }

        String s3 = destinationArray.toString();

        System.out.println(s3);

Solution

  • If I got the requirement right, you want to merge a large number of single JSON files into one large String that you want to parse later.

    For my understanding, this should work like this:

    final var joiner = new StringJoiner( ", ", "{ array : [", "]}";
    for( var i = 0; i < maxFiles; ++i )
    {
      final var path = Path.of( "c:/test1/jsonparser%d.json".formatted( i ) );
      joiner.add( Files.readString( path, StandardCharsets.UTF_8 );
    }
    final var combinedJSON = joiner.toString();
    

    If you want to have a kind of struct instead of an array, that may look like this:

    final var joiner = new StringJoiner( "}, {", "{", "}";
    for( var i = 0; i < maxFiles; ++i )
    {
      final var path = Path.of( "c:/test1/jsonparser%d.json".formatted( i ) );
      joiner.add( "object%d : %s".formatted( i, Files.readString( path, StandardCharsets.UTF_8 ) );
    }
    final var combinedJSON = joiner.toString();
    

    And of course, I omitted any error handling …


    Ok, let's fix your code:

    JSONArray destinationArray = new JSONArray();
    for( int j = 1; j < 10; ++j ) 
    {
      String data = "";
      // try-with-resources makes things easier …
      try( final var br = new BufferedReader( new InputStreamReader( new FileInputStream( "c:/test1/jsonparser" + j +".json" ), "UTF-8" ) );
      {
        // StringBuilder is more efficient than StringBuffer in this case
        final StringBuilder stringBuffer = new StringBuilder();
    
        // Of course you can read a file like this, but you also shoot you in the foot …
        int i;
        while( ( i = br.read() ) != -1 )
        {
          stringBuffer.append( (char) i );
        }
        data = stringBuffer.toString();
      }
      catch( IOException e ) // NEVER catch java.lang.Exception!
      {
        // We log the failure for this file and try the next one …
        //LoggerUtil.printStackTrace(e);
        // Not nice, but can be done this way
      }
      JSONTokener tokener = new JSONTokener( data );
      JSONObject json = new JSONObject( tokener );
      destinationArray.put( json );
    }
          
    String s3 = destinationArray.toString();
    System.out.println(s3);
    

    But why parsing the JSON files when simple operations on String would do the job, too? Only when it could be possible that the input files are not valid JSON, it makes sense to parse them before merging, because at a failure you know which file was broken.