Проблемы в JCIFS с некоторыми не-ASCII-символами

Я использую JCIFS для доступа к общей папке с большим количеством японских имен и сталкиваюсь с проблемами, когда в ней появляется символ ・

Например:

путь 人事部/要員・コスト管理課/

первая часть нормальная, а вот вторая вызывает проблемы. Это может быть связано с тем, что «・» можно вводить через косую черту, но я не уверен. Я попытался избежать персонажа, но это, похоже, не решает проблему. У вас есть какие-либо идеи, что может быть причиной этого?


person user439407    schedule 02.05.2016    source источник
comment
Не могли бы вы добавить немного минимального кода, чтобы мы могли понять четкую концепцию. Это будет полезно, чтобы дать вам ответ.   -  person SkyWalker    schedule 06.05.2016
comment
Также нужно больше подробностей о том, какие проблемы - сообщения об ошибках, сбои, повреждение и т. д.?   -  person gordy    schedule 06.05.2016
comment
Я предположу: ・ (средняя точка катакана) — это символ, отображаемый, когда имя файла содержит недопустимый символ. Таким образом, в имени файла на самом деле нет ・, и поэтому вы не можете получить к нему доступ.   -  person heenenee    schedule 06.05.2016
comment
вопросы: 1) ваш пользователь пытается получить доступ к известному файлу (можете ли вы это проверить), потому что неизвестные пользователи могут вызывать ошибки. 2) Путь пройден?   -  person jeorfevre    schedule 06.05.2016
comment
Когда вы говорите the first part, вы имеете в виду бит перед первым / после 3-го символа, то есть для создания каталога в файловой системе с именем, указанным выше, вам нужно создать ‹b›два‹/b› каталога, а не один, то есть mkdir -p 人事部/要員・コスト管理課/ будет работать но mkdir 人事部/要員・コスト管理課/ не будет.   -  person Harry    schedule 07.05.2016


Ответы (2)


ОБНОВЛЕНИЕ для U+30FB (КАТАКАНА СРЕДНЯЯ ТОЧКА):

Поскольку @sergey-tachenov указывает, что проблема связана с U+30FB (KATAKANA MIDDLE DOT), тогда ее необходимо решено. По этой причине я хотел бы поделиться некоторым предыдущим проектным опытом и предложениями.

Предложение-1:

Один из моих проектов, мы делаем руководство для проекта. Руководство было на разных языках. Там мы получили такие же проблемы. Мы использовали Lotus Notes. В этом случае мы сделали несколько фильтров, которые изменили эти символы или глифы на точки. После этого Lotus Notes создает папку и имя файла, которые позже используются в качестве пути. Таким образом, эта проблема была решена. Если у вас есть такой вариант, вы можете легко это исправить.

Предложение-2:

Разные люди сталкиваются с одним и тем же типом проблемы. Поэтому они пытались по-разному.

Некоторые говорят,

  • замена его точкой (.) решила проблему.
  • KATAKANA MIDDLE DOT (・) — это символ двойной ширины. Если вы хотите использовать среднюю точку Катакана (японский), рассмотрите возможность использования вместо нее ПОЛУШИРИННОЙ КАТАКАНЫ СРЕДНЕЙ ТОЧКИ.
  • перешел на обычную пулю и все работает.

Если вы видите twitter-text, они сделали решение для KATAKANA MIDDLE DOT (・). См. репозиторий github

Ссылка на ресурс

Решена проблема со средней точкой катаканы в Twitter-Text

Но разработчик attom chrissimpkins заявил, что ниже

Я могу подтвердить, что у нас нет среднего точечного глифа катаканы (U+30FB) в обычном шрифте Hack. Есть средняя точка (U + 00B7), которая будет иметь вид, который вы здесь ищете. Я могу подтвердить, что глиф U + 00B7 имеет такой же фиксированный интервал ширины, как и остальная часть обычного набора (и все другие наборы вариантов).

Ссылка на ресурс: https://github.com/atom/atom/issues/9115


Во-первых, я хочу поделиться с вами тем, что точка или точка (.) — это символ ASCII. Так что точка (.) не проблема. Проблема может заключаться в кодировке символов и настройке сервера.

URL-адреса можно отправлять через Интернет только с использованием набора символов ASCII. Если URL-адрес содержит символы, не входящие в набор ASCII, URL-адрес необходимо преобразовать.

URL-адрес SMB будет выглядеть следующим образом:

smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?param=value[param2=value2[...]]]

jCIFS также может обращаться к серверам и рабочим группам.

Важно: все URL-адреса SMB, представляющие рабочие группы, серверы, общие ресурсы или каталоги, должны иметь завершающую косую черту «/».

