[英]Problems in JCIFS with certain non-ascii characters
我正在使用JCIFS來訪問一個包含很多日文名稱的文件共享,當我在其中的字符時遇到問題
例如:
路徑人事部/要員·コスト管理課程/
第一部分沒問題,但第二部分引起了問題。 這可能與“·”可以使用斜線輸入的事實有關,但我不確定。 我試過逃避角色,但似乎沒有解決問題。 你有什么可能導致它的線索嗎?
正如@ sergey-tachenov指出這個問題與U+30FB
( U+30FB
MIDDLE DOT)有關,那么它需要解決。 出於這個原因,我想分享一些以前的項目經驗和建議。
我的一個項目,我們正在為項目制作一些手冊。 該手冊有各種語言版本。 我們遇到了同樣的問題。 我們使用Lotus Notes
。 在這種情況下, 我們制作了一些過濾器,將這些字符或字形更改為點 。 之后蓮花筆記創建文件夾和文件名,稍后將其用作路徑。 所以這個問題就這樣解決了。 如果您有這種類型的選項,那么您可以輕松修復。
各種各樣的人都面臨同樣的問題。 所以他們以各種方式嘗試過。
有人說,
KATAKANA MIDDLE DOT (・)
是雙倍寬度的角色。 如果您想使用片假名(日語)中點,請考慮使用HALFWIDTH KATAKANA MIDDLE DOT。 如果您看到twitter-text
,他們已經為KATAKANA MIDDLE DOT (・)
制定了解決方案。 在github repo中查看
Katakana Middle Dot問題在Twitter-Text中得到解決
但是開發人員chrissimpkins表示如下
我可以確認我們在常規Hack字體中沒有片假名中間點字形(U + 30FB)。 有一個中間點(U + 00B7),它具有你在這之后的外觀。 我可以確認U + 00B7字形與常規集的其余部分(以及所有其他變體集)具有相同的固定寬度間距。
資源鏈接: https : //github.com/atom/atom/issues/9115
首先,我想與您分享點或句點(。)是ASCII字符 。 所以dot(。)不是問題。 字符編碼和服務器設置可能是個問題。
URL只能使用ASCII字符集通過Internet發送。 如果URL包含ASCII集之外的字符,則必須轉換URL。
smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?param=value[param2=value2[...]]]
jCIFS還可以處理服務器和工作組。
重要提示:表示工作組,服務器,共享或目錄的所有SMB URL都需要使用尾部斜杠“/”。
當使用帶有'smb://'
URL的java.net.URL
類時,首先需要調用static jcifs.Config.registerSmbURLHandler();
方法。 這是注冊SMB協議處理程序所必需的。
如果SMB URL的userinfo組件(domain; user:pass)包含保留字符,則必須對其進行URL編碼。 根據RFC 2396,這些字符是非US-ASCII字符和大多數元字符,但是jCIFS可以正常使用除“@”之外的任何內容,用於從服務器界定userinfo組件,而'%'是URL轉義字符本身。
然后你必須知道你正在使用哪個charset。 通過使用以下代碼,您可以獲得:
System.out.println(Charset.defaultCharset());
或者你可以發號施令
$ testparm -v | grep dos
$ 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_JIS
下表顯示了J2SE 5.0支持的Japanese
編碼集 。 新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分享了一些完整的代碼示例。 你可以嘗試一下
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 );
}
您還可以讀/寫,刪除,創建目錄,重命名,列出目錄內容,列出網絡上的工作組/ ntdomains和服務器,列出服務器的共享,打開命名管道,驗證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;
}
}
資源鏈接: 如何使用Java中的jcifs將文件從smb共享復制到本地驅動器?
在大多數情況下,通過HTTP運行的URL工作正常,但在使用HTTPS(即通過SSL)時則不行 。 這通常會導致HTTPS URL中的Unicode(非ASCII)字符在URL中顯示不正確,並且服務頁面包含大量錯誤當conf/server.xml
中的HTTPS連接器定義中未定義useBodyEncodingForURI="true"
標志時會發生這種情況運行JIRA的Apache Tomcat應用程序服務器的conf/server.xml
。 默認情況下,此標志在JIRA的“推薦”分發安裝中設置為此標志。
但是,在JIRA WAR設置中,情況可能並非如此。 因此,請確保useBodyEncodingForURI="true"
標志包含在運行JIRA的Apache Tomcat安裝的conf/server.xml
文件的以下元素中:
<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" />
在所有連接器定義(ie both the HTTP and the HTTPS connectors)
指定useBodyEncodingForURI="true"
之后,如在Tomcat 6.0或7.0文檔上安裝JIRA的“修改Tomcat server.xml”部分所述
如何使HTTPS URL中的Unicode“非ASCII”字符正確顯示
看看heenenee的評論,通過服務器文件系統走一走,檢查一下真實的共享名稱。 我正在測試使用Java源(UTF-8)的Samba服務器(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));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.