rdf-file:读、写、合并示例

<dependency><groupId>com.alipay.rdf.file</groupId><artifactId>rdf-file-core</artifactId><version>2.2.10</version>
</dependency>

一:读

1.1 原始读

原始文件读取就是不需要根据协议布局模板和数据定义模板来把数据转换成对象。

1.readRow(Class<?> requiredType) 如果文件是分隔符分割的支持读取, requiredType只能是String[].class。
2.支持readLine()。
3.不支持 readHead, readTail,getSummary()方法。
4.用户完全可用jdk的Reader工具,组件实现完全是为了接口统一。

String path = new ClassPathResource("data1.txt").getFile().getPath();
FileConfig fileConfig = new FileConfig(path, "templates/template1.json", new StorageConfig("nas"));
fileConfig.setType(FileCoreToolContants.RAW_READER);FileReader fileReader = FileFactory.createReader(fileConfig);
String[] row = null;
while (null != (row = fileReader.readRow(String[].class))) {System.out.println(row);
}
fileReader.close();fileReader = FileFactory.createReader(fileConfig);
String line = null;
while (null != (line = fileReader.readLine())) {System.out.println(line);
}
fileReader.close();

1.2 简单读取

String path = new ClassPathResource("data1.txt").getFile().getPath();
FileConfig config = new FileConfig(path, "templates/template1.json", new StorageConfig("nas"));
FileReader fileReader = FileFactory.createReader(config);try {Map<String, Object> head = fileReader.readHead(HashMap.class);System.out.println(head);Map<String, Object> row = null;while (null != (row = fileReader.readRow(HashMap.class))) {System.out.println(row);}Map<String, Object> tail = fileReader.readTail(HashMap.class);System.out.println(tail);
} finally {fileReader.close();
}

1.3 汇总读

String path = new ClassPathResource("data2.txt").getFile().getPath();
FileConfig config = new FileConfig(path, "templates/template2.json", new StorageConfig("nas"));
config.setSummaryEnable(true);
FileReader fileReader = FileFactory.createReader(config);try {Map<String, Object> head = fileReader.readHead(HashMap.class);BigDecimal totalAmount = (BigDecimal)head.get("totalAmount");Map<String, Object> tail = fileReader.readTail(HashMap.class);BigDecimal  tailAmount = (BigDecimal)tail.get("tailAmount");Map<String, Object> row = null;while (null != (row = fileReader.readRow(HashMap.class))) {System.out.println(row);}Summary summary = fileReader.getSummary();for (SummaryPair pair : summary.getHeadSummaryPairs()) {BigDecimal summaryValue = (BigDecimal) pair.getSummaryValue();BigDecimal headValue = (BigDecimal) pair.getHeadValue();pair.isSummaryEquals();}for (SummaryPair  pair : summary.getTailSummaryPairs()) {BigDecimal  summaryValue = (BigDecimal) pair.getSummaryValue(); //数据字段汇总后的值BigDecimal tailValue = (BigDecimal) pair.getTailValue(); //文件尾中的汇总值pair.isSummaryEquals(); // 汇总的值是否一致}
} finally {fileReader.close();
}

1.4 排序

组件可以根据文件一个或者几个字段来对文件记录进行排序。
排序后可以是有序的分片文件,也可以合成一个完整的有序文件。

1.4.1 单文件排序

{"head":["totalCount|总笔数|Required|BigDecimal","totalAmount|总金额|BigDecimal|Required"],"body":["seq|流水号","instSeq|基金公司订单号|Required","gmtApply|订单申请时间|Date:yyyy-MM-dd HH:mm:ss","date|普通日期|Date:yyyyMMdd","dateTime|普通日期时间|Date:yyyyMMdd HH:mm:ss","applyNumber|普通数字|BigDecimal","amount|金额|BigDecimal","age|年龄|Integer","longN|长整型|Long","bol|布尔值|Boolean","memo|备注"],"protocol":"DE","lineBreak":"\r\n","summaryColumnPairs":["totalAmount|amount"]
}
总笔数:100|总金额:300.03
流水号|基金公司订单号|订单申请时间|普通日期|普通日期时间|普通数字|金额|年龄|长整型|布尔值|备注
seq_17|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|8|12345|true|备注1de2
seq_23|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注2de2
seq_12|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|6|12345|true|备注3de2
seq_80|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|30|12345|true|备注4de2
seq_77|inst_seq_77|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|26|12345|true|备注5de2
seq_56|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|38|12345|true|备注6de2
seq_55|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|35|12345|true|备注7de2
seq_33|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|20|12345|true|备注8de2
seq_7|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|18|12345|true|备注9de2
String path = new ClassPathResource("data4.txt").getFile().getPath();
FileConfig fileConfig = new FileConfig(path, "templates/template4.json", new StorageConfig("nas"));
String sortTempPath = "/Users/mengday/Temp/springboot-rdffile/";
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 2, TimeUnit.MINUTES, new LinkedBlockingQueue());
SortConfig sortConfig = new SortConfig(sortTempPath, SortConfig.SortTypeEnum.ASC, executor, SortConfig.ResultFileTypeEnum.FULL_FILE_PATH);
sortConfig.setResultFileName("sort_result");
sortConfig.setSliceSize(1024);
sortConfig.setSortIndexes(new int[]{7});FileSorter fileSorter = FileFactory.createSorter(fileConfig);
SortResult sortResult = fileSorter.sort(sortConfig);
System.out.println(sortResult);

