我是JavaFX新手,对软件的设计/架构有问题。
我的用例是:
目前我只计算一个校验和,因为我不知道如何等待其他服务。我觉得我的设计不是很聪明。你有什么建议吗?
dev.kanka.checksumsharer.ChecksumSharerApplication#handleDragAndDropFiles
:
private void handleDragAndDropFiles(Dragboard dragboard) {
List<File> newFiles = dragboard.getFiles();
logger.info("Dropped files: " + newFiles);
FileUtil.handleNewFiles(newFiles);
}
dev.kanka。查克沙勒。乌提尔斯。FileUtil#handleNewFiles
public static void handleNewFiles(List<File> files) {
for (java.io.File file : files) {
KnkFile knkFile = new KnkFile(file.getAbsolutePath());
ChecksumCalculatorService sha256service = new ChecksumCalculatorService(knkFile, Algorithm.SHA_256);
sha256service.start();
sha256service.setOnSucceeded(event -> {
knkFile.setSha256(sha256service.getValue());
logger.debug(knkFile);
// TODO: I could call the second service here?
FileDAO.insertFile(knkFile);
});
// ChecksumCalculatorService sha512Service = new ChecksumCalculatorService(file, Algorithm.SHA_512);
// ChecksumCalculatorService sha3384Service = new ChecksumCalculatorService(file, Algorithm.SHA3_384);
// ChecksumCalculatorService sha3512Service = new ChecksumCalculatorService(file, Algorithm.SHA3_512);
//
// sha512Service.start();
// sha3384Service.start();
// sha3512Service.start();
// TODO: How can I insert this one file after calculating all checksums? Software Architecture Question...
}
}
检查和计算器服务:
package dev.kanka.checksumsharer.hash;
import dev.kanka.checksumsharer.models.KnkFile;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ChecksumCalculatorService extends Service<String> {
private static final Logger logger = LogManager.getLogger();
private KnkFile knkFile;
private Algorithm algorithm;
public ChecksumCalculatorService(KnkFile f, Algorithm algorithm) {
this.knkFile = f;
this.algorithm = algorithm;
}
private String getChecksumOfFile() throws IOException, NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance(algorithm.toString());
// Get knkFile input stream for reading the knkFile content
try (FileInputStream fis = new FileInputStream(this.knkFile)) {
// Create byte array to read data in chunks
byte[] byteArray = new byte[8192];
int bytesCount = 0;
// Read knkFile data and update in message digest
while ((bytesCount = fis.read(byteArray)) != -1) {
digest.update(byteArray, 0, bytesCount);
}
}
//Get the hash's bytes
byte[] bytes = digest.digest();
// bytes[] has bytes in decimal format;
// Convert it to hexadecimal format
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
@Override
protected Task<String> createTask() {
return new Task<>() {
@Override
protected String call() throws Exception {
return getChecksumOfFile();
}
};
}
}
创建4个服务可以吗?或者我可以创建一个包含4个任务的服务吗?在将信息插入数据库之前,如何同步它们并等待所有结果?
谢谢
我试着跟着回答。
public class ChecksumCalculationTask extends Task<String> {
private static final Logger logger = LogManager.getLogger();
private final KnkFile knkFile;
private final Algorithm algorithm;
public ChecksumCalculationTask(KnkFile f, Algorithm algorithm) {
this.knkFile = f;
this.algorithm = algorithm;
}
private String getChecksumOfFile() throws IOException, NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance(algorithm.toString());
// Get knkFile input stream for reading the knkFile content
try (FileInputStream fis = new FileInputStream(this.knkFile)) {
// Create byte array to read data in chunks
byte[] byteArray = new byte[8192];
int bytesCount = 0;
// Read knkFile data and update in message digest
while ((bytesCount = fis.read(byteArray)) != -1) {
digest.update(byteArray, 0, bytesCount);
}
}
//Get the hash's bytes
byte[] bytes = digest.digest();
// bytes[] has bytes in decimal format;
// Convert it to hexadecimal format
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
public KnkFile getKnkFile() {
return this.knkFile;
}
public Algorithm getAlgorithm() {
return this.algorithm;
}
@Override
protected String call() throws Exception {
return getChecksumOfFile();
}
}
dev.kanka。查克沙勒。乌提尔斯。FileUtil#handleNewFiles
public static void handleNewFiles(List<File> files) {
ExecutorService exec = Executors.newFixedThreadPool(Algorithm.values().length);
List<ChecksumCalculationTask> tasks = new ArrayList<>();
for (File file : files) {
KnkFile knkFile = new KnkFile(file.getAbsolutePath());
tasks.add(new ChecksumCalculationTask(knkFile, Algorithm.SHA_256));
tasks.add(new ChecksumCalculationTask(knkFile, Algorithm.SHA_512));
tasks.add(new ChecksumCalculationTask(knkFile, Algorithm.SHA3_384));
tasks.add(new ChecksumCalculationTask(knkFile, Algorithm.SHA3_512));
}
List<Future<String>> futures = exec.invokeAll(tasks);
// Create a `Task` that waits until they're finished and processes them all
Task<Void> processCompletedTasks = new Task<>() {
@Override
protected Void call() throws Exception {
// block until tasks complete
for (Future<String> f : futures) {
f.get();
}
// process completed tasks
for (ChecksumCalculationTask task : tasks) {
KnkFile knkFile = task.getKnkFile();
String checksum = task.getValue();
Algorithm algorithm = task.getAlgorithm();
// ... whatever you need here, note this is on background thread
}
return null;
}
};
exec.submit(processCompletedTasks);
exec.shutdown();
}
对我来说,这看起来很有逻辑,但我在IntelliJ中遇到了一个编译器错误,因为exec.invokeAll
-call:原因:没有类型变量T的实例存在,因此Checksum计算任务符合Callable
将校验和计算器设置为任务
,而不是服务
:
public class ChecksumCalculatorTask extends Task<String> {
private static final Logger logger = LogManager.getLogger();
private final KnkFile knkFile;
private final Algorithm algorithm;
public ChecksumCalculatorService(KnkFile f, Algorithm algorithm) {
this.knkFile = f;
this.algorithm = algorithm;
}
public KnkFile getKnkFile() {
return knkFile;
}
private String getChecksumOfFile() throws IOException, NoSuchAlgorithmException {
// ...
}
@Override
protected String call() throws Exception {
return getChecksumOfFile();
}
}
创建执行者:
private ExecutorService exec = Executors.newCachedTheadPool() ;
现在,您可以将任务提交给执行者:
public static void handleNewFiles(List<File> files) {
List<ChecksumCalculatorTask> tasks = new ArrayList<>();
for (java.io.File file : files) {
KnkFile knkFile = new KnkFile(file.getAbsolutePath());
ChecksumCalculatorTask sha256task = new ChecksumCalculatorTask(knkFile, Algorithm.SHA_256);
tasks.add(sha256Task);
sha256task.setOnSucceeded(event -> {
logger.debug(knkFile);
});
}
// And now you can invoke all the tasks:
List<Future<String>> futures = exec.invokeAll(tasks);
// Create a `Task` that waits until they're finished and processes tham all:
Task<Void> processCompletedTasks = new Task<>() {
@Override
protected Void call() throws Exception {
// block until tasks complete:
for (Future<String> f : futures) {
f.get();
}
// process completed tasks:
for (ChecksumCalculatorTask task : tasks) {
KnkFile file = task.getKnkFile() ;
String checksum = task.getValue();
// ... whatever you need here, note this is on background thread
}
}
};
exec.submit(processCompletedTasks);
}
我正在使用iTextSharp从PDF文件中读取文本。然而,有些时候我不能提取文本,因为PDF文件只包含图像。我每天下载同样的PDF文件,我想看看PDF是否被修改过。如果无法获得文本和修改日期,那么MD5校验和是判断文件是否已更改的最可靠方法吗? 如果是的话,一些代码示例将会很感激,因为我对密码学没有太多的经验。
我一直在阅读有关为将向客户公开的REST服务设计API的最佳实践。例如,我们应该使用名词来命名所有公开的URI。此外,动词应遵循HTTP命令的语义。例如,GET请求不应该修改资源,而应该在这里使用PUT请求。我在一次采访中被问到这个问题,但我不能满意地回答这个问题——我正在设计一个计算器,它提供以下功能:对两个操作数进行加法、乘法、除法和减法。如何按照REST原则向客户端公开这些方法。这些操作要使
在此之前我问了一个问题。我的服务conifg是: 我编写了一个扩展mediator交易文件。该类返回文件名并向服务发送请求。服务没有输入消息。我要每天13:30的服务。我尝试添加新的计划任务。但是它不能工作?谁能告诉我如何设置这个计划任务? 我也不知道如何设置“固定服务器”。
问题内容: 我正在为大型视频文件创建MD5校验和。我当前正在使用代码: 但这会创建一个内存缓冲区,并且对于大型视频文件而言并不理想。Swift中是否有一种方法可以计算读取文件流的MD5校验和,从而使内存占用量最小? 问题答案: 您可以分块计算MD5校验和,例如在?中有没有一个MD5库不需要同时输入全部内容?。 这是使用Swift的可能实现(现已针对Swift 5更新) 需要自动释放池来释放所返回的
服务端设计 服务端主要的问题是大数据的实时处理,截止2017年6月后端CAT的计算集群大约100台物理机,存储集群大约50台物理机,每天处理了约200TB的数据量。下面是CAT服务端一些设计细节: 架构设计 服务端单机cat-consumer的整体架构如下: 如上图,CAT服务端在整个实时处理中,基本上实现了全异步化处理。 消息接收是基于Netty的NIO实现 消息接收到服务端就存放内存队列,然后