如何处理823237个字符的字符串

时间:2012-05-29 12:02:21

标签: java string servlets file-io io

我有一个字符串,其中包含823237个字符。它实际上是一个xml文件,出于测试目的,我希望作为servlet的响应返回。

我已经尝试了所有可以想到的事情

1)用整个字符串创建一个常量...在这种情况下Eclipse抱怨(在servlet类名下有一个红线) -

 The type generates a string that requires more than 65535 bytes to encode in Utf8 format in the constant pool

2)将整个字符串分成20个字符串常量并直接写入out对象 类似的东西:

out.println( CONSTANT_STRING_PART_1 + CONSTANT_STRING_PART_2 + 
             CONSTANT_STRING_PART_3 + CONSTANT_STRING_PART_4 +
             CONSTANT_STRING_PART_5 + CONSTANT_STRING_PART_6 + 
     // add all the string constants till .... CONSTANT_STRING_PART_20); 

在这种情况下......构建失败..抱怨..

   [javac] D:\xx\xxx\xxx.java:87: constant string too long
   [javac]      CONSTANT_STRING_PART_19 + CONSTANT_STRING_PART_20); 
                                                    ^

3)将xml文件作为字符串读取并写入out object ..在这种情况下我得到

SEVERE: Allocate exception for servlet MyServlet
Caused by: org.apache.xmlbeans.XmlException: error: Content is not allowed in prolog.

最后我的问题是......如何从servlet ???

返回如此大的字符串(作为回复)

6 个答案:

答案 0 :(得分:5)

您可以避免使用流加载内存中的所有文本:

    InputStream is = new FileInputStream("path/to/your/file"); //or the following line if the file is in the classpath
    InputStream is = MyServlet.class.getResourceAsStream("path/to/file/in/classpath");
    byte[] buff = new byte[4 * 1024];
    int read;  
    while ((read = is.read(buff)) != -1) {  
        out.write(buff, 0, read);  
    }

答案 1 :(得分:3)

第二种方法可能有以下方式:

out.print(CONSTANT_STRING_PART_1);
out.print(CONSTANT_STRING_PART_2);
out.print(CONSTANT_STRING_PART_3);
out.print(CONSTANT_STRING_PART_4);
// ...
out.print(CONSTANT_STRING_PART_N);
out.println();

您可以在循环中执行此操作(强烈建议;))。

你这样做的方法,你只需要再次创建大字符串然后将其传递给println(),这与第一个问题相同。

答案 2 :(得分:2)

Ropes: Theory and practice

为什么以及何时使用Ropes for Java进行字符串操作

答案 3 :(得分:1)

您可以将823K文件读入字符串。也许不是最优雅的方法,但完全可行。方法3应该有效。存在XML错误,但这与从文件读取字符串或数据长度无关。

它必须是一个外部文件,因为它太大而无法内联到类文件中(这些文件有大小限制)。

我推荐Commons IO FileUtils#readFileToString

答案 4 :(得分:1)

你必须处理ByteArrayOutputStream而不是自己的字符串。如果你想在http响应中发送你的String,你所要做的就是从byteArray流中读取并写入响应流,如下所示:

ByteArrayOutputStream baos = new ByteArrayOutputStream(8232237);
baos.write(constant1.getBytes());
baos.write(constant2.getBytes());
...
baos.writeTo(response.getOutputStream());

答案 5 :(得分:0)

问题1)和2)都是由于同样的根本问题。字符串文字(或常量字符串表达式)不能超过65535个字符,因为类文件格式中的字符串常量存在硬限制。

第三个问题听起来像是你实现它的方式中的一个错误而不是一个基本问题。事实上,这听起来像是在尝试将XML加载为DOM然后将其解析(这是不必要的),并且在某种程度上您已经设法在此过程中破坏XML。 (或者它可能在你试图阅读的文件中被破坏了......)

简单而优雅的解决方案是将文件保存在文件中,然后将其作为纯文本阅读。

或者......不那么优雅,但同样有效:

   String[] strings = new String[](
        "longString1",
        "longString2",
        ...
        "longStringN"};

   for (String str : strings) {
       out.write(str);
   }

当然,将测试数据嵌​​入字符串文字的问题是你必须转义字符串中的某些字符才能使编译器满意。如果你必须手工完成,那就太乏味了。