import java.lang.invoke.MethodHandles;import java.lang.invoke.VarHandle;import java.nio.ByteOrder;import java.nio.charset.StandardCharsets;// # CSV编码规则// - ','间隔列;"\r\n"间隔行(最后一行可能没有换行符结尾)// - 文本含有','或'\r',或以'"'开头,则整个内容两边加'"'// - 两边加'"'的情况下,里面的每个'"'改成两个// # 简单&高性能的实现,需要严格按以上规则编码,需要JDK9以上public final class FastCsv {private static final VarHandle longLeVH = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN);private FastCsv() {}public interface Handler {void onCell(int pos, int len); // len<0: next line}public static void parseCsv(final byte[] csv, final Handler handler) { // csv maybe modifiedparseCsv(csv, 0, csv.length, handler);}public static void parseCsv(final byte[] csv, int pos, final int len, final Handler handler) { // csv maybe modifiedfinal int end = pos + len;if (len >= 3 && csv[pos] == -17 && csv[pos + 1] == -69 && csv[pos + 2] == -65) // check UTF-8 BOMpos += 3; // \xef\xbb\xbffor (; ; ) {if (pos >= end) {handler.onCell(end, -1);return;}int b = csv[pos];if (b == ',') {handler.onCell(pos++, 0); // ,if (pos >= end) {handler.onCell(pos, 0);handler.onCell(end, -1);return;}} else if (b == '\r') {handler.onCell(pos, 0);handler.onCell(pos, -1);if ((pos += 2) >= end) // \r\nreturn;} else if (b == '"') {int e = scanQuot(csv, ++pos, end), p = e, q;while ((q = e + 1) < end && (b = csv[q]) == '"') {final int n = (e = scanQuot(csv, q + 1, end)) - q;System.arraycopy(csv, q, csv, p, n);p += n;}handler.onCell(pos, p - pos);if (b == ',')pos = e + 2; // ",else { // '\r' | <EOF>handler.onCell(e + 1, -1);if ((pos = e + 3) >= end) // "\r\n | "<EOF>return;}} else {final int e = scanCellEnd(csv, pos + 1, end);handler.onCell(pos, e - pos);if (e < end && csv[e] == ',')pos = e + 1; // ,else { // '\r' | <EOF>handler.onCell(e, -1);if ((pos = e + 2) >= end) // \r\nreturn;}}}}private static int scanQuot(final byte[] csv, int pos, final int end) {for (; pos + 8 <= end; pos += 8) {long p = (long)longLeVH.get(csv, pos) ^ 0x22222222_22222222L; // '"'p = (p - 0x01010101_01010101L) & ~p & 0x80808080_80808080L;if (p != 0)return pos + (Long.numberOfTrailingZeros(p) >> 3);}for (; ; pos++) {if (pos >= end || csv[pos] == '"')return pos;}}private static int scanCellEnd(final byte[] csv, int pos, final int end) {for (; pos + 8 <= end; pos += 8) {final long b8 = (long)longLeVH.get(csv, pos);long p0 = b8 ^ 0x2c2c2c2c_2c2c2c2cL; // ','long p1 = b8 ^ 0x0d0d0d0d_0d0d0d0dL; // '\r'p0 = (p0 - 0x01010101_01010101L) & ~p0 & 0x80808080_80808080L;p1 = (p1 - 0x01010101_01010101L) & ~p1 & 0x80808080_80808080L;if ((p0 |= p1) != 0)return pos + (Long.numberOfTrailingZeros(p0) >> 3);}for (int b; ; pos++) {if (pos >= end || (b = csv[pos]) == ',' || b == '\r')return pos;}}static void main() {/* ----------------------------|ab|a,b|"ab"|a"b| ab |"a,b"|----------------------------|a||b|----------------------------||||||ab|----------------------------|ab"|||||a"b|----------------------------*/final byte[] csv = """ab,"a,b",""\"ab""\",a"b, ab ,""\"a,b""\"\r"ab",,,,,\r,,,,,"ab"\rab",,,,,"a""b\"""".getBytes(StandardCharsets.UTF_8);System.out.println("---");System.out.println(new String(csv, StandardCharsets.UTF_8));System.out.println("---");final StringBuilder sb = new StringBuilder();parseCsv(csv, (pos, len) -> {if (len < 0)sb.append("<EOL>\n");elsesb.append('[').append(new String(csv, pos, len, StandardCharsets.UTF_8)).append(']');});final String out = sb.toString();System.out.println(out);System.out.println("===");System.out.println("check: " + out.equals("""[ab][a,b]["ab"][a"b][ ab ]["a,b"]<EOL>[ab][][][][][]<EOL>[][][][][][ab]<EOL>[ab"][][][][][a"b]<EOL>"""));}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。