1.4.2 多文件排序

FileConfig fileConfig = new FileConfig("templates/template4.json", new StorageConfig("nas"));
// 多文件排序
fileConfig.setType(FileCoreToolContants.PROTOCOL_MULTI_FILE_SORTER);String[] sourceFilePaths = new String[2];
sourceFilePaths[0] = new ClassPathResource("data4.txt").getFile().getPath();
sourceFilePaths[1] = new ClassPathResource("data5.txt").getFile().getPath();String sortTempPath = "/Users/mengday/Temp/springboot-rdffile/";
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 5, TimeUnit.MINUTES, new LinkedBlockingQueue());
SortConfig sortConfig = new SortConfig(sortTempPath, SortConfig.SortTypeEnum.ASC, executor, SortConfig.ResultFileTypeEnum.FULL_FILE_PATH);
sortConfig.setSourceFilePaths(sourceFilePaths);
sortConfig.setResultFileName("test_sort");
sortConfig.setSliceSize(1024);
sortConfig.setSortIndexes(new int[]{0, 1});FileSorter fileSorter = FileFactory.createSorter(fileConfig);
SortResult sortResult = fileSorter.sort(sortConfig);
System.out.println(sortResult);

1.4.3 读文件之单文件有序读

先排序,再读。

ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 5, TimeUnit.MINUTES, new LinkedBlockingQueue());
String sortTempPath = "/Users/mengday/Temp/springboot-rdffile/";
String path = new ClassPathResource("data4.txt").getFile().getPath();
FileConfig fileConfig = new FileConfig(path, "templates/template4.json", new StorageConfig("nas"));
fileConfig.setType(FileCoreToolContants.PROTOCOL_MULTI_FILE_SORTER);ProtocolFilesSortedReader reader = (ProtocolFilesSortedReader)FileFactory.createReader(fileConfig);
FileSorter fileSorter = (FileSorter) reader;
SortConfig sortConfig = new SortConfig(sortTempPath, SortConfig.SortTypeEnum.ASC, executor, SortConfig.ResultFileTypeEnum.SLICE_FILE_PATH);
sortConfig.setSliceSize(256);
sortConfig.setSortIndexes(new int[]{0, 1});
fileSorter.sort(sortConfig);HashMap<String, Object> head = reader.readHead(HashMap.class);
System.out.println(head);
Map<String, Object> row = null;
int i = 0;
while (null != (row = reader.readRow(HashMap.class))) {System.out.println(row.get("seq"));
}

1.4.4 多文件有序读

