首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java在通过Windows远程桌面(tsclient)写入时会创建巨大的文件

Java在通过Windows远程桌面(tsclient)写入时会创建巨大的文件
EN

Stack Overflow用户
提问于 2013-12-03 20:49:01
回答 1查看 1.4K关注 0票数 17

我们的一个客户报告了一个非常奇怪的问题,当我们的Swing应用程序通过Windows远程桌面(该应用程序托管在用户连接的终端服务器上)将文件写入用户的本地计算机时。

流程是:

  • 用户通过远程桌面登录并运行该应用程序(其C:\被包括为"Local resource")
  • While working“他们将数据从数据库导出到文件中
  • 用户选择要导出的数据
  • 用户在其本地计算机上选择目标文件,例如Java可能很大,因此从数据库中提取1000行并将其写入第二批上的文件
  • 当Java打开文件并再次写入该文件时,开始发生一些非常奇怪的事情!
    • 文件大小迅速增加,并在大约2 GB
    • 处停止,然后继续向file

写入数据

我不确定这是核心Java库中的问题,还是远程桌面实现的问题,还是两者的组合。我们的应用程序也是通过Citrix托管的,它工作得很好,写入本地磁盘或UNC网络路径也很好。

我已经创建了一个演示该问题的SSCCE,连接到具有远程桌面的计算机(确保C:\是一个“本地资源”),然后运行该程序来查看一些非常奇怪的行为!我正在使用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;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2018-07-13 14:20:39

我们也遇到了同样的问题,一位客户报告说,我们的java应用程序在写入TS客户端共享驱动器时会创建2 2GB的文件。我们注意到,只有在使用java.io.FileOutputStream和java.nio.Files.write追加数据时才会出现这个问题。

我们打开了一个问题,您可以在此处找到:

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8206888

然而,经过进一步的调查,我们发现问题是windows WriteFile API的一个不正确的行为,在这样的环境中,它显示了文档中所写的内容:

(摘自https://docs.microsoft.com/en-gb/windows/desktop/api/fileapi/nf-fileapi-writefile)

若要写入文件末尾,请将重叠结构的Offset和OffsetHigh成员都指定为0xFFFFFFFFF。这在功能上等同于前面调用CreateFile函数以使用FILE_APPEND_DATA访问打开hFile。

以下C程序可用于重现该问题:

#include <windows.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Not enough args\n");
        return 1;
    }

    HANDLE hFile = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD nw;
    OVERLAPPED ov;
    ov.Offset = (DWORD)0xFFFFFFFF;
    ov.OffsetHigh = (DWORD)0xFFFFFFFF;
    ov.hEvent = NULL;
    WriteFile(hFile, "a", 1, &nw, &ov);
    CloseHandle(hFile);

    return 1;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20351683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档