Search code examples
javabinaryfilesdatainputstream

Java DataInputStream String out of Range : 0


I am working on a college project where I have to pull celebrity data from TVMaze API into Java.

I store the searched results into a binary file using 'DIS' and since I've objects I pad and depad the file on read / write.

I am getting an error when I'm trying to load the file back into the HashMap .

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0

The error is directed into Load method and Depad Method.

It worked for me yesterday but for an unknown reason it stopped working.

Save Code:

    private static void save(HashMap<String, ArrayList<Person>> persons) throws IOException
{
    try
    {
        ArrayList<Person> p = convertFileData(persons);
        File f = new File("person.dat");
        if(!f.exists())
        {
            f.createNewFile();
        }

        DataOutputStream dos = new DataOutputStream(new FileOutputStream(f));
        Iterator<Person> iter = p.iterator();
        while(iter.hasNext())
        {
            Person s = iter.next();
            dos.writeDouble(s.getScore());
            dos.writeBytes(pad(s.getQueryName(), 30));
            dos.writeBytes(pad(s.getName(), 30));
            dos.writeInt(s.getId());
            List<String> images = s.getImageUrls();
            for(String image : images)
            {
                dos.writeBytes(pad(image, 80));
            }
            dos.writeBytes(pad(s.getPersonUrl(), 50));
            dos.writeDouble(s.getMyRating());
            ArrayList<String> comments = s.getMyComments();
            int commentSize = comments.size();
            System.out.println(commentSize);
            dos.writeInt(commentSize);
            for(String comment : comments)
            {
                dos.writeBytes(pad(comment, 40));
            }
        }
        dos.close();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}

Load Code:

    public static HashMap<String, ArrayList<Person>> load() throws FileNotFoundException, IOException
{
   File f = new File("person.dat");
   HashMap<String, ArrayList<Person>> persons = new HashMap<>();
   if(f.exists())
   {
       DataInputStream dis = new DataInputStream(new FileInputStream(f));
       ArrayList<Person> x = new ArrayList<>();
       while(dis.available() > 0)
       {
           double score = dis.readDouble();
           System.out.println(score);

           byte[] queryNameBytes = new byte[30];
           dis.read(queryNameBytes);
           String queryName = depad(new String(queryNameBytes));
           System.out.println(queryName);

           byte[] nameBytes = new byte[30];
           dis.read(nameBytes);
           String name = depad(new String(nameBytes));
           System.out.println(name);

           int id = dis.readInt();
           System.out.println(id);

           ArrayList<String> imageUrls = new ArrayList<>();

           byte[] mediumImage = new byte[80];
           dis.read(mediumImage);
           String mImage = depad(new String(mediumImage));
           imageUrls.add(mImage);

           byte[] originalImage = new byte[80];
           dis.read(originalImage);
           String oImage = depad(new String(originalImage));
           imageUrls.add(oImage);
           System.out.println(imageUrls);

           byte[] personLinkBytes = new byte[50];
           dis.read(personLinkBytes);
           String personLink = depad(new String(personLinkBytes));
           System.out.println(personLink);

           double myRating = dis.readDouble();
           System.out.println(myRating);

           ArrayList<String> myComments = new ArrayList<>();

           int commentCount = dis.readInt();
           System.out.println(commentCount);
           for(int i = 0; i < commentCount; i++)
           {
                byte[] myCommentsBytes = new byte[40];
                dis.read(myCommentsBytes);
                String myComment = depad(new String(myCommentsBytes));
                myComments.add(myComment);
           }
           System.out.println(myComments);
           x.add(new Person(score, queryName, name, id, imageUrls, personLink, myRating, myComments));

           persons.put(queryName, x); // -> Add person to Map               
       }
       dis.close();
   }
   return persons;
}

Pad Code:

    public static String pad(String s, int size)
{
    while (s.length() < size)
    {
        s = (char)0 + s;
    }
    return s;
}

Depad Code:

    public static String depad(String s)
{
    while(s.charAt(0) == (char)0)
    {
        s = s.substring(1);
    }
    return s;
}

Solution

  • Look at your code:

    public static String depad(String s)
    {
        while(s.charAt(0) == (char)0)
        {
            s = s.substring(1);
        }
    }
    

    What if String s is 0 in size? Then you'll get the StringIndexOutOfBoundsException as expected. You should always do these types of checks when reading in data that can change.