FileConfig fileConfig = new FileConfig("templates/template5.json", new StorageConfig("nas"));fileConfig.setType(FileCoreToolContants.PROTOCOL_MULTI_FILE_SORTER);
ProtocolFilesSortedReader reader = (ProtocolFilesSortedReader) FileFactory.createReader(fileConfig);FileSorter fileSorter = (FileSorter) reader;ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 5, TimeUnit.MINUTES, new LinkedBlockingQueue());String sortTempPath = new ClassPathResource("temp").getFile().getPath();String[] sourceFilePath = {new ClassPathResource("data51.txt").getFile().getPath(),new ClassPathResource("data52.txt").getFile().getPath(),new ClassPathResource("data53.txt").getFile().getPath()};SortConfig sortConfig = new SortConfig(sortTempPath, SortConfig.SortTypeEnum.ASC, executor, SortConfig.ResultFileTypeEnum.SLICE_FILE_PATH);
sortConfig.setResultFileName("testSort");
sortConfig.setSliceSize(1024);
sortConfig.setSortIndexes(new int[]{0, 1});
sortConfig.setSourceFilePaths(sourceFilePath);
fileSorter.sort(sortConfig);HashMap<String, Object> head = reader.readHead(HashMap.class);
System.out.println(head);System.out.println("--------------------------------------");
HashMap<String, Object> tail = reader.readTail(HashMap.class);
System.out.println(tail);Map<String, Object> row = null;
int i = 0;
while (null != (row = reader.readRow(HashMap.class))) {System.out.println(row.get("seq"));
}

1.5 分片读取

分片的文件名一般都是有规律的,比如放在一个文件夹中,文件的名字有相同的前缀,后缀可以使用累加编号(例如从0或者从1开始)。例如 test-0.txttest-1.txt, test-2.txt 这样在合并文件时只要知道分片总数量就能拿到所有文件的路径了。

1.5.1 文件结构分割

String path = new ClassPathResource("data3.txt").getFile().getPath();
FileConfig config = new FileConfig(path, "templates/template3.json", new StorageConfig("nas"));// 创建分解分割器
FileSplitter splitter = FileFactory.createSplitter(config.getStorageConfig());
// 获取头分片
FileSlice headSlice = splitter.getHeadSlice(config);// 读取头分片
FileConfig headConfig = config.clone();
headConfig.setPartial(headSlice.getStart(), headSlice.getLength(), headConfig.getFileDataType());
FileReader headReader = FileFactory.createReader(headConfig);
try {Map<String, Object> head = headReader.readHead(HashMap.class);System.out.println(head);
} finally {headReader.close();
}FileSlice bodySlice = splitter.getBodySlice(config);
FileConfig bodyConfig = config.clone();
bodyConfig.setPartial(bodySlice.getStart(), bodySlice.getLength(), bodySlice.getFileDataType());
FileReader bodyReader = FileFactory.createReader(bodyConfig);
try {Map<String, Object> row = null;while (null != (row = bodyReader.readRow(HashMap.class))) {System.out.println(Thread.currentThread().getName() + ":" + row);}
} finally {bodyReader.close();
}// 获取tail分片
FileSlice tailSlice = splitter.getTailSlice(config);
// 读取tail分片
FileConfig tailConfig = config.clone();
tailConfig.setPartial(tailSlice.getStart(), tailSlice.getLength(), tailSlice.getFileDataType());
FileReader tailReader = FileFactory.createReader(tailConfig);
try {Map<String, Object> tail = tailReader.readTail(HashMap.class);System.out.println(tail);
} finally {tailReader.close();
}

1.5.2 body按大小分片

String path = new ClassPathResource("data3.txt").getFile().getPath();
FileConfig config = new FileConfig(path, "templates/template3.json", new StorageConfig("nas"));
final FileSplitter splitter = FileFactory.createSplitter(config.getStorageConfig());
// body 按大小分片
final List<FileSlice> bodySlices = splitter.getBodySlices(config, 256);// 分片读取数据
for (FileSlice slice : bodySlices) {final FileConfig sliceConfig = config.clone();sliceConfig.setPartial(slice.getStart(), slice.getLength(), slice.getFileDataType());final FileReader reader = FileFactory.createReader(sliceConfig);try {Map<String, Object> row = null;while (null != (row = reader.readRow(HashMap.class))) {System.out.println(row);}} finally {reader.close();}
}

1.5.3 先分片再根据分片读

