You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2013/04/17 02:59:43 UTC
svn commit: r1468703 - in /commons/proper/io/trunk/src: changes/changes.xml
main/java/org/apache/commons/io/input/Tailer.java
test/java/org/apache/commons/io/input/TailerTest.java
Author: sebb
Date: Wed Apr 17 00:59:42 2013
New Revision: 1468703
URL: http://svn.apache.org/r1468703
Log:
IO-354 Commons IO Tailer does not respect UTF-8 Charset
Modified:
commons/proper/io/trunk/src/changes/changes.xml
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java
Modified: commons/proper/io/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1468703&r1=1468702&r2=1468703&view=diff
==============================================================================
--- commons/proper/io/trunk/src/changes/changes.xml (original)
+++ commons/proper/io/trunk/src/changes/changes.xml Wed Apr 17 00:59:42 2013
@@ -47,6 +47,9 @@ The <action> type attribute can be add,u
<body>
<!-- The release date is the date RC is cut -->
<release version="2.5" date="2013-??-??" description="New features and bug fixes.">
+ <action issue="IO-354" dev="sebb" type="fix">
+ Commons IO Tailer does not respect UTF-8 Charset.
+ </action>
<action issue="IO-323" dev="sebb" type="fix">
What should happen in FileUtils.sizeOf[Directory] when an overflow takes place?
Added Javadoc.
Modified: commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java?rev=1468703&r1=1468702&r2=1468703&view=diff
==============================================================================
--- commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java (original)
+++ commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/Tailer.java Wed Apr 17 00:59:42 2013
@@ -16,10 +16,12 @@
*/
package org.apache.commons.io.input;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.charset.Charset;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -444,11 +446,11 @@ public class Tailer implements Runnable
* @throws java.io.IOException if an I/O error occurs.
*/
private long readLines(final RandomAccessFile reader) throws IOException {
- final StringBuilder sb = new StringBuilder();
-
+ // Make explicit that the default charset is being used here
+ Charset cset = Charset.defaultCharset();
+ ByteArrayOutputStream lineBuf = new ByteArrayOutputStream(64);
long pos = reader.getFilePointer();
long rePos = pos; // position to re-read
-
int num;
boolean seenCR = false;
while (getRun() && ((num = reader.read(inbuf)) != -1)) {
@@ -457,30 +459,29 @@ public class Tailer implements Runnable
switch (ch) {
case '\n':
seenCR = false; // swallow CR before LF
- listener.handle(sb.toString());
- sb.setLength(0);
+ listener.handle(new String(lineBuf.toByteArray(), cset));
+ lineBuf.reset();
rePos = pos + i + 1;
break;
case '\r':
if (seenCR) {
- sb.append('\r');
+ lineBuf.write('\r');
}
seenCR = true;
break;
default:
if (seenCR) {
seenCR = false; // swallow final CR
- listener.handle(sb.toString());
- sb.setLength(0);
+ listener.handle(new String(lineBuf.toByteArray(), cset));
+ lineBuf.reset();
rePos = pos + i + 1;
}
- sb.append((char) ch); // add character, not its ascii value
+ lineBuf.write(ch);
}
}
-
pos = reader.getFilePointer();
}
-
+ IOUtils.closeQuietly(lineBuf); // not strictly necessary
reader.seek(rePos); // Ensure we can re-read if necessary
return rePos;
}
Modified: commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java?rev=1468703&r1=1468702&r2=1468703&view=diff
==============================================================================
--- commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java (original)
+++ commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/TailerTest.java Wed Apr 17 00:59:42 2013
@@ -16,10 +16,13 @@
*/
package org.apache.commons.io.input;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Writer;
import java.util.ArrayList;
@@ -105,6 +108,42 @@ public class TailerTest extends FileBase
listener.clear();
}
+ public void testMultiByteBreak() throws Exception {
+ final long delay = 50;
+ final File origin = new File(this.getClass().getResource("/test-file-utf8.bin").toURI());
+ final File file = new File(getTestDirectory(), "testMultiByteBreak.txt");
+ createFile(file, 0);
+ final TestTailerListener listener = new TestTailerListener();
+ final String osname = System.getProperty("os.name");
+ final boolean isWindows = osname.startsWith("Windows");
+ tailer = new Tailer(file, listener, delay, false, isWindows);
+ final Thread thread = new Thread(tailer);
+ thread.start();
+
+
+ BufferedReader reader = null;
+ try{
+ List<String> lines = new ArrayList<String>();
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(origin)));
+ String line = null;
+ while((line = reader.readLine()) != null){
+ write(file, line);
+ lines.add(line);
+ }
+
+ final long testDelayMillis = delay * 10;
+ Thread.sleep(testDelayMillis);
+ List<String> tailerlines = listener.getLines();
+ assertEquals("line count",lines.size(),tailerlines.size());
+ for(int i = 0,len = lines.size();i<len;i++){
+ assertEquals("line "+i, lines.get(i), tailerlines.get(i));
+ }
+ }finally{
+ tailer.stop();
+ IOUtils.closeQuietly(reader);
+ }
+ }
+
public void testTailerEof() throws Exception {
// Create & start the Tailer
final long delay = 50;