Spring batch 处理windows 平台TXT换行 CRLF 问题

windows采用回车+换行CR/LF表示下一行,UNIX/Linux使用换行符LF表示下一行,MAC OS系统使用用回车符CR表示下一行。CR使用符号’\r’表示, ASCII码是13;LF使用’\n’符号表示, ASCII码是10。各系统使用不同的符号表示下一行,这就给日常处理文档带来了麻烦,例如一些程序读行只能处理LF换行的文件。遇到换行符问题,如果不能修改程序,那么只能编辑文件替换换行符。

window是只认\r\n 联在一起的情况

所以数据在window的文本编辑器里看是一行的数据,在notepad++打开却是


spring batch 读取txt 默认使用的bufferReader.readLine()

默认的bufferReader 是碰到\r,\n就自动认为下一行

/**     * Reads a line of text.  A line is considered to be terminated by any one     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return     * followed immediately by a linefeed.     *     * @return     A String containing the contents of the line, not including     *             any line-termination characters, or null if the end of the     *             stream has been reached     *     * @exception  IOException  If an I/O error occurs     *     * @see java.nio.file.Files#readAllLines     
*/    
public String () throws IOException {        return readLine(false);    }

spring 默认的DefaultBufferedReaderFactory 使用该对象.

另外还提供了一个支持自定义lineEnd的reader,那就是

/** * A {@link BufferedReaderFactory} useful for reading simple binary (or text) * files with no line endings, such as those produced by mainframe copy books. * The reader splits a stream up across fixed line endings (rather than the * usual convention based on plain text). The line endings are discarded, just * as with the default plain text implementation. *  * @author Dave Syer *  * @since 2.1 */
public class SimpleBinaryBufferedReaderFactory implements BufferedReaderFactory { 	
/**	 * The default line ending value.	 */	
private static final String DEFAULT_LINE_ENDING = "\n"; 	
private String lineEnding = DEFAULT_LINE_ENDING; 	
/**	 * @param lineEnding	 */	
public void (String lineEnding) {		this.lineEnding = lineEnding;	}

这下我们只要把lineEnding设置成"\r\n"就可以了。

于是我兴致匆匆的来了

<bean id="txtItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" abstract="true">        
    <property name="resource" value="#{jobParameters['filePath']}"/>        
    <property name="encoding" value="#{jobParameters['fileEncoding']==null?'UTF-8':jobParame        ters['fileEncoding']}"/>        
    <property name="bufferedReaderFactory">            
        <bean class="org.springframework.batch.item.file.SimpleBinaryBufferedReaderFactory">                <property name="lineEnding" value="\r\n"/>            
        </bean>        
    </property>    
</bean>

    结果是令人失望的,debug 了半天发现原来注入的“\r\n”被注入成了"\\r\\n",原来的2个char,变成了4个char,导致里面的判断不能用。

private boolean isEndOfLine(StringBuilder buffer, StringBuilder candidate, int next) {
 			if (next == -1) {				return true;			} 			
 			char c = (char) next;			
 			if (ending.charAt(0) == c || candidate.length() > 0) {
 							candidate.append(c);			} 			
 			if (candidate.length() == 0) {				
 			    buffer.append(c);				return false;			} 
 			boolean end = ending.equals(candidate.toString());			
 			if (end) {				candidate.delete(0, candidate.length());			}			    else if (candidate.length() >= ending.length()) {				
 			buffer.append(candidate);				
 			candidate.delete(0, candidate.length());			} 			
 			return end; 		}	
 	}

折腾了<![CDATA[\r\n]]>,也不行。无奈,只好继承扩展该类,写实

public class WindowBinaryBufferedReaderFactory extends SimpleBinaryBufferedReaderFactory {     public WindowBinaryBufferedReaderFactory(){        super();        super.setLineEnding("\r\n");    }}

这样,解析总算正常。



你可能感兴趣的:(Spring batch 处理windows 平台TXT换行 CRLF 问题)