I need to split a FileWriter into multiple partitioned files using "try-with-resources" technique. But when I use "try-with-resources", I can't recreate the FileWriter and BufferWriter in a different file. I'm trying to solve some sonar issues and "try-with-resources" is a rule to follow.
Does anyone have an idea to solve it?
Thanks
....
try (InputStream fis=new FileInputStream(sArquivo);
BufferedReader br=new BufferedReader(new InputStreamReader(fis));
FileWriter fw = new FileWriter(sNomeArquivoDestino);
BufferedWriter bw = new BufferedWriter(fw)) {
String vLinha = "";
while (br.ready())
{
vLinha = br.readLine();
if(vLinha == null) { break; }
bw.write(vLinha System.lineSeparator());
if (lLinhas % lLimiteLinhas == 0L && lLinhas > 0L)
{
bw.flush();
bw.close();
lPart;
sNomeArquivoDestino = sPathDestino "\\" sFileName.replace(".TXT", "") "-Part-" String.format("d" ,lPart) ".TXT";
fw = new FileWriter(sNomeArquivoDestino); // Compile error: The resource fw of a try-with-resources statement cannot be assigned
bw = new BufferedWriter(fw); // Compile error: The resource bw of a try-with-resources statement cannot be assigned
}
lLinhas;
}
}
catch (Exception ex)
{
throw ex;
}
CodePudding user response:
As the BufferedWriter is used to write several numbered partial files, one does not have an automatically closing file for a try-with-resources syntax.
Easiest is to have a finally
block and do all oneself. Of course one could also introduce a second nested loop with try-with-resources for the output of a part.
First I would use Files, Path, and Paths for a shorter usage of otherwise nested file constructors. Also the text encoding of the computer is the default one. Better make it explicit. (Best would have been StandardCharsets.UTF_8
for full Unicode power, when possible.)
Using ready()
is wrong, as it is a test, whether a read will block (the current buffer is empty). Here the right thing to do is to request a read. Otherwise you might be so fast, still nothing is there, and though there is still something on disk, you stop reading.
One might use sNomeArquivoDestino = String.format("...%s ...", ..., ...);
for a nicer style.
Charset charset = Charset.defaultCharset();
Path arguivo = Paths.get(sArguivo);
BufferedWriter bw = null;
try (BufferedReader br = Files.newBufferedReader(arguivo, charset)) {
long lPart = 0;
long lLinhas = 0L;
for (;;) {
String vLinha = br.readLine();
if (vLinha == null) {
break;
}
if (lLinhas % lLimiteLinhas == 0L) {
if (bw != null) {
bw.close();
bw = null;
}
sNomeArquivoDestino = sPathDestino "\\"
sFileName.replace(".TXT", "") "-Part-"
String.format("d", lPart) ".TXT";
Path arquivoDestino = Paths.get(sNomeArquivoDestino);
bw = Files.newBufferedWriter(arquivoDestino, charset);
lPart;
}
bw.write(vLinha);
bw.write(System.lineSeparator());
lLinhas;
}
} finally {
if (bw != null) {
bw.close();
}
}
By the way, Hungarian notation with prefixes like s
and l
are not common in java, in favor of more fluent names. (Compare old MS C with Linux C .)
CodePudding user response:
You'll need to change your logic to use try-with-resources inside try-with-resources. In pseudo code:
try (fis; br):
for each partition in br:
try (fw; bw):
write partition to bw
Assuming that you should always write at least one partition, this could be done changed a bit:
try (fis; br):
while (true):
try (fw; bw):
write partition
- continue when the partition is full
- break when no more data