A client of ours reported a very weird issue when our Swing application is writing a file to the users local machine via Windows Remote Desktop (the application is hosted on a terminal server where users connects).
The flow is:
- Users logon and run the application via remote desktop (with their
C:\
included as a "Local resource") - While working they export data from the database into files
- The user chooses what data to export
- The user selects a destination file on their local computer like
\\tsclient\C\Temp\TestFile.txt
- Files could be big so 1000 rows are fetched from database and written to file per batch
- On the second batch, when Java opens the file and write to it again, something really weird starts to happen!
- The file increases rapidly in size and stops at around 2 GB
- Then data continues to be written to the file
I'm not sure if this is a problem in the core Java libraries, the Remote Desktop implementation or a combination. Our application is also hosted via Citrix which works fine, and writing to local disk or UNC network paths works fine as well.
I've created a SSCCE demonstrating the problem, connect to a computer with Remote Desktop (make sure C:\
is a "local resource") and run the program to see some really strange behavior! I'm using JDK-7u45.
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.WRITE;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.util.Collections;
/**
* Demonstrates weird issue when writing (appending) to a file over TsClient (Microsoft Remote Desktop).
*
* @author Martin
*/
public class WriteOverTsClientDemo
{
private static final File FILE_TO_WRITE = new File("\\\\tsclient\\C\\Temp\\TestFile.txt");
//private static final File FILE_TO_WRITE = new File("C:\\Temp\\TestFile.txt");
private static final String ROW_DATA = "111111111122222222223333333333444444444555555555566666666667777777777888888888899999999990000000000";
public static void main(String[] args) throws IOException
{
if (!FILE_TO_WRITE.getParentFile().exists())
{
throw new RuntimeException("\nPlease create directory C:\\Temp\\ on your local machine and run this application via RemoteDesktop with C:\\ as a 'Local resource'.");
}
FILE_TO_WRITE.delete();
new WriteOverTsClientDemo().execute();
}
private void execute() throws IOException
{
System.out.println("Writing to file: " + FILE_TO_WRITE);
System.out.println();
for (int i = 1; i <= 10; i++)
{
System.out.println("Writing batch " + i + "...");
writeDataToFile(i);
System.out.println("Size of file after batch " + i + ": " + FILE_TO_WRITE.length());
System.out.println();
}
System.out.println("Done!");
}
private void writeDataToFile(int batch) throws IOException
{
Charset charset = Charset.forName("UTF-8");
CharsetEncoder encoder = charset.newEncoder();
try(OutputStream out = Files.newOutputStream(FILE_TO_WRITE.toPath(), CREATE, WRITE, getTruncateOrAppendOption(batch));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder)))
{
writeData(batch, writer);
}
}
private void writeData(int batch, BufferedWriter writer) throws IOException
{
for (String data : createData())
{
writer.append(Integer.toString(batch));
writer.append(" ");
writer.append(data);
writer.append("\n");
}
}
private Iterable<String> createData()
{
return Collections.nCopies(100, ROW_DATA);
}
/**
* @return option to write from the beginning or from the end of the file
*/
private OpenOption getTruncateOrAppendOption(int batch)
{
return batch == 1 ? TRUNCATE_EXISTING : APPEND;
}
}
On the second batch, when Java opens the file and write to it again ...
, so the .delete() in your SSCCE is needed ? – PeterMmmtry-catch
rather thantry with resources
. As sometimes the exception fromtry with resources
is suppressed in certain cases. I had faced a similar case once, but in that case I wasn't closing the file due to which teh file size kept increasing. – Jatin