Java scanner.nextLine() not reading long line with 259094 characters

Tags: ,



I want to read an xml file as a String in Java so that I can encrypt it.

My current approach is to treat it like a txt file.

My problem is that the third line in the xml file is 259094 characters long and for some reason, the scanner’s nextLine() method is only reading up to 131072 characters into the string instead of the whole line. My code for reading the xml file is below and this is the xml file I used.

try {
  File myFile = new File(filename);
  Scanner myReader = new Scanner(myFile);
  int lineCount = 0;

  while (myReader.hasNextLine()) {
    if (lineCount > 0) { // To make sure it doesn't append n before the first line[enter link description here][1]
      data += "n";
    }
    String temp = myReader.nextLine();
    data += temp;
    lineCount += 1;
  }
      
  myReader.close();
}
catch (FileNotFoundException e) {
  System.out.println("An error occurred.");
  e.printStackTrace();
}

Answer

The code you provided works fine on my system.

But if your aim is to encrypt a file (without parsing it), then there is no reason why you should read it as a String. You could just treat it as a byte stream and encrypt those.

An example for that would be the following code:

    public static void main(String[] args) throws NoSuchAlgorithmException {
            String filename = "/tmp/xml.xml";
    
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            keygen.init(256);
            SecretKey secretKey = keygen.generateKey();
            byte[] IV = new byte[16]; //TODO The bytes should be random and different for each file
            GCMParameterSpec gcmSpec = new GCMParameterSpec(128, IV);
    
            try {
                encryptFile(new File(filename), new File(filename + ".encrypted"), secretKey, gcmSpec);
                decyptFile(new File(filename + ".encrypted"), new File(filename + ".decrypted"), secretKey, gcmSpec);
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    
        static void encryptFile(File inputFile, File outputFile, SecretKey secretKey, GCMParameterSpec gcmSpec) throws InvalidKeyException, IOException {
            InputStream input = null;
            OutputStream output = null;
            try {
                input = new BufferedInputStream(new FileInputStream(inputFile));
                output = new BufferedOutputStream(new FileOutputStream(outputFile));
                Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
    
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmSpec);
    
                while (input.available() > 0) {
                    byte[] bytes = input.readNBytes(128);
                    output.write(cipher.update(bytes));
                }
                output.write(cipher.doFinal());
    
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
                e.printStackTrace();
                System.exit(1);
            } finally {
                if (input != null) input.close();
                if (output != null) output.close();
            }
        }
    
        static void decyptFile(File encryptedFile, File outputFile, SecretKey secretKey, GCMParameterSpec gcmSpec) throws InvalidKeyException, IOException {
            InputStream input = null;
            OutputStream output = null;
            try {
                input = new BufferedInputStream(new FileInputStream(encryptedFile));
                output = new BufferedOutputStream(new FileOutputStream(outputFile));
                Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
    
                cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmSpec);
    
                while (input.available() > 0) {
                    byte[] bytes = input.readNBytes(128);
                    output.write(cipher.update(bytes));
                }
    
                output.write(cipher.doFinal());
    
            } catch (NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            } finally {
                if (input != null) input.close();
                if (output != null) output.close();
            }
        }

This reads a file and saves the output to another file. Note that for this to be secure you need to change the IV to a random value with changes for each file (Probably by saving the iv at the beginning of the encrypted file)



Source: stackoverflow