INT-3738: Fix FileSplitter
JIRA: https://jira.spring.io/browse/INT-3738 Don't rely on `BufferedReader.ready()` to detect EOF. Polishing FileSplitter Fix
This commit is contained in:
committed by
Artem Bilan
parent
505bfac2f8
commit
c278548216
@@ -30,6 +30,7 @@ import java.nio.charset.Charset;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.springframework.integration.file.splitter.FileSplitter.FileMarker.Mark;
|
import org.springframework.integration.file.splitter.FileSplitter.FileMarker.Mark;
|
||||||
import org.springframework.integration.splitter.AbstractMessageSplitter;
|
import org.springframework.integration.splitter.AbstractMessageSplitter;
|
||||||
@@ -87,7 +88,7 @@ public class FileSplitter extends AbstractMessageSplitter {
|
|||||||
* the markers are included in the sequence size.
|
* the markers are included in the sequence size.
|
||||||
* @param iterator true to return an iterator, false to return a list of lines.
|
* @param iterator true to return an iterator, false to return a list of lines.
|
||||||
* @param markers true to emit start of file/end of file marker messages before/after the data.
|
* @param markers true to emit start of file/end of file marker messages before/after the data.
|
||||||
* @since 1.4.5
|
* @since 4.1.5
|
||||||
*/
|
*/
|
||||||
public FileSplitter(boolean iterator, boolean markers) {
|
public FileSplitter(boolean iterator, boolean markers) {
|
||||||
this.iterator = iterator;
|
this.iterator = iterator;
|
||||||
@@ -165,10 +166,18 @@ public class FileSplitter extends AbstractMessageSplitter {
|
|||||||
|
|
||||||
boolean done;
|
boolean done;
|
||||||
|
|
||||||
|
String line;
|
||||||
|
|
||||||
|
boolean hasNextCalled;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
|
this.hasNextCalled = true;
|
||||||
try {
|
try {
|
||||||
boolean ready = !this.done && bufferedReader.ready();
|
if (this.line == null && !this.done) {
|
||||||
|
this.line = bufferedReader.readLine();
|
||||||
|
}
|
||||||
|
boolean ready = !this.done && this.line != null;
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
if (this.markers) {
|
if (this.markers) {
|
||||||
this.eof = true;
|
this.eof = true;
|
||||||
@@ -180,6 +189,7 @@ public class FileSplitter extends AbstractMessageSplitter {
|
|||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
|
this.done = true;
|
||||||
}
|
}
|
||||||
catch (IOException e1) {}
|
catch (IOException e1) {}
|
||||||
throw new MessageHandlingException(message, "IOException while iterating", e);
|
throw new MessageHandlingException(message, "IOException while iterating", e);
|
||||||
@@ -188,6 +198,10 @@ public class FileSplitter extends AbstractMessageSplitter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object next() {
|
public Object next() {
|
||||||
|
if (!this.hasNextCalled) {
|
||||||
|
hasNext();
|
||||||
|
}
|
||||||
|
this.hasNextCalled = false;
|
||||||
if (this.sof) {
|
if (this.sof) {
|
||||||
this.sof = false;
|
this.sof = false;
|
||||||
return new FileMarker(filePath, Mark.START);
|
return new FileMarker(filePath, Mark.START);
|
||||||
@@ -198,15 +212,14 @@ public class FileSplitter extends AbstractMessageSplitter {
|
|||||||
this.done = true;
|
this.done = true;
|
||||||
return new FileMarker(filePath, Mark.END);
|
return new FileMarker(filePath, Mark.END);
|
||||||
}
|
}
|
||||||
try {
|
if (this.line != null) {
|
||||||
return bufferedReader.readLine();
|
String line = this.line;
|
||||||
|
this.line = null;
|
||||||
|
return line;
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
else {
|
||||||
try {
|
this.done = true;
|
||||||
bufferedReader.close();
|
throw new NoSuchElementException(filePath + " has been consumed");
|
||||||
}
|
|
||||||
catch (IOException e1) {}
|
|
||||||
throw new MessageHandlingException(message, "IOException while iterating", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,9 +104,11 @@ public class FileSplitterTests {
|
|||||||
this.input1.send(new GenericMessage<File>(file));
|
this.input1.send(new GenericMessage<File>(file));
|
||||||
Message<?> receive = this.output.receive(10000);
|
Message<?> receive = this.output.receive(10000);
|
||||||
assertNotNull(receive); //HelloWorld
|
assertNotNull(receive); //HelloWorld
|
||||||
|
assertEquals("HelloWorld", receive.getPayload());
|
||||||
assertEquals(2, receive.getHeaders().get(IntegrationMessageHeaderAccessor.SEQUENCE_SIZE));
|
assertEquals(2, receive.getHeaders().get(IntegrationMessageHeaderAccessor.SEQUENCE_SIZE));
|
||||||
receive = this.output.receive(10000);
|
receive = this.output.receive(10000);
|
||||||
assertNotNull(receive); //äöüß
|
assertNotNull(receive); //äöüß
|
||||||
|
assertEquals("äöüß", receive.getPayload());
|
||||||
assertNull(this.output.receive(1));
|
assertNull(this.output.receive(1));
|
||||||
|
|
||||||
this.input1.send(new GenericMessage<String>(file.getAbsolutePath()));
|
this.input1.send(new GenericMessage<String>(file.getAbsolutePath()));
|
||||||
|
|||||||
Reference in New Issue
Block a user