String filePath = new ClassPathResource("data2.txt").getFile().getPath();
FileConfig fileConfig = new FileConfig(filePath, "templates/template2.json", new StorageConfig("nas"));// 对body分片
FileSplitter fileSplitter = FileFactory.createSplitter(fileConfig.getStorageConfig());
List<FileSlice> bodySlices = fileSplitter.getBodySlices(fileConfig, 256);
System.out.println(bodySlices);FileConfig bodyConfig = new FileConfig(filePath, "templates/template2.json", new StorageConfig("nas"));
for (FileSlice bodySlice : bodySlices) {bodyConfig.setPartial(bodySlice.getStart(), bodySlice.getEnd() - bodySlice.getStart(), FileDataTypeEnum.BODY);FileReader sliceBodyReader = FileFactory.createReader(bodyConfig);try {Map<String, Object> row = null;while (null != (row = sliceBodyReader.readRow(HashMap.class))) {System.out.println(row);}} finally {sliceBodyReader.close();}
}// 获取head
FileSlice headSlice = fileSplitter.getHeadSlice(fileConfig);
FileConfig headConfig = fileConfig.clone();
headConfig.setPartial(headSlice.getStart(), headSlice.getLength(), headConfig.getFileDataType());
FileReader headReader = FileFactory.createReader(headConfig);
HashMap<String, Object> headMap = headReader.readHead(HashMap.class);
System.out.println(headMap);
headReader.close();// 获取tail
FileSlice tailSlice = fileSplitter.getTailSlice(fileConfig);
FileConfig tailFileConfig = fileConfig.clone();
tailFileConfig.setPartial(tailSlice.getStart(), tailSlice.getLength(), tailSlice.getFileDataType());
FileReader tailReader = FileFactory.createReader(tailFileConfig);
HashMap<String, Object> tailMap = tailReader.readTail(HashMap.class);
tailReader.close();
System.out.println(tailMap);

二:写

2.1 正常写

协议布局模板

使用内置的布局文件: rdf-file-core-2.2.10.jar!/META-INF/rdf-file/protocol/fund.xml

数据定义模板

{"head":["identity|信息标识|[8,0]|default:OFDCFDAT","version|协议版本号|[4,0]|default:20","msgCreator|信息创建人|[9,0]|default:H0","msgRecipient|信息接收人|[9,0]","sendDate|传送发生日期|[8,0]|Date:yyyyMMdd","summaryTableNo|汇总表号|[3,0]","fileTypeCode|文件类型代码 |[2,0]","sender|发送人|[8,0]|default:H0","recipient|接收人|[8,0]"],"body":["TransactionCfmDate|对帐日期|[8,0]|Date:yyyyMMdd","FundCode|基金代码|[8,0]","AvailableVol|基金可用份数|Integer|[6,2]"],"tail":["fileEnd|数据文件尾部字符|default:OFDCFEND|[8,0]"],"protocol":"FUND"
}

示例程序

String filePath = new File("/Users/mengday/Temp", "demofund.txt").getAbsolutePath();
FileConfig fileConfig = new FileConfig(filePath, "templates/demofund.json", new StorageConfig("nas"));
FileWriter fileWriter = FileFactory.createWriter(fileConfig);
try {//构建文件头Map<String, Object> head = new HashMap<>();head.put("msgRecipient", "xxx");head.put("sendDate", "20231122");head.put("summaryTableNo", "aa");head.put("fileTypeCode", "bb");head.put("recipient", "ll");head.put("totalCount", 1);fileWriter.writeHead(head);// 文件数据内容Map<String, Object> row = new HashMap<>();row.put("TransactionCfmDate", "20231122");row.put("FundCode", "中国1");row.put("AvailableVol", 42.11);fileWriter.writeRow(row);// 文件尾,没有数据,是取了数据定义模板中默认值fileWriter.writeTail(new HashMap<String, Object>());
} catch (Exception e) {e.printStackTrace();
} finally {fileWriter.close();
}

生成文件

OFDCFDAT
20  
H0       
xxx      
20231122
aa 
bb
H0      
ll      
003
TransactionCfmDate
FundCode
AvailableVol
00000001
20231122中国1 004211
OFDCFEND

2.2 汇总写

协议布局模板

rdf-file-core-2.2.10.jar!/META-INF/rdf-file/protocol/sp.xml

数据定义模板

tail:定义字段,summaryColumnPairs:定义对什么字段进行汇总,汇总的值赋给tail的什么字段上。"totalAmount|amount"表示对totalAmount=sum(amount),totalCount是系统预定义好的总条数。

{"head": ["fileStart|数据文件头部字符|default:汇总文件测试"],"body": ["seq|流水号","instSeq|基金公司订单号|Required","gmtApply|订单申请时间|Date:yyyy-MM-dd HH:mm:ss","date|普通日期|Date:yyyyMMdd","dateTime|普通日期时间|Date:yyyyMMdd HH:mm:ss","applyNumber|普通数字|Long","amount|金额|BigDecimal","age|年龄|Integer","longN|长整型|Long","bol|布尔值|Boolean","memo|备注"],"tail": ["totalCount|总笔数|Required|Integer","totalAmount|总金额|BigDecimal|Required"],"protocol": "SP","lineBreak": "\r\n","summaryColumnPairs": ["totalAmount|amount"]
}

