从文件的第一行读取时,有什么方法可以检索 cvsMapper 使用的 csvSchema 吗?
is there any way to retrieve the csvSchema used by a cvsMapper when it's read from the first line of a file?
我设置了 CsvSchema
和 CsvMapper
来读取第一行列名的 CSV
文件。
我需要能够对数据进行一些处理,更改特定字段,然后在保留列顺序的同时写回数据。
我假设 CsvMapper
有一个从第一行创建的内部模式,因为地图有所有正确的 key-value
对。
那么,有没有什么方法可以使用 CsvMapper
的 writer
函数来使用该模式来排序输出数据?
CsvSchema schema = CsvSchema.emptySchema().withHeader();
CsvMapper mapper = new CsvMapper();
MappingIterator<Map<String, String>> it = this.mapper.readerFor(Map.class)
.with(this.schema)
.readValues(stream);
现在,我在第一列数据上得到 "Unrecognized column" 的 CsvMappingException
,所以看起来它没有使用架构。
您可以使用从输入文件中读取的第一行中的架构构建 SequenceWriter
。 Jackson
后面用了LinkedHashMap,所以,顺序是保持的。假设您的 CSV
输入包含:
C1,name,type
I1,John,T1
I2,Adam,T2
您可以读取、更新和写入控制台,如下例所示:
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SequenceWriter;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class CsvApp {
private CsvMapper csvMapper = new CsvMapper();
private void handle() throws Exception {
File csvFile = new File("./resource/test.csv").getAbsoluteFile();
CsvSchema schema = CsvSchema.emptySchema().withHeader();
MappingIterator<Map<String, String>> iterator = csvMapper.readerFor(Map.class).with(schema).readValues(csvFile);
SequenceWriter writer = null;
while (iterator.hasNext()) {
final Map<String, String> row = iterator.next();
if (writer == null) {
writer = createWriter(row).writeValues(System.out);
}
// do something ...
for (Map.Entry<String, String> item : row.entrySet()) {
row.replace(item.getKey(), item.getValue() + "U");
}
// write back
writer.write(row);
}
close(writer);
}
private ObjectWriter createWriter(Map<String, String> row) {
CsvSchema.Builder writeSchema = new CsvSchema.Builder();
writeSchema.setUseHeader(true);
row.keySet().forEach(writeSchema::addColumn);
return csvMapper.writerFor(Map.class).with(writeSchema.build());
}
private void close(Closeable closeable) throws IOException {
if (closeable != null) {
closeable.close();
}
}
public static void main(String[] args) throws Exception {
new CsvApp().handle();
}
}
以上代码打印:
C1,name,type
I1U,JohnU,T1U
I2U,AdamU,T2U
另请参阅:
我设置了 CsvSchema
和 CsvMapper
来读取第一行列名的 CSV
文件。
我需要能够对数据进行一些处理,更改特定字段,然后在保留列顺序的同时写回数据。
我假设 CsvMapper
有一个从第一行创建的内部模式,因为地图有所有正确的 key-value
对。
那么,有没有什么方法可以使用 CsvMapper
的 writer
函数来使用该模式来排序输出数据?
CsvSchema schema = CsvSchema.emptySchema().withHeader();
CsvMapper mapper = new CsvMapper();
MappingIterator<Map<String, String>> it = this.mapper.readerFor(Map.class)
.with(this.schema)
.readValues(stream);
现在,我在第一列数据上得到 "Unrecognized column" 的 CsvMappingException
,所以看起来它没有使用架构。
您可以使用从输入文件中读取的第一行中的架构构建 SequenceWriter
。 Jackson
后面用了LinkedHashMap,所以,顺序是保持的。假设您的 CSV
输入包含:
C1,name,type
I1,John,T1
I2,Adam,T2
您可以读取、更新和写入控制台,如下例所示:
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SequenceWriter;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class CsvApp {
private CsvMapper csvMapper = new CsvMapper();
private void handle() throws Exception {
File csvFile = new File("./resource/test.csv").getAbsoluteFile();
CsvSchema schema = CsvSchema.emptySchema().withHeader();
MappingIterator<Map<String, String>> iterator = csvMapper.readerFor(Map.class).with(schema).readValues(csvFile);
SequenceWriter writer = null;
while (iterator.hasNext()) {
final Map<String, String> row = iterator.next();
if (writer == null) {
writer = createWriter(row).writeValues(System.out);
}
// do something ...
for (Map.Entry<String, String> item : row.entrySet()) {
row.replace(item.getKey(), item.getValue() + "U");
}
// write back
writer.write(row);
}
close(writer);
}
private ObjectWriter createWriter(Map<String, String> row) {
CsvSchema.Builder writeSchema = new CsvSchema.Builder();
writeSchema.setUseHeader(true);
row.keySet().forEach(writeSchema::addColumn);
return csvMapper.writerFor(Map.class).with(writeSchema.build());
}
private void close(Closeable closeable) throws IOException {
if (closeable != null) {
closeable.close();
}
}
public static void main(String[] args) throws Exception {
new CsvApp().handle();
}
}
以上代码打印:
C1,name,type
I1U,JohnU,T1U
I2U,AdamU,T2U
另请参阅: