Java JSch在复制时更改文件编码

Java JSch在复制时更改文件编码,java,character-encoding,sftp,jsch,Java,Character Encoding,Sftp,Jsch,我将一些文件从SFTP服务器传输到另一台机器。SFTP中的文件是UTF-8字符集,我需要它们在“cp1251”中,这是在复制过程中更改文件编码的一种方法吗 我是这样做的: ChannelSftp sftp_channel = (ChannelSftp) channel; // some code sftp_channel.get(src, dst); 不,你不能那样做。您只能传输字节 您需要做的是将文件下载到临时文件中,然后将其转换为: final Path transferFile = Fi

我将一些文件从SFTP服务器传输到另一台机器。SFTP中的文件是UTF-8字符集,我需要它们在“cp1251”中,这是在复制过程中更改文件编码的一种方法吗

我是这样做的:

ChannelSftp sftp_channel = (ChannelSftp) channel;
// some code
sftp_channel.get(src, dst);

不,你不能那样做。您只能传输字节

您需要做的是将文件下载到临时文件中,然后将其转换为:

final Path transferFile = Files.createTempFile("transfer", "xxx");

// transfer file to transferFile

// Sure it's not 1252?
final Charset srcCharset = Charset.forName("windows-1251");

final Path dstFile = Paths.get("destinationFile");
final Charset dstCharset = StandardCharsets.UTF_8;

final char[] buf = new char[16384]; // or another size
int charsRead;

try (
    final BufferedReader reader = Files.newBufferedReader(transferFile, srcCharset);
    final BufferedWriter writer = Files.newBufferedWriter(dstFile, dstCharset);
) {
    while ((charsRead = reader.read(buf)) != -1)
        writer.write(buf, 0, charsRead);
    writer.flush();
}

Files.delete(transferFile);

现在,如果您可以从要传输的文件中获取
InputStream
,那么代码将如下所示(注意:关闭原始
InputStream
,此处未处理;但是请注意,
Closeable
.close()
是幂等的,因此即使读取器关闭流,您也要关闭它):


理想情况下:在SFTP上存在JSR203实现,但是我没有找到它;如果找到它,您甚至可以使用
Files.copy()


JSch无法为您转换下载的文件编码。正如@fge的回答所示,你必须自己做

为避免保存已下载文件的临时副本(原始编码),请使用返回流的签名
get
方法:

public InputStream get(String src)
然后直接从该流中读取,并动态转换下载的数据,然后将其保存到目标文件中

有关动态转换,请参阅从流读取时的示例:


感谢您的意见。。。但是有些文件非常大(超过1Gb),在重新编码文件时会不会遇到麻烦?为什么会这样?没有理由这样做;)但是如果你有这么大的文件,你应该选择一个大于2048的缓冲区;如果它存在,你会有一个更容易的时间。它应该存在,不幸的是我找不到它。。。如果我找到答案,我会尝试更新它。@fge为什么?您的代码也可以在流上工作,不是吗?我已经包括了一些对我答案的参考。@Steve.B最好是从远程文件中获得一个
InputStream
;如果是,请使用编码正确的
InputStreamReader
,然后打开一个
BufferedWriter
到目标文件并进行传输。您确定
字符串作为参数是您的意思吗?是<代码>字符串
作为要下载的远程文件的路径。您将获得一个
InputStream
返回以进行读取。我遗漏了什么吗?啊,好吧,出于某种原因,我认为这个参数应该是远程文件的内容:/
final Charset srcCharset = Charset.forName("windows-1251");

final Path dstFile = Paths.get("destinationFile");
final Charset dstCharset = StandardCharsets.UTF_8;

try (
    final FileSystem sshfs = xxx;
    final BufferedReader reader 
        = Files.newBufferedReader(sshfs.getPath("sourcepath"), srcCharset);
    final BufferedWriter writer  = Files.newBufferedWriter(dstFile, dstCharset);
) {
    while ((charsRead = reader.read(buf)) != -1)
        writer.write(buf, 0, charsRead);
    writer.flush();
}
public InputStream get(String src)