簡體   English   中英

JCIFS中存在某些非ascii字符的問題

[英]Problems in JCIFS with certain non-ascii characters

我正在使用JCIFS來訪問一個包含很多日文名稱的文件共享,當我在其中的字符時遇到問題

例如:

路徑人事部/要員·コスト管理課程/

第一部分沒問題,但第二部分引起了問題。 這可能與“·”可以使用斜線輸入的事實有關,但我不確定。 我試過逃避角色,但似乎沒有解決問題。 你有什么可能導致它的線索嗎?

U + 30FB更新(KATAKANA MIDDLE DOT):

正如@ sergey-tachenov指出這個問題與U+30FBU+30FB MIDDLE DOT)有關,那么它需要解決。 出於這個原因,我想分享一些以前的項目經驗和建議。

建議1:

我的一個項目,我們正在為項目制作一些手冊。 該手冊有各種語言版本。 我們遇到了同樣的問題。 我們使用Lotus Notes 在這種情況下, 我們制作了一些過濾器,將這些字符或字形更改為點 之后蓮花筆記創建文件夾和文件名,稍后將其用作路徑。 所以這個問題就這樣解決了。 如果您有這種類型的選項,那么您可以輕松修復。

建議2:

各種各樣的人都面臨同樣的問題。 所以他們以各種方式嘗試過。

有人說,

  • 用點(。)替換它解決了這個問題。
  • 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 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分享了一些完整的代碼示例。 你可以嘗試一下

  1. 使用Java在網絡共享文件夾上復制文件
  2. 使用Java將資源復制到Windows網絡或從Windows網絡復制資源
  3. Java教程 - 使用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;
        }
    }

歸功於 @ man叫哈尼

資源鏈接: 如何使用Java中的jcifs將文件從smb共享復制到本地驅動器?


注意事項1:

有關HTTPS和Tomcat用戶的更多注意事項,

在大多數情況下,通過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”字符正確顯示


對於非ASCII字符,您可以通過

  1. (請)停止在URL中使用不安全的字符
  2. 我可以在URL中使用非ASCII字符嗎?
  3. 是否建議在URL中使用非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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM