Java JSch 在复制时更改文件编码
Java JSch change file encoding while copying
我将一些文件从 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()
是幂等的,所以即使 reader 关闭了流,你还是想关闭它):
// "in" is the InputStream from the remote file
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 Reader reader = new InputStreamReader(in, srcCharset);
final BufferedWriter writer = Files.newBufferedWriter(dstFile, dstCharset);
) {
while ((charsRead = reader.read(buf)) != -1)
writer.write(buf, 0, charsRead);
writer.flush();
}
理想情况下:存在一个基于 SFTP 的 JSR 203 实现,但我还没有找到它;如果你找到它,你甚至可以使用 Files.copy()
:
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();
}
JSch 无法为您转换下载的文件编码。正如@fge 的回答所示,您必须自己完成。
为避免保存下载文件的临时副本(以原始编码),使用 get
方法的签名 returns 一个流:
public InputStream get(String src)
然后直接从该流中读取,并在实际将下载的数据保存到目标文件之前即时转换它们。
对于即时转换,当从流中读取时,请参见示例:
- Java file encoding conversion from ANSI to UTF8
- java: how to convert a file to utf8
我将一些文件从 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()
是幂等的,所以即使 reader 关闭了流,你还是想关闭它):
// "in" is the InputStream from the remote file
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 Reader reader = new InputStreamReader(in, srcCharset);
final BufferedWriter writer = Files.newBufferedWriter(dstFile, dstCharset);
) {
while ((charsRead = reader.read(buf)) != -1)
writer.write(buf, 0, charsRead);
writer.flush();
}
理想情况下:存在一个基于 SFTP 的 JSR 203 实现,但我还没有找到它;如果你找到它,你甚至可以使用 Files.copy()
:
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();
}
JSch 无法为您转换下载的文件编码。正如@fge 的回答所示,您必须自己完成。
为避免保存下载文件的临时副本(以原始编码),使用 get
方法的签名 returns 一个流:
public InputStream get(String src)
然后直接从该流中读取,并在实际将下载的数据保存到目标文件之前即时转换它们。
对于即时转换,当从流中读取时,请参见示例:
- Java file encoding conversion from ANSI to UTF8
- java: how to convert a file to utf8