示例程序

String filePath = new File("/Users/mengday/Temp", "demosp.txt").getAbsolutePath();
FileConfig fileConfig = new FileConfig(filePath, "templates/demosp.json", new StorageConfig("nas"));
// 开启汇总写
fileConfig.setSummaryEnable(true);
FileWriter fileWriter = FileFactory.createWriter(fileConfig);
try {Date testDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-01-03 12:22:33");// 头使用数据定义模板的常量Map<String, Object> head = new HashMap<String, Object>();fileWriter.writeHead(head);// 写入两条数据Map<String, Object> body = new HashMap<String, Object>();body.put("seq", "seq12345");body.put("instSeq", "303");body.put("gmtApply", testDate);body.put("date", testDate);body.put("dateTime", testDate);body.put("applyNumber", 12);body.put("amount", new BigDecimal("1.22"));body.put("age", new Integer(33));body.put("longN", new Long(33));body.put("bol", true);body.put("memo", "memo1");fileWriter.writeRow(body);testDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-03 12:22:33");body.put("seq", "seq234567");body.put("instSeq", "505");body.put("gmtApply", testDate);body.put("date", testDate);body.put("dateTime", testDate);body.put("applyNumber", 12);body.put("amount", new BigDecimal("1.09"));body.put("age", 66);body.put("longN", 125);body.put("bol", false);body.put("memo", "memo2");fileWriter.writeRow(body);// 根据汇总信息写入尾部fileWriter.writeTail(fileWriter.getSummary().summaryTailToMap());
} catch (Exception e) {e.printStackTrace();
} finally {fileWriter.close();
}

生成文件

汇总文件测试
seq12345|303|2017-01-03 12:22:33|20170103|20170103 12:22:33|12|1.22|33|33|true|memo1
seq234567|505|2016-02-03 12:22:33|20160203|20160203 12:22:33|12|1.09|66|125|false|memo2
2|2.31

三:合并写

文件合并使用场景,一般在分布式环境下导出文件,如分库分表下每个表导出一个分片文件,最后合成一个完整文件。
文件合并支持: 文件头, 文件body,文件尾,完整文件, 不同存储文件的合并。

{"head": ["totalCount|总笔数|Required|Integer","totalAmount|总金额|BigDecimal|Required"],"body": ["seq|流水号","instSeq|基金公司订单号|Required","gmtApply|订单申请时间|Date:yyyy-MM-dd HH:mm:ss","date|普通日期|Date:yyyyMMdd","dateTime|普通日期时间|Date:yyyyMMdd HH:mm:ss","applyNumber|普通数字|BigDecimal","amount|金额|BigDecimal","age|年龄|Integer","longN|长整型|Long","bol|布尔值|Boolean","memo|备注"],"tail": ["fileEnd|数据文件尾部字符","date|普通日期|Date:yyyyMMdd","amount|总金额|BigDecimal"],"protocol": "DE","summaryColumnPairs": ["totalAmount|amount","amount|amount"]
}

文件内容

de_all1.txt

总笔数:100|总金额:300.03
流水号|基金公司订单号|订单申请时间|普通日期|普通日期时间|普通数字|金额|年龄|长整型|布尔值|备注
seq_0|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注1
seq_1|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
OFDCFEND|20131109|100

de_all2.txt

总笔数:100|总金额:300.11
流水号|基金公司订单号|订单申请时间|普通日期|普通日期时间|普通数字|金额|年龄|长整型|布尔值|备注
seq_2|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注1
seq_3|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
OFDCFEND|20131109|12

de_all3.txt

总笔数:100|总金额:300.12
流水号|基金公司订单号|订单申请时间|普通日期|普通日期时间|普通数字|金额|年龄|长整型|布尔值|备注
seq_10|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注1
seq_11|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
OFDCFEND|20131109|211

示例程序

