java - 线程写入本地txt文件的问题
问题描述
我正在尝试使用隔离的此类从大量来源的文本中写入,而无需每次打开一个实例或文件的连接,因此我添加到 ArrayList 并在隔离线程中工作以查看该行是否存在,因此服务类尽快完成写入信息的工作,避免客户端类等待其使用写入器类的时间。这个类的问题是我在构造函数中执行线程,但是线程在第一次调用中停止以执行方法 write (gerenciadorDeArquivos().escreveEmArquivo(),它在文件中写入一次,没有更多,这个当我将程序调试时,如果我不这样做,他甚至不会执行一次。也许您可以提供一些见解。
主窗体类
package EscreveArquivo;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Tela extends javax.swing.JFrame {
public Tela() {
initComponents();
}
private void initComponents() {....} /// Form Components
EscreveArquivo escritorDeArquivos = new EscreveArquivo();
private void recordTextButtonActionPerformed(java.awt.event.ActionEvent evt) {
escritorDeArquivos.AdicionaArquivoEmListaDeInstrucoes(textField.getText());
}
二等舱
package Escrevearquivo;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;*
public class EscreveArquivo {
private static List<String> listaDeInstrucoes = new ArrayList<String>();
private boolean gerenciadorEstaEmExecucao = false;
EscreveArquivo() {
Thread t = new Thread() {
public void run() //Anonymous class overriding run() method of Thread class
{
while (true) {
if (!listaDeInstrucoes.isEmpty()) {
gerenciadorDeArquivos();
}
}
}
};
t.start();
}
public static void AdicionaArquivoEmListaDeInstrucoes(String arquivoASerEscrito) {
listaDeInstrucoes.add(arquivoASerEscrito);
}
private void gerenciadorDeArquivos() {
if (gerenciadorEstaEmExecucao == false) {
gerenciadorEstaEmExecucao = true;
ArrayList<String> listaDeInstrucoesCopia = new ArrayList<String>();
for (String textoAEscrever : listaDeInstrucoes) {
listaDeInstrucoesCopia.add(textoAEscrever);
}
for (String textoAApagar : listaDeInstrucoesCopia) {
EscreveEmArquivo(textoAApagar);
listaDeInstrucoesCopia.remove(textoAApagar);
}
}
gerenciadorEstaEmExecucao = false;
}
private static void EscreveEmArquivo(String texto) {
File arquivo = new File("C://Users//Josué//Desktop//arquivoTexto.txt");
try {
if (!arquivo.exists()) {
arquivo.createNewFile();
}
FileWriter writer = new FileWriter(arquivo, true);
BufferedWriter saida = new BufferedWriter(writer);
saida.write(texto);
saida.newLine();
saida.close();
} catch (IOException ex) {
Logger.getLogger(Tela.class
.getName()).log(Level.SEVERE, null, ex);
}
}
}
解决方案
这部分
for(String textoAApagar : listaDeInstrucoesCopia) {
EscreveEmArquivo(textoAApagar);
listaDeInstrucoesCopia.remove(textoAApagar); //error will be thrown here!
}
实际上会产生错误,因为您在遍历列表时ConcurrentModificationException
正在修改列表。listaDeInstrucoesCopia
所以在这种情况下,调用将不会写入第二个字段。只有第一个调用会被执行。
删除线listaDeInstrucoesCopia.remove(textoAApagar);
,它应该可以正常工作。但同样你没有清空你的 ArrayList,所以旧值将被重写。
您应该考虑使用 Queue 实现并弹出结束元素并连续写入文件。
推荐阅读
- reactjs - google-map-react 和 google-maps-react 之间的区别?
- java - 如何将jmeter属性路径指向maven下载的jmeter jar路径?
- reactjs - 如何使用 React 功能组件在 CanvasJS 中为动态更新设置动画?
- rabbitmq - ResolveEndpointFailedException:“有 1 个参数无法在端点上设置。” 使用端点 DSL 创建端点时
- javascript - 如何使 Protractor 的 ElementArrayFinder 'each' 函数等待当前操作完成,然后再进行下一次迭代?
- python - 尝试将文件移动到临时目录时出现 FileNotFoundError
- python - astype 函数没有神秘地工作
- docker - 如何在 Visual Studio Code docker 容器中运行的 .devcontainer 使用的 env 文件中引用另一个环境变量?
- python - 如何使用 Selenium 从右键菜单中选择选项
- python-3.x - 如何使用 Boto3 从不同的 AWS 账户密钥管理器获取所有密钥?