我正在尝试处理一个包含几个(小的)xml文件的zip文件。我需要解压缩,处理所有文件(转换一些标签内容),然后再次获得zip。
我的想法是使用带拆分器的unmarshal,然后使用zip聚合器对其进行聚合,如下所示:
<route id="ZipFileProcess">
<from uri="file:{{path.to.input.zip}}?move=.done&moveFailed=.error&readLock=rename"/>
<!-- Unzip -->
<unmarshal>
<zipFile usingIterator="true"/>
</unmarshal>
<split streaming="true" parallelProcessing="false">
<simple>${body}</simple>
<!-- Process single file (xpath) -->
<setProperty propertyName="FieldsToTransform">
<xpath resultType="java.util.List">//*[local-name()='Field1']/text()|//*[local-name()='Field2']/text()</xpath>
</setProperty>
....
<!-- Aggregate to zip -->
<aggregate strategyRef="zipAggregationStrategy" eagerCheckCompletion="true">
<correlationExpression>
<simple>${header.CamelFileName}</simple>
</correlationExpression>
<completionPredicate>
<simple>${property.CamelSplitComplete}</simple>
</completionPredicate>
<to uri="file://{{path.to.output.zip}}?fileName=${header.CamelFileName}&tempPrefix=TEMP_"/>
</aggregate>
</split>
</route>
但这会产生以下错误:
org.apache.camel.TypeConversionException: Error during type conversion from type: java.lang.String to the required type: org.apache.camel.StreamCache with value [Body is instance of java.io.InputStream] due java.util.zip.ZipException: too many length or distance symbols
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.createTypeConversionException(BaseTypeConverterRegistry.java:667)
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:158)
at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:87)
at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:61)
at org.apache.camel.impl.DefaultStreamCachingStrategy.cache(DefaultStreamCachingStrategy.java:191)
at org.apache.camel.processor.CamelInternalProcessor$StreamCachingAdvice.before(CamelInternalProcessor.java:810)
at org.apache.camel.processor.CamelInternalProcessor$StreamCachingAdvice.before(CamelInternalProcessor.java:789)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:149)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:715)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:638)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:248)
at org.apache.camel.processor.Splitter.process(Splitter.java:122)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:452)
at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:219)
at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:183)
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174)
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.camel.RuntimeCamelException: java.util.zip.ZipException: too many length or distance symbols
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1830)
at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1409)
at org.apache.camel.impl.converter.StaticMethodTypeConverter.convertTo(StaticMethodTypeConverter.java:59)
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.doConvertTo(BaseTypeConverterRegistry.java:326)
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.convertTo(BaseTypeConverterRegistry.java:141)
... 31 common frames omitted Caused by: java.util.zip.ZipException: too many length or distance symbols
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
at java.util.zip.ZipInputStream.read(ZipInputStream.java:194)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at org.apache.camel.util.IOHelper.copy(IOHelper.java:202)
at org.apache.camel.util.IOHelper.copy(IOHelper.java:174)
at org.apache.camel.util.IOHelper.copyAndCloseInput(IOHelper.java:234)
at org.apache.camel.util.IOHelper.copyAndCloseInput(IOHelper.java:230)
at org.apache.camel.converter.stream.StreamCacheConverter.convertToStreamCache(StreamCacheConverter.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1405)
... 34 common frames omitted
我猜这是由于每个主体都是解压缩后的文件流的事实……但是,在解压缩时是否可以将我的工作不将文件写到磁盘上就可以实现?
内存不会成为问题,因为zip包含大约10个8kb的文件。
答案 0 :(得分:0)
如果内存不是问题,可以选择使用以下方法将每个拆分交换主体(即每个文件内容)转换为字符串:
<convertBodyTo type="java.lang.String"/>
作为拆分后的第一步。