String path = new ClassPathResource("data").getFile().getPath();
String filePath = new File(path, "de_all_merge.txt").getAbsolutePath();
FileConfig config = new FileConfig(filePath, "templates/template8.json", new StorageConfig("nas"));List<String> existFilePaths = Arrays.asList(new ClassPathResource("data/de_all1.txt").getFile().getPath(),new ClassPathResource("data/de_all2.txt").getFile().getPath(),new ClassPathResource("data/de_all3.txt").getFile().getPath()
);
MergerConfig mergerConfig = new MergerConfig();
mergerConfig.setExistFilePaths(existFilePaths);FileMerger fileMerger = FileFactory.createMerger(config);
fileMerger.merge(mergerConfig);

生成文件

  • 总笔试累加
  • 总金额累加
  • 数据体合并
  • 汇总累加
总笔数:300|总金额:900.26
流水号|基金公司订单号|订单申请时间|普通日期|普通日期时间|普通数字|金额|年龄|长整型|布尔值|备注
seq_0|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注1
seq_1|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
seq_2|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注1
seq_3|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
seq_10|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|备注1
seq_11|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
OFDCFEND|20131109|323

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/181190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java(九)(多线程,线程安全,实现线程的方法,线程同步,线程池,并发和并行,线程的六种状态)

目录 多线程 线程 实现线程的方法 方法一:继承Thread父类 方法二:实现Runnable接口 方法三:Callable接口和FutureTask类来实现 Thread方法 线程安全 线程同步 同步代码块 同步方法 Lock锁 线程池 线程池对象的创建方式一: 线程池处理Runnable任务 线程池处理Cal…

BGP综合实验

任务如下&#xff1a; 1.AS1存在两个环回&#xff0c;一个地址为192.168.1.0/24该地址不能在任何协议中宣告 AS3存在两个环回&#xff0c;一个地址为192.168.2.0/24该地址不能在任何协议中宣告&#xff0c;最终要求这两个环回可以互相通讯 2.整个AS2的IP地址为172.16.0.0/16&…

Sentaurus TCAD半导体器件入门常用案例合集

Sentaurus TCAD是用于模拟半导体器件和工艺的工具之一&#xff0c;可以帮助工程师设计电路元件&#xff0c;优化半导体工艺和器件性能。主要功能包括&#xff1a;半导体器件建模&#xff08;用于建立各种半导体器件的物理模型工艺模拟&#xff09;、半导体器件的制造工艺模拟&a…

Debian10安装VMware Tools

一、原系统 首先我在界面按CTRLALTT和CTRLSiftT都没有反应&#xff0c;没关系&#xff0c;我有办法 系统版本 管理员用户 步骤一&#xff1a;打开VMware Tools文件 步骤二、将文件复制到自己熟悉的文件内 步骤三、命令行查看文件是否复制成功存在 步骤四、解压VMware-tools…

redis缓存问题

redis缓存问题 缓存击穿 缓存击穿是指热点key在某个时间点过期的时候&#xff0c;而恰好在这个时间点对这个Key有大量的并发请求过来&#xff0c;从而大量的请求打到db 解决方案&#xff1a; 利用互斥锁&#xff0c;缓存中没有&#xff0c;先获取锁&#xff0c;再去请求数据…

Easy Excel设置表格样式

1. 设置通用样式 import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.xxx.npi.config.easypoi.EasyExcelDateConverter; import lombok.Data; import …

宋仕强论道之华强北的商业配套(十三)

宋仕强论道之华强北的商业配套&#xff08;十三&#xff09;&#xff1a;金航标电子萨科微半导体总经理宋仕强先生发布“宋仕强论道”系列视频&#xff0c;分享多年学习、生活和工作经验和感悟&#xff0c;甚至涵盖了文学、艺术、哲学、宗教。这段时间发表的是对华强北&#xf…

程序设计基础中可能出现的简单编程题2(以郑大为主体)

我们在学习编程过程中往往不仅有C语言实验报告&#xff0c;还有程序设计实验报告。程序设计这一科目主要是为了培养我们写代码时的计算思维&#xff0c;养成从问题到代码实现逐步分析&#xff0c;逐步深入的好习惯。前面有一篇文章介绍了部分程序设计实验报告中的编程题&#x…

第二十章 -----多线程

20.1 线程简介 计算机完全可以将多种活动同时进行&#xff0c;这种思想在java中称为并发&#xff0c;将并发完成的每一件事情称为线程 线程的特点&#xff1a; 极小的单位 一个进程有很多个线程 线程共享进程的资源 20.2 创建线程 20.2.1 继承Thread类 Thread类是Java.l…

golang 实现单向链表(lru)、双向链表、双向循环链表

单向链表实现lru package mainimport "fmt"func main() {// 实现一个lru 淘汰算法// linked 结构体// node 节点 &#xff1a; data prev next// 更新lru// 如果没有满// 将新的数据加入到头结点// 队满 &#xff1a; 删除尾结点// 将新数据加入头结点linkedObj : g…

Python实现视频人脸检测识别功能

目录 一、引言 二、人脸检测识别技术概述 三、Python实现视频人脸检测识别功能的步骤 1、安装相关库和工具 2、加载视频文件 3、人脸检测和识别 4、保存视频结果 四、实验结果和讨论 五、结论 一、引言 在当今社会&#xff0c;人脸检测识别技术在安全监控、人机交互、…

全网日志智能聚合及问题根因分析

1 日志关联分析的挑战 随着各行各业数字化转型的不断深入&#xff0c;网络承载了人们日常生活所需的政务、金融、娱乐等多方面的业务系统&#xff0c;已经成为影响社会稳定运行、关系国计民生的重要基础设施资源。哪怕网络发生及其微小的故障&#xff0c;也可能带来难以估量的…

Java基础之原码,反码,补码,位运算符

文章目录 前言一、二进制在运算中介绍二、原码&#xff0c;反码&#xff0c;补码&#xff08;针对有符号的&#xff09;三、位运算符按位与&按位或 |按位异或 ^按位取反 ~算术右移>>算术左移<<逻辑右移>>> 总结 前言 原码&#xff0c;反码&#xff0…

【shell】文本三剑客之sed详解

目录 一、sed简介&#xff08;行编辑器&#xff09; 二、基本用法 三、sed脚本格式&#xff08;匹配地址 脚本命令&#xff09; 1、不给地址&#xff0c;那么就是针对全文处理 2、单地址&#xff0c;表示#&#xff0c;指定的行&#xff0c;$表示最后一行&#xff0c;/pattt…

牛客算法题 HJ100 等差数列 golang语言实现

算法题目 HJ100 等差数列 描述 等差数列 2&#xff0c;5&#xff0c;8&#xff0c;11&#xff0c;14。。。。 &#xff08;从 2 开始的 3 为公差的等差数列&#xff09; 输出求等差数列前n项和数据范围&#xff1a; 1 ≤ &#xfffd; ≤ 10001≤n≤1000 输入描述&#xff…

python与机器学习1,机器学习的一些基础知识概述(完善ing)

目录 1 AI ,ML,DL,NN 等等概念分类 1.1 人工智能、机器学习、深度学习、神经网络之间的关系&#xff1a; 1.2 人工智能的发展 2 ML机器学习的分类&#xff1a;SL, USL,RL 2.1 机器学习的分类 2.2 具体的应用举例 2.3 数据分类 3 关于阈值θ和偏移量b的由来 4 不同的激…

qt使用qproperty在css中设置自定义的qobject类属性

在Qt的CSS样式表中使用 qproperty 来赋值&#xff0c;首先需要在类的定义中使用 Q_PROPERTY 宏声明属性&#xff0c;并提供相应的 getter 和 setter 函数。 // MyWidget.h#ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget>class MyWidget : public QWidget {Q_O…

网站定制开发对企业的好处|软件app小程序搭建

网站定制开发对企业的好处|软件app小程序搭建 在当今数字化的时代&#xff0c;拥有一个专属于自己企业的网站已经成为了一种趋势。而与此同时&#xff0c;网站定制开发作为一种针对企业需求量身定制的解决方案&#xff0c;也越来越受到企业的关注和青睐。那么&#xff0c;网站定…

SSL证书实惠品牌——JoySSL

随着互联网的普及和发展&#xff0c;网络安全问题日益严重。为了保护网站数据的安全&#xff0c;越来越多的网站开始使用SSL证书。JoySSL证书作为一款高性价比的SSL证书&#xff0c;受到了广泛的关注和好评。 目前市面上主流的证书基本上都是国外证书&#xff0c;也就是说你在验…

09-详解JSR303规范及其对应的校验框架的使用

JSR303规范 校验注解 前端请求后端接口时传输的参数在Controller和Service中都要校验但分工不同,因为你无法保证Service接口一定是由Controller层调用 Controller中的校验代码是通用的: 主要是校验请求参数的合法性&#xff0c;包括必填项校验、数据格式校验(如日期格式) Se…