想改进一下实验代码,要求在for循环中添加一段java代码把每次循环中的参数positionMap的值写入每个新建的txt文件中,要求一个txt文件存储一个positionMap的值,且txt文件命名为自增的数字序号。
图示代码部分如下:
import client.utils.*;
import it.unisa.dia.gas.jpbc.Element;
import orestes.bloomfilter.CountingBloomFilter;
import orestes.bloomfilter.FilterBuilder;
import pojo.PrivateKey;
import pojo.PublicKey;
import server.Search;
import server.utils.HomoEncryption_Server;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Phrase_multi {
public static void main(String[] args) {
KeyGenUtils.genKey();
Object[] key = KeyGenUtils.getKeyFromFile("key.data");
PublicKey publicKey = (PublicKey) key[0];
PrivateKey privateKey = (PrivateKey) key[1];
CountingBloomFilter<Object> cbf = new FilterBuilder(1000000, 0.01)
.buildCountingBloomFilter();
ConcurrentHashMap<Integer, HashMap<String, ArrayList<Element>>> filesMaps = new ConcurrentHashMap<>();
File dataSetFolder = new File("C:\\mypaperdataset\\enron\\version2\\256");
ExecutorService executorService = Executors.newCachedThreadPool();
long s = System.currentTimeMillis();
for (File file : dataSetFolder.listFiles()) {
// if (count==7000) break;
// count++;
Integer node = NodeGen_Client.getNode();
executorService.execute(()->{
System.out.println("正在处理文件:" + file.getName() +"分配的节点:"+node);
List<String> extracted = ExtractKeyword.extract_easy(file);//一个文件提取关键词耗费5ms
IndexBuilding.buildCBF_Batch(extracted, node, cbf);
HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
filesMaps.put(node, positionMap);
//System.out.println(positionMap);//写一段java代码把每次循环中的参数positionMap的值写入每个txt文件中,一个txt文件对应一个positionMap的值
});
}
executorService.shutdown();
try {
while (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("线程池没有关闭");
// System.out.println("isTerminated:" + executorService.isTerminated());
ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
System.out.println("剩余线程数: "+executor.getActiveCount());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
long e = System.currentTimeMillis();
System.out.println("线程池已经关闭");
System.out.println("isTerminated:" + executorService.isTerminated());
System.out.println("用时:"+(e-s)+"毫秒");
// 搜索
HomoEncryption_Client homo_client = new HomoEncryption_Client(privateKey, publicKey);
Element elementX = homo_client.getElementX();
Element elementY = homo_client.getElementY();
while (true) {
ArrayList<String> keywords = new ArrayList<>();
while (true) {
System.out.println("请输入:");
Scanner input = new Scanner(System.in);
String next = input.next();
if (next.equals("0")) {
System.out.println("开始查询");
break;
}
keywords.add(MyHashUtils.md5(next));
}
HomoEncryption_Server homo_server = new HomoEncryption_Server(publicKey);
long kk = System.nanoTime();
List<Integer> search_result1 = Search.searchKeywords(keywords, cbf);
long ll = System.nanoTime();
System.out.println("普通查询完成,用时:"+(ll-kk)+"ns 查询到了"+search_result1.size()+"个文件");
long pp = System.nanoTime();
List<Integer> search_result2 = Search.searchKeywords_Phrase(keywords, cbf, filesMaps, homo_server, elementX, elementY);
long jj = System.nanoTime();
System.out.println("词组查询完成,用时:"+(jj-pp)+"ms 查询到了"+search_result2.size()+"个文件");
}
}
}
该回答引用chatgpt:
//添加一个计数器
private static AtomicInteger fileCounter = new AtomicInteger(1);
executorService.execute(() -> {
// 省略其他代码...
HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
filesMaps.put(node, positionMap);
// 将positionMap写入txt文件
int fileIndex = fileCounter.getAndIncrement();
String fileName = fileIndex + ".txt";
writePositionMapToFile(fileName, positionMap);
});
// ...
private static void writePositionMapToFile(String fileName, HashMap<String, ArrayList<Element>> positionMap) {
try (PrintWriter writer = new PrintWriter(fileName)) {
for (String key : positionMap.keySet()) {
writer.println(key + ": " + positionMap.get(key));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
在每次循环中,我们首先通过fileCounter.getAndIncrement()获取一个自增的序号作为文件名,然后调用writePositionMapToFile()方法将positionMap写入txt文件中。该方法使用PrintWriter将数据写入文件,并按照指定的格式进行写入
要在每次循环中将参数positionMap
的值写入新建的txt文件,并且要求每个txt文件存储一个positionMap
的值,且文件命名为自增的数字序号。
您可以在循环的适当位置添加以下Java代码段来实现此功能:
// 在循环开始前定义一个自增的数字序号变量
AtomicInteger fileIndex = new AtomicInteger(1);
// 在循环内部获取当前循环的positionMap
HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
// 创建txt文件并写入positionMap的值
try {
String fileName = fileIndex.getAndIncrement() + ".txt";
File outputFile = new File(fileName);
FileWriter writer = new FileWriter(outputFile);
// 将positionMap的值写入文件
writer.write(positionMap.toString());
writer.close();
System.out.println("已将positionMap的值写入文件:" + fileName);
} catch (IOException e) {
e.printStackTrace();
}
将以上代码段添加到您的循环内部,它将根据自增的数字序号创建一个新的txt文件,并将当前循环的positionMap
的值写入文件中。
请注意,代码段中的位置应根据您的需求进行调整,以确保在适当的时机创建和写入文件。
希望这可以帮助您改进实验代码!
在for循环之前添加一个计数器fileCount,用于生成文件名的自增数字序号。初始值为0。
在executorService.execute()方法中的positionMap赋值后添加代码将其写入txt文件。您可以使用Java的文件操作功能来实现。
在写入txt文件后,将fileCount自增。
在for循环结束后添加代码关闭文件。
// 添加计数器
AtomicInteger fileCount = new AtomicInteger(0);
for (File file : dataSetFolder.listFiles()) {
Integer node = NodeGen_Client.getNode();
executorService.execute(() -> {
// 省略其他代码
HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
filesMaps.put(node, positionMap);
// 将positionMap的值写入txt文件
try {
int count = fileCount.incrementAndGet();
String fileName = count + ".txt";
File txtFile = new File(fileName);
FileWriter writer = new FileWriter(txtFile);
for (String key : positionMap.keySet()) {
ArrayList<Element> elements = positionMap.get(key);
writer.write(key + ": ");
for (Element element : elements) {
writer.write(element.toString() + " ");
}
writer.write("\n");
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
});
}
// 关闭文件
executorService.execute(() -> {
for (int i = 0; i < fileCount.get(); i++) {
File txtFile = new File(i + ".txt");
if (txtFile.exists()) {
txtFile.delete();
}
}
});
executorService.shutdown();
// 省略其他代码
在这个修改后的代码中,每个循环中生成的positionMap的值将被写入一个新建的txt文件中,并使用自增的数字序号作为文件名。最后,添加了一个任务来删除所有生成的txt文件,以保持代码的整洁性。
引入包:
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
核心代码如下:
int i = 1;
for (File file : dataSetFolder.listFiles()) {
// if (count==7000) break;
// count++;
Integer node = NodeGen_Client.getNode();
executorService.execute(()->{
System.out.println("正在处理文件:" + file.getName() +"分配的节点:"+node);
List<String> extracted = ExtractKeyword.extract_easy(file);//一个文件提取关键词耗费5ms
IndexBuilding.buildCBF_Batch(extracted, node, cbf);
HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
filesMaps.put(node, positionMap);
//System.out.println(positionMap);//写一段java代码把每次循环中的参数positionMap的值写入每个txt文件中,一个txt文件对应一个positionMap的值
String mapStr = JSONObject.toJSONString(map);
Path pathFile = Paths.get("C:\\mypaperdataset\\enron\\version2\\positionMapValue"+i+".sql");
try (BufferedWriter writerFile = Files.newBufferedWriter(pathFile, StandardCharsets.UTF_8)) {
writerFile.write(mapStr);
} catch (IOException e) {
e.printStackTrace();
}
});
i ++;
}