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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10798769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:37:12  来源:igfitidea点击:

How to process a string with 823237 characters

javastringservletsfile-ioio

提问by Hell Boy

I have a string that has 823237 characters in it. its actually an xml file and for testing purpose I want to return as a response form a servlet.

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

I have tried everything I can possible think of

我已经尝试了所有我能想到的

1) creating a constant with the whole string... in this case Eclipse complains (with a red line under servlet class name) -

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

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

2) breaking the whole string into 20 string constants and writing to the outobject directly something like :

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

in this case ... the build fails .. complaining..

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

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

3) reading the xml file as a string and writing to out object.. in this case I get

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

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

Finally my question is ... how can I return such a big string (as response) from the servlet???

最后我的问题是......我怎样才能从servlet???返回这么大的字符串(作为响应)

回答by Teg

You can avoid to load all the text in memory using streams:

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

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

回答by brimborium

The second approach might work the following way:

第二种方法可能按以下方式工作:

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

You can do this in a loop of course (which is highly recommended ;)).

当然,您可以循环执行此操作(强烈建议这样做;))。

The way you do it, you just temporarely create the large string again to then pass it to println(), which is the same problem as the first one.

您这样做的方式是,您只是暂时再次创建大字符串,然后将其传递给println(),这与第一个问题相同。

回答by Skynin

Ropes: Theory and practice

绳索:理论与实践

Why and when to use Ropes for Java for string manipulations

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

回答by Thilo

You can read a 823K file into a String. Maybe not the most elegant method, but totally doable. Method 3 should have worked. There was an XML error, but that has nothing to do with reading from a file into a String, or the length of the data.

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

It has to be an external file, though, because it is too big to be inlined into a class file (there are size limits for those).

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

I recommend Commons IO FileUtils#readFileToString.

我推荐 Commons IO FileUtils#readFileToString

回答by Houcem Berrayana

You have to deal with ByteArrayOutputStreamand not with the String it self. If you want to send your String in the http response all you have to do is to read from that byteArray stream and write in the response stream like this :

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

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

回答by Stephen C

Both problem 1) and 2) are due to the same fundamental issue. A String literal (or constant String expression) cannot be more than 65535 characters because there is a hard limit on string constants in the class file format.

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

The third problem sounds like a bug in the way you've implemented it rather than a fundamental problem. In fact, it sounds like you are trying to load the XML as a DOM and then unparse it (which is unnecessary), and that somehow you have managed to mangle the XML in the process. (Or maybe it is mangled in the file you are trying to read ...)

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

The simple and elegant solution is to save the stuff in a file, and then read it as plain text.

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

Or ... less elegant, but just as effective:

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

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

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

Of course, the problem with embedding test data as string literals is that you have to escape certain characters in the string to keep the compiler happy. That's tedious if you have to do it by hand.

当然,将测试数据嵌​​入为字符串文字的问题在于您必须对字符串中的某些字符进行转义以使编译器满意。如果您必须手动完成,那将很乏味。