Java scanner.nextLine() 未读取包含 259094 个字符的长行

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

我想在 Java 中读取一个 xml 文件作为字符串,以便我可以加密它。

我目前的做法是将其视为 txt 文件。

我的问题是 xml 文件中的第三行有 259094 个字符长,出于某种原因,扫描仪的 nextLine() 方法最多只能将 131072 个字符读入字符串而不是整行.我读取 xml 文件的代码如下,this 是我使用的 xml 文件。

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();
}

您提供的代码在我的系统上运行良好。

但是如果您的目标是加密文件(不解析它),那么您没有理由将其作为字符串来读取。您可以将其视为字节流并对其进行加密。

下面的代码就是一个例子:

    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();
            }
        }

这会读取一个文件并将输出保存到另一个文件。请注意,为了确保安全,您需要将 IV 更改为随机值,并对每个文件进行更改(可能通过将 iv 保存在加密文件的开头)