Java 具有某些非ascii字符的JCIFS中的问题
我使用JCIFS访问一个文件共享,其中有很多日文名称,当・性格 例如: 路径人事部/要員・コスト管理課/Java 具有某些非ascii字符的JCIFS中的问题,java,samba,jcifs,Java,Samba,Jcifs,我使用JCIFS访问一个文件共享,其中有很多日文名称,当・性格 例如: 路径人事部/要員・コスト管理課/ 第一部分还可以,但第二部分会引起问题。这可能与以下事实有关:・” 可以使用斜杠输入,但我不确定。我已尝试转义字符,但似乎无法解决问题。您是否知道可能是什么原因造成的?查看Heeneee注释,浏览服务器文件系统以检查真正的共享名。我正在测试对网络的访问权限Samba服务器(UTF-8)中带有中间点和日语名称的ares,Java源代码(UTF-8)没有问题 import java.io.File
第一部分还可以,但第二部分会引起问题。这可能与以下事实有关:・” 可以使用斜杠输入,但我不确定。我已尝试转义字符,但似乎无法解决问题。您是否知道可能是什么原因造成的?查看Heeneee注释,浏览服务器文件系统以检查真正的共享名。我正在测试对网络的访问权限Samba服务器(UTF-8)中带有中间点和日语名称的ares,Java源代码(UTF-8)没有问题
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import jcifs.smb.SmbFile;
import junit.framework.TestCase;
public class JCifstest extends TestCase {
@Test
public void testJCifs() throws IOException {
System.out.println(Charset.defaultCharset());
SmbFile smbFile = new SmbFile("smb://myuser:mypass@myserver/basepath/人事部要員・コスト管理課/test.txt");
File destFile = new File("/tmp/" + smbFile.getName());
FileUtils.writeByteArrayToFile(destFile, IOUtils.toByteArray(smbFile.getInputStream()));
assertEquals("content", FileUtils.readFileToString(destFile));
}
}
更新U+30FB(片假名中间点):
正如@指出的问题与U+30FB
(片假名中间点)有关,那么它需要解决。因此,我想分享一些以前的项目经验和建议
建议-1:
在我的一个项目中,我们正在为项目制作一些手册。手册使用了各种语言。在那里我们遇到了相同类型的问题。我们使用了Lotus Notes
。在这种情况下,我们制作了一些过滤器,将这些字符或字形更改为点。之后,Lotus Notes创建了文件夹和文件名,稍后将其用作所以这个问题是通过这种方式解决的。如果你有这种类型的选项,那么你可以很容易地解决
建议2:
不同的人面临着相同类型的问题,所以他们尝试了不同的方式
有人说,
- 用点(.)替换它解决了这个问题
片假名中间点(・)代码>是一个双倍宽度的字符。如果您想 使用片假名(日语)中点,考虑使用半宽度。 片假名中间有一个圆点
- 换成普通子弹,效果很好
twitter文本
,他们已经为片假名中间点制定了解决方案(・)代码>。请参见中的
资源链接
但阿托姆开发商在下文中表示:
我可以确认我们没有片假名中间点图示符(U+30FB)
在普通的Hack字体中,有一个中间点(U+00B7)将
有你在这里的样子。我可以确认
U+00B7图示符与图形的其余部分具有相同的固定宽度间距
常规集(和所有其他变量集)
资源链接:
首先,我想告诉大家点或句点(.)是。因此点(.)不是问题。字符编码和服务器设置可能是问题
只能使用通过Internet发送URL。如果URL包含ASCII集之外的字符,则必须转换URL
jCIFS还可以寻址服务器和工作组
重要提示:表示工作组、服务器、共享或共享的所有SMB URL
目录需要尾部斜杠“/”
将java.net.URL
类与'smb://'
URL一起使用时,必须首先调用静态jcifs.Config.registerSmbURLHandler();
方法。这是注册smb协议处理程序所必需的
SMB URL(域;用户:pass)的userinfo组件必须是URL
如果包含保留字符,则进行编码。根据RFC 2396
这些字符是非US-ASCII字符和大多数元字符
但是,jCIFS将正确处理除所使用的“@”以外的任何内容
从服务器和“%”分隔userinfo组件,后者是
URL转义字符本身
字符检查和设置
然后,您必须知道正在使用哪个字符集。通过使用以下代码,您可以获得:
System.out.println(Charset.defaultCharset());
或者你可以发出命令
$testparm-v|grep dos
显示Samba的默认OEM编码
CIFS使用UTF-16LE
或默认代码页。默认
JCIFS使用的代码页是Cp850或US_ASCII
在jCIFS中,您可以将其设置为UTF-8并检查:
System.setProperty("jcifs.encoding", "UTF8");
那么对于日语地区,你可以试试
System.setProperty("jcifs.encoding", "Shift_JIS");
共享名称、密码、,
在某些情况下,文件和目录名包含非ASCII
可能无法正确处理字符。
默认情况下,此属性是Cp860,它是MS-DOS Latin1
注意:Cp860字符集转换器位于jre/lib/charsets.jar中
哪种AFAIK仅由的国际化版本支持
Sun的JRE。如果Cp860不可用,将发生异常。要避免
此异常您可以将jcifs.encoding设置为ASCII,但共享名称和
带有非ASCII字符的密码将无法正确处理。
要确定jCIFS是否正确处理这些字符,请创建
包含非ASCII字符的共享(例如Grüße),然后尝试
列出与ListFiles.java示例程序共享的文件
对于日语,您可以尝试设置jcifs.encoding=Shift\u JIS
下表显示了J2SE 5.0支持的日文
编码集。新java.nio API使用的规范名称在许多情况下与java.io和java.lang API中使用的规范名称不同
----------------------------------------------------------------------------------------------
|Canonical Name for | Canonical Name for java.io | Description |
| java.nio API | and java.lang API | |
----------------------------------------------------------------------------------------------
| EUC-JP | EUC_JP | JISX 0201, 0208 and 0212, EUC encoding |
| | | Japanese |
----------------------------------------------------------------------------------------------
| ISO-2022-JP | ISO2022JP | JIS X 0201, 0208, in ISO 2022 form, |
| | | Japanese |
----------------------------------------------------------------------------------------------
| Shift_JIS | SJIS | Shift-JIS, Japanese |
----------------------------------------------------------------------------------------------
| windows-31j | MS932 | Windows Japanese |
----------------------------------------------------------------------------------------------
| x-euc-jp-linux | EUC_JP_LINUX | JISX 0201, 0208, EUC encoding Japanese |
----------------------------------------------------------------------------------------------
| x-eucJP-Open | EUC_JP_Solaris | JISX 0201, 0208, 0212, EUC encoding |
| | | Japanese |
----------------------------------------------------------------------------------------------
| x-IBM33722 | Cp33722 | IBM-eucJP - Japanese (superset of 5050) |
----------------------------------------------------------------------------------------------
| x-IBM930 | Cp930 | Japanese Katakana-Kanji mixed with 4370 |
| | | UDC, superset of 5026 |
----------------------------------------------------------------------------------------------
| x-IBM939 | Cp939 | Japanese Latin Kanji mixed with 4370 |
| | | UDC, superset of 5035 |
----------------------------------------------------------------------------------------------
| x-IBM942 | Cp942 | IBM OS/2 Japanese, superset of Cp932 |
----------------------------------------------------------------------------------------------
| x-IBM943 | Cp943 | IBM OS/2 Japanese, superset of Cp932 |
| | | and Shift-JIS |
----------------------------------------------------------------------------------------------
我已经分享了一些JCIFS的完整代码示例。您可以尝试一下
以下是检索文件的示例:
您还可以读/写、删除、创建目录、重命名、列出目录内容、列出网络上的工作组/域和服务器、列出服务器的共享、打开命名管道、验证web客户端等
SmbFile、SmbFileInputStream和SmbFileOutputStream类是
类似于File、FileInputStream和FileOutputStream类
通过使用FileInputStream和FileOutputStream,代码如下所示:
SmbFile[] files = getSMBListOfFiles(sb, logger, domain, userName, password, sourcePath, sourcePattern);
if (files == null)
return false;
output(sb, logger, " Source file count: " + files.length);
String destFilename;
FileOutputStream fileOutputStream;
InputStream fileInputStream;
byte[] buf;
int len;
for (SmbFile smbFile: files) {
destFilename = destinationPath + smbFile.getName();
output(sb, logger, " copying " + smbFile.getName());
try {
fileOutputStream = new FileOutputStream(destFilename);
fileInputStream = smbFile.getInputStream();
buf = new byte[16 * 1024 * 1024];
while ((len = fileInputStream.read(buf)) > 0) {
fileOutputStream.write(buf, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
} catch (SmbException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, SMP issue: " + e.getMessage(), e);
e.printStackTrace();
return false;
} catch (FileNotFoundException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, file not found: " + e.getMessage(), e);
e.printStackTrace();
return false;
} catch (IOException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, IO problem: " + e.getMessage(), e);
e.printStackTrace();
return false;
} finally {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, IO problem: " + e.getMessage(), e);
e.printStackTrace();
return false;
}
}
功劳归于@
资源链接:
import jcifs.smb.*;
jcifs.Config.setProperty( "jcifs.netbios.wins", "192.168.1.220" );
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain", "username", "password");
SmbFileInputStream in = new SmbFileInputStream("smb://host/c/My Documents/人事部/要員・コスト管理課/somefile.txt", auth);
byte[] b = new byte[8192];
int n;
while(( n = in.read( b )) > 0 ) {
System.out.write( b, 0, n );
}
SmbFile[] files = getSMBListOfFiles(sb, logger, domain, userName, password, sourcePath, sourcePattern);
if (files == null)
return false;
output(sb, logger, " Source file count: " + files.length);
String destFilename;
FileOutputStream fileOutputStream;
InputStream fileInputStream;
byte[] buf;
int len;
for (SmbFile smbFile: files) {
destFilename = destinationPath + smbFile.getName();
output(sb, logger, " copying " + smbFile.getName());
try {
fileOutputStream = new FileOutputStream(destFilename);
fileInputStream = smbFile.getInputStream();
buf = new byte[16 * 1024 * 1024];
while ((len = fileInputStream.read(buf)) > 0) {
fileOutputStream.write(buf, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
} catch (SmbException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, SMP issue: " + e.getMessage(), e);
e.printStackTrace();
return false;
} catch (FileNotFoundException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, file not found: " + e.getMessage(), e);
e.printStackTrace();
return false;
} catch (IOException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, IO problem: " + e.getMessage(), e);
e.printStackTrace();
return false;
} finally {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, IO problem: " + e.getMessage(), e);
e.printStackTrace();
return false;
}
}
<Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true" />