При использовании класса java.net.URL с 'smb://' URL-адресами необходимо сначала вызвать метод static jcifs.Config.registerSmbURLHandler();. Это необходимо для регистрации обработчика протокола SMB.

Компонент userinfo URL-адреса SMB (домен;пользователь:пароль) должен быть закодирован в URL-адресе, если он содержит зарезервированные символы. Согласно RFC 2396 эти символы не являются символами US-ASCII и большинством метасимволов, однако jCIFS будет правильно работать с чем угодно, кроме «@», который используется для разграничения компонента userinfo с сервером, и «%», который является самим escape-символом URL.


Проверка и установка символов

Затем вы должны знать, какую кодировку вы используете. Используя следующий код, вы можете получить:

System.out.println(Charset.defaultCharset());

или вы можете дать команду

$ testparm -v | grep dos показывает, что OEM-кодировка Samba по умолчанию

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, который, насколько мне известно, поддерживается только интернационализированной версией Sun JRE. Если Cp860 недоступен, возникает исключение. Чтобы избежать этого исключения, вы можете установить jcifs.encoding в ASCII, но общие имена и пароли с символами, отличными от ASCII, не будут обрабатываться правильно. Чтобы определить, правильно ли jCIFS обрабатывает эти символы, создайте общую папку, содержащую символы, отличные от ASCII (например, Grüße), а затем попробуйте составить список этой общей папки с помощью примера программы ListFiles.java.


Настройка свойств клиента для японского языка

Для японского языка попробуйте установить jcifs.encoding = Shift_JIS

В следующих таблицах показаны наборы кодировок Japanese, поддерживаемые J2SE 5.0. Канонические имена, используемые новыми API-интерфейсами java.nio, во многих случаях не совпадают с именами, используемыми в API-интерфейсах java.io и java.lang.

----------------------------------------------------------------------------------------------
|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. Копирование ресурсов в сеть Windows и из нее с помощью Java
  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 );
}

Вы также можете читать/записывать, удалять, создавать каталоги, переименовывать, перечислять содержимое каталога, перечислять рабочие группы/домены и серверы в сети, перечислять общие ресурсы сервера, открывать именованные каналы, аутентифицировать веб-клиенты и т. д.

Классы 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;
        }
    }

Кредит принадлежит @человеку по имени Хейни

Ссылка на ресурс: Как скопировать файл из общей папки smb на локальный диск с помощью jcifs в Java?


Мера предосторожности-1:

Дополнительные предупреждения для пользователей HTTPS и Tomcat см.

В большинстве случаев URL-адреса, работающие через HTTP, работают нормально, но не при использовании HTTPS (т. е. через SSL). Обычно это приводит к тому, что символы Unicode (не ASCII) в URL-адресе HTTPS отображаются неправильно в URL-адресе, а обслуживаемая страница содержит множество ошибок. Это происходит, когда флаг useBodyEncodingForURI="true" не определен в определении соединителя HTTPS в conf/server.xml сервера приложений Apache Tomcat. работает JIRA. Этот флаг установлен по умолчанию в "рекомендуемых" установках дистрибутива JIRA.< /а>

Однако в настройках JIRA WAR это может быть не так. Следовательно, убедитесь, что флаг useBodyEncodingForURI="true" включен в следующий элемент файла conf/server.xml вашей установки Apache Tomcat с JIRA:

<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" />

После указания useBodyEncodingForURI="true" во всех определениях соединителя (i.e. both the HTTP and the HTTPS connectors), как описано в разделе «Изменение Tomcat server.xml» документа Установка JIRA в документации Tomcat 6.0 или 7.0

Ссылка на ресурс:

Как сделать так, чтобы символы Unicode, отличные от ASCII, в URL-адресе HTTPS отображались правильно


Для символа НЕ-ASCII вы можете пройти

  1. (Пожалуйста) прекратите использование небезопасных символов в URL
  2. Можно ли использовать в URL-адресах символы, отличные от ASCII?
  3. Целесообразно ли иметь не-ascii-символы в URL-адрес?
person SkyWalker    schedule 07.05.2016
comment
Эта точка определенно не является символом ASCII. Это U+30FB (КАТАКАНА СРЕДНЯЯ ТОЧКА). - person Sergei Tachenov; 09.05.2016
comment
@SergeyTachenov Спасибо за указание. Я обновил ответ с некоторыми предложениями. - person SkyWalker; 10.05.2016

Взгляните на комментарий heenee, пройдитесь по файловой системе вашего сервера, чтобы проверить, каково настоящее имя общего ресурса. Я тестировал доступ к сетевым ресурсам со средней точкой и японскими именами на сервере Samba (UTF-8) с исходным кодом 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));
    }
}
person vzamanillo    schedule 06.05.2016