📄 importreaddata.java
字号:
return lineNumber; } /**the way we read the next row from input file depends on it's format * @exception Exception if there is an error */ boolean readNextRow(String[] returnStringArray) throws Exception { boolean readVal; int idx; if (!streamOpenForReading) { openFile(); //as earlier, ignore the first row if it's colum definition //do uppercase because the ui shows the values as True and False if (hasColumnDefinition){ ignoreFirstRow(); } } if (formatCode == DEFAULT_FORMAT_CODE) readVal=readNextDelimitedRow(returnStringArray); else readVal=readNextFixedRow(returnStringArray); return readVal; } // made this a field so it isn't inited for each row, just // set and cleared on the rows that need it (the last row // in a file, typically, so it isn't used much) private boolean haveSep = true; //read the specified column width for each column private boolean readNextFixedRow(String[] returnStringArray) throws Exception { // readLength is how many bytes it has read so far int readLength = 0; int totalLength = 0; // keep reading until rolWidth bytes have been read while ((readLength += bufferedReader.read(tempString, readLength, rowWidth-readLength)) < rowWidth) { if (readLength == totalLength-1) {// EOF if ( readLength == -1) { // no row, EOF return false; } else { // it's only a bad read if insufficient data was // returned; missing the last record separator is ok if (totalLength != rowWidth - recordSeparator.length) { throw LoadError.unexpectedEndOfFile(lineNumber+1); } else { haveSep = false; break; } } } // else, some thing is read, continue until the whole column is // read totalLength = readLength; } int colStart = 0; for (int i=0; i< numberOfColumns; i++) { int colWidth = columnWidths[i]; if (colWidth == 0) //if column width is 0, return null returnStringArray[i] = null; else { // if found nullstring, return it as null value String checkAgainstNullString = new String(tempString, colStart, colWidth); if (checkAgainstNullString.trim().equals(nullString)) returnStringArray[i] = null; else returnStringArray[i] = checkAgainstNullString; colStart += colWidth; } } //if what we read is not recordSeparator, throw an exception if (haveSep) { for (int i=(recordSeparatorLength-1); i>=0; i--) { if (tempString[colStart+i] != recordSeparator[i]) throw LoadError.recordSeparatorMissing(lineNumber+1); } } else haveSep = true; // reset for the next time, if any. lineNumber++; return true; } //by this time, we know number of columns that make up a row in this data file //so first look for number of columns-1 field delimites and then look for record //delimiter private boolean readNextDelimitedRow(String[] returnStringArray) throws Exception { int upperLimit = numberOfColumns-1; //reduce # field accesses //no data in the input file for some reason if (upperLimit < 0) return false; //look for number of columns - 1 field separators for (int i = 0; i<upperLimit; i++) { if (!readNextToken(fieldSeparator, 0, fieldSeparatorLength, false) ) { if (i == 0) // still on the first check return false; else throw LoadError.unexpectedEndOfFile(lineNumber+1); } //following is to take care of a case like "aa"aa This will result in an //error. Also a case like "aa" will truncate it to just aa. valid blank //chars are ' ' '\r' '\t' if (stopDelimiterPosition!=0 && ((stopDelimiterPosition) != totalCharsSoFar)) { for (int k=stopDelimiterPosition+1; k<totalCharsSoFar; k++) { // alc: should change || to && since || case is never true -- // currentChar can't be three different things at once. // alc: why no \n? BTW, \r and \n should be replaced // or amended with the first char of line.separator... //char currentChar = currentToken[k]; //if (currentChar != ' ' && currentChar != '\r' && currentChar != '\t') // use String.trim()'s definition of whitespace. // i18n - check for whitespace - avoid doing a hard coded // character check and use the isWhitespace method to cover all // the Unicode options if (Character.isWhitespace(currentToken[k])==false) { throw LoadError.dataAfterStopDelimiter(lineNumber+1, i+1); } } totalCharsSoFar = stopDelimiterPosition; } //totalCharsSoFar can become -1 in readNextToken if (totalCharsSoFar != -1) { returnStringArray[i] = new String(currentToken, positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); } else returnStringArray[i] = null; } //look for record separator for the last column's value //if I find endoffile and the it's only one column table, then it's a valid endoffile //case. Otherwise, it's an error case. Without the following check for the return value //of readNextToken, import was going into infinite loop for a table with single column //import. end-of-file was getting ignored without the following if. if (!readNextToken(recordSeparator, 0, recordSeparatorLength, true) ) { if (upperLimit == 0) return false; else throw LoadError.unexpectedEndOfFile(lineNumber+1); } //following is to take care of a case like "aa"aa This will result in an //error. Also a case like "aa" will truncate it to just aa. valid blank //chars are ' ' '\r' '\t' if (stopDelimiterPosition!=0 && (stopDelimiterPosition != totalCharsSoFar)) { for (int i=stopDelimiterPosition+1; i<totalCharsSoFar; i++) { // alc: should change || to && since || case is never true -- // currentChar can't be three different things at once. // alc: why no \n? BTW, \r and \n should be replaced // or amended with the first char of line.separator... //char currentChar = currentToken[i]; //if (currentChar != ' ' && currentChar != '\r' && currentChar != '\t') // use String.trim()'s definition of whitespace. // i18n - check for whitespace - avoid doing a hard coded character // check and use the isWhitespace method to cover all the Unicode // options if (Character.isWhitespace(currentToken[i])==false) { throw LoadError.dataAfterStopDelimiter(lineNumber+1, numberOfColumns); } } totalCharsSoFar = stopDelimiterPosition; } //to be able to read delimited files that have a delimeter at the end, //we have to reduce totalCharsSoFar by one when it is last column. //Otherwise last delimeter becomes part of the data. if (hasDelimiterAtEnd) { if (!(fieldStopDelimiterLength > 0)) { //if there is no field stop delimeter specified, //hopefully fieldStopDelimiterLength will not be >0 //there is weird behavior in the code that makes it read the last //delimeter as part of the last column data, so this forces us to //reduce number of read chars only if there is data stop delimeter //Only if it is the last column: //if (fieldStopDelimiter==null){ --totalCharsSoFar; //} } } if (totalCharsSoFar != -1) { /* This is a hack to fix a problem: When there is missing data in columns and hasDelimiterAtEnd==true, then the last delimiter was read as the last column data. Hopefully this will tackle that issue by skipping the last column which is in this case just the delimiter. We need to be careful about the case when the last column data itself is actually same as the delimiter. */ if (!hasDelimiterAtEnd) {//normal path: returnStringArray[upperLimit] = new String(currentToken, positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); } else if (totalCharsSoFar==fieldSeparatorLength && isFieldSep(currentToken) ){ //means hasDelimiterAtEnd==true and all of the above are true String currentStr = new String(currentToken, positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); if (currentToken[totalCharsSoFar+1]==fieldStopDelimiter[0]){ returnStringArray[upperLimit] = currentStr; } else { returnStringArray[upperLimit] = null; } } else { //means hasDelimiterAtEnd==true and previous case is wrong. if (totalCharsSoFar>0) { returnStringArray[upperLimit] = new String(currentToken, positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); } else{ returnStringArray[upperLimit] = null; } } } else returnStringArray[upperLimit] = null; lineNumber++; return true; } //tells if a char array is field separator: private boolean isFieldSep(char[] chrArray){ for (int i=0; i<chrArray.length && i<fieldSeparatorLength; i++){ if (chrArray[i]!=fieldSeparator[i]) return false; } return true; } //read one column's value at a time boolean readNextToken(char[] delimiter, int delimiterIndex, int delimiterLength, boolean isRecordSeperator) throws Exception { int nextChar; fieldStopDelimiterIndex = 0; fieldStartDelimiterIndex = 0; totalCharsSoFar = 0; //at the start of every new token, make white space in front count 0 positionOfNonWhiteSpaceCharInFront = 0; stopDelimiterPosition = 0; foundStartAndStopDelimiters = false; foundStartDelimiter = false; int returnValue; while (true) { nextChar = bufferedReader.read(); if (nextChar == -1) //end of file return false; //read the character into the token holder. If token holder reaches it's capacity, //double it's capacity currentToken[totalCharsSoFar++] = (char)nextChar; //check if character read is white space char in front checkForWhiteSpaceInFront(); if (totalCharsSoFar == currentTokenMaxSize) { currentTokenMaxSize = currentTokenMaxSize * 2; char[] tempArray = new char[currentTokenMaxSize]; System.arraycopy(currentToken, 0, tempArray, 0, totalCharsSoFar); currentToken = tempArray; } returnValue = lookForPassedSeparator(delimiter, delimiterIndex, delimiterLength, nextChar, isRecordSeperator); if (returnValue == -1) { //if no stop delimiter found that "" this means null //also if no stop delimiter found then get rid of spaces around the token if (!foundStartAndStopDelimiters ) { if (totalCharsSoFar == 0) totalCharsSoFar = -1; else { //get the count of white spaces from back and subtract that and white spaces in //the front from the characters read so far so that we ignore spaces around the //token. checkForWhiteSpaceInBack(); totalCharsSoFar = totalCharsSoFar - positionOfNonWhiteSpaceCharInFront - positionOfNonWhiteSpaceCharInBack; } } return true; } delimiterIndex = returnValue; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -