stringbuilder-在Java中将CLOB读取为String并将String读取为CLOB的最有效解决方案?
我有一个大的CLOB(大于32kB),我想使用StringBuilder读取为String。 如何以最有效的方式做到这一点? 我不能将“ int length”构造函数用于StringBuilder,因为我的CLOB的长度比“ int”长,并且需要一个“ long”值。
我对Java I / O类不太满意,并希望获得一些指导。
编辑-我尝试使用此代码为clobToString():
private String clobToString(Clob data) {
StringBuilder sb = new StringBuilder();
try {
Reader reader = data.getCharacterStream();
BufferedReader br = new BufferedReader(reader);
String line;
while(null != (line = br.readLine())) {
sb.append(line);
}
br.close();
} catch (SQLException e) {
// handle this exception
} catch (IOException e) {
// handle this exception
}
return sb.toString();
}
11个解决方案
45 votes
好的,我想一般性地使用它,首先您必须下载apache commons,然后您将找到一个名为IOUtils的实用程序类,该类具有一个名为copy()的方法。
现在的解决方案是:使用getAsciiStream()获取CLOB对象的输入流,并将其传递给copy()方法。
InputStream in = clobObject.getAsciiStream();
StringWriter w = new StringWriter();
IOUtils.copy(in, w);
String clobAsString = w.toString();
Omar Al Kababji answered 2020-08-06T20:43:11Z
18 votes
我不能为StringBuilder使用“ int length”构造函数,因为我的CLOB的长度大于Integer.MAX_VALUE,并且需要long的值。
如果CLOB长度大于int的长度,则CLOB数据也将不适合String。 您将必须使用流方法来处理大量XML数据。
如果CLOB的实际长度小于Integer.MAX_VALUE,只需将(int)放在(int)的前面,将其强行压到int到int。
Barend answered 2020-08-06T20:42:46Z
18 votes
我的回答只是一样。 但是我通过序列化压缩内容对其进行了测试,并且可以正常工作。 因此,我可以信任此解决方案,而不像第一个提供的解决方案(使用readLine),因为它会忽略换行并破坏输入。
/*********************************************************************************************
* From CLOB to String
* @return string representation of clob
*********************************************************************************************/
private String clobToString(java.sql.Clob data)
{
final StringBuilder sb = new StringBuilder();
try
{
final Reader reader = data.getCharacterStream();
final BufferedReader br = new BufferedReader(reader);
int b;
while(-1 != (b = br.read()))
{
sb.append((char)b);
}
br.close();
}
catch (SQLException e)
{
log.error("SQL. Could not convert CLOB to string",e);
return e.toString();
}
catch (IOException e)
{
log.error("IO. Could not convert CLOB to string",e);
return e.toString();
}
return sb.toString();
}
Stan Sokolov answered 2020-08-06T20:43:31Z
18 votes
有什么问题:
clob.getSubString(1, (int) clob.length());
?
例如,Oracle CLOB在内部char[]上执行getSubString(),内部oracle.jdbc.driver.T4CConnection和System.arraycopy()以及接下来的String定义...接下来的读取速度不会比System.arraycopy()快。
更新获取驱动程序ojdbc6.jar,并反编译CLOB实现,并根据内部知识研究哪种情况会更快。
gavenkoa answered 2020-08-06T20:44:04Z
4 votes
如果您真的只需要使用标准库,则只需在Omar的解决方案上稍加扩展即可。 (Apache的IOUtils基本上只是一组便捷方法,可节省大量代码)
您已经可以通过clobObject.getAsciiStream()获得输入流
您只需将字符“手动传输”到StringWriter:
InputStream in = clobObject.getAsciiStream();
Reader read = new InputStreamReader(in);
StringWriter write = new StringWriter();
int c = -1;
while ((c = read.read()) != -1)
{
write.write(c);
}
write.flush();
String s = write.toString();
请记住
如果您的Clob包含的字符多于适合字符串的字符,则此方法将无效。
分别使用BufferedReader和BufferedWriter包裹InputStreamReader和StringWriter以获得更好的性能。
Edwin Lee answered 2020-08-06T20:44:47Z
4 votes
如果使用Mule,请执行以下步骤。
请遵循以下步骤。
在连接器中启用流式传输,即ProgressiveStreaming = 2
Typecast DB2将CLOB返回到java.sql.Clob(IBM支持此类型转换)
将其转换为字符流(ASCII流有时可能不支持某些特殊字符)。 因此,您可以使用getCharacterStream()
这将返回一个“ reader”对象,可以使用common-io(IOUtils)将其转换为“ String”。
因此,简而言之,请使用groovy组件并添加以下代码。
clobTest = (java.sql.Clob)payload.field1
bodyText = clobTest.getCharacterStream()
targetString = org.apache.commons.io.IOUtils.toString(bodyText)
payload.PAYLOADHEADERS=targetString return payload
注意:在这里,我假设“ payload.field1”正在保存clob数据。
而已!
问候纳文
Naveen K Reddy answered 2020-08-06T20:45:46Z
1 votes
public static final String tryClob2String(final Object value)
{
final Clob clobValue = (Clob) value;
String result = null;
try
{
final long clobLength = clobValue.length();
if (clobLength < Integer.MIN_VALUE || clobLength > Integer.MAX_VALUE)
{
log.debug("CLOB size too big for String!");
}
else
{
result = clobValue.getSubString(1, (int) clobValue.length());
}
}
catch (SQLException e)
{
log.error("tryClob2String ERROR: {}", e);
}
finally
{
if (clobValue != null)
{
try
{
clobValue.free();
}
catch (SQLException e)
{
log.error("CLOB FREE ERROR: {}", e);
}
}
}
return result;
}
kayz1 answered 2020-08-06T20:46:01Z
1 votes
private String convertToString(java.sql.Clob data)
{
final StringBuilder builder= new StringBuilder();
try
{
final Reader reader = data.getCharacterStream();
final BufferedReader br = new BufferedReader(reader);
int b;
while(-1 != (b = br.read()))
{
builder.append((char)b);
}
br.close();
}
catch (SQLException e)
{
log.error("Within SQLException, Could not convert CLOB to string",e);
return e.toString();
}
catch (IOException e)
{
log.error("Within IOException, Could not convert CLOB to string",e);
return e.toString();
}
//enter code here
return builder.toString();
}
Hemant answered 2020-08-06T20:46:17Z
0 votes
public static String readClob(Clob clob) throws SQLException, IOException {
StringBuilder sb = new StringBuilder((int) clob.length());
Reader r = clob.getCharacterStream();
char[] cbuf = new char[2048];
int n;
while ((n = r.read(cbuf, 0, cbuf.length)) != -1) {
sb.append(cbuf, 0, n);
}
return sb.toString();
}
上述方法也是非常有效的。
Rohit answered 2020-08-06T20:46:36Z
0 votes
使用apache commons.io的友好助手方法
Reader reader = clob.getCharacterStream();
StringWriter writer = new StringWriter();
IOUtils.copy(reader, writer);
String clobContent = writer.toString();
fl0w answered 2020-08-06T20:46:56Z
-1 votes
CLOB就像文件一样,您可以像这样轻松读取其中的部分内容
// read the first 1024 characters
String str = myClob.getSubString(0, 1024);
你可以这样覆盖它
// overwrite first 1024 chars with first 1024 chars in str
myClob.setString(0, str,0,1024);
我不建议使用StringBuilder并填充它,直到出现异常为止,几乎就像盲目地加数字直到溢出一样。 Clob就像一个文本文件,最好的读取方法是使用缓冲区,以防您需要对其进行处理,否则可以将其流式传输到本地文件中
int s = 0;
File f = new File("out.txt");
FileWriter fw new FileWriter(f);
while (s < myClob.length())
{
fw.write(myClob.getSubString(0, 1024));
s += 1024;
}
fw.flush();
fw.close();
Khaled.K answered 2020-08-06T20:47:25Z