1 回答

TA貢獻(xiàn)2021條經(jīng)驗(yàn) 獲得超8個贊
讀取器會按照這樣的協(xié)議來讀?。何募^是一個字符串列表,而記錄集是一個字符串列表的列表。讀取器接受一個java.io.Reader對象用為讀取來源。 先從讀取文件頭開始。讀取文件頭的算法如下: - 打開資源準(zhǔn)備讀取。 - 讀取第一行然后解析 - 將行按分隔符分割。 - 將該行轉(zhuǎn)化成一個字符串列表后返回 下面是它的實(shí)現(xiàn)。
class CsvReader {
private static final String SEPARATOR = ";";
private final Reader source;
CsvReader(Reader source) {
this(source);
}
List<String> readHeader() {
try (BufferedReader reader = new BufferedReader(source)) {
return reader.lines()
.findFirst()
.map(line -> Arrays.asList(line.split(SEPARATOR)))
.get();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
相當(dāng)簡單,自我解釋型的。類似的,創(chuàng)建了一個方法來讀取所有的記錄。讀取記錄的算法如下:
打開資源文件進(jìn)行讀取
跳過首行
用分隔符分割行。
對每行應(yīng)用一個map操作,將行映射到一個字符串列表
下面是它的實(shí)現(xiàn):
class CsvReader {
List<List<String>> readRecords() {
try (BufferedReader reader = new BufferedReader(source)) {
return reader.lines()
.substream(1)
.map(line -> Arrays.asList(line.split(separator)))
.collect(Collectors.toList());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
會注意到兩個方法中的map是幾乎一樣的。事實(shí)上,它可以提取到一個變量里面:
Function<String, List<String>> mapper
= line -> Arrays.asList(line.split(separator));
我寫了個測試來完成整個過程。
public class CsvReaderTest {
@Test
public void readsHeader() {
CsvReader csvReader = createCsvReader();
List<String> header = csvReader.readHeader();
assertThat(header)
.contains("username")
.contains("visited")
.hasSize(2);
}
@Test
public void readsRecords() {
CsvReader csvReader = createCsvReader();
List<List<String>> records = csvReader.readRecords();
assertThat(records)
.contains(Arrays.asList("jdoe", "10"))
.contains(Arrays.asList("kolorobot", "4"))
.hasSize(2);
}
private CsvReader createCsvReader() {
try {
Path path = Paths.get("src/test/resources", "sample.csv");
Reader reader = Files.newBufferedReader(
path, Charset.forName("UTF-8"));
return new CsvReader(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
添加回答
舉報