2016-03-31 2 views
4

Мое приложение Java требует доступа к большому файлу excel (размером 1 ГБ +), сохраненному в удаленной общей папке. Я использую SmbFile, чтобы получить файл с аутентификацией.Преобразование SmoFile в Java IO-файл

Примечание: Загрузка файла не является вариантом в основном по причинам размера.

Проблема заключается в том, что мне нужен файл excel для Java IO File, а не SmbFile, поскольку other libraries, который я использую для синтаксического анализа excel, принимает только Java IO File.

  1. Есть ли способ конвертировать этот SmbFile в Java-совместимый файл?
+2

Включает ли другая библиотека что-либо еще, кроме файла? Например. 'InputStream'? Если да, вы можете использовать 'SmbFile.getInputStream()'. Если нет, вы можете загрузить файл локально (например, во временный файл) и использовать его для другой библиотеки. Будет ли это работать на вас? –

+0

Библиотека работает с InputStream, но проблема в том, что она также закрывает поток после обработки каждого листа excel, а затем я должен открыть его снова для следующего листа, который, я думаю, должен быть в порядке. Загрузка файла не является вариантом из-за размера excel (1GB +). Я попробую InputStream и дам вам знать. –

+1

Можете ли вы включить библиотеку, которую вы используете для синтаксического анализа excel? Возможно, это вызывает больше людей, чтобы помочь. –

ответ

4

См implementation details библиотеки:

Эта библиотека будет принимать предоставленный InputStream и выводить его в файловую систему. (...) После создания файла он затем передается в память из файловой системы.

Причина, по которой поток, выводимый таким образом, связан с тем, как работают файлы ZIP. Поскольку формат файла XLSX в основном является ZIP-файлом, невозможно найти все записи без чтения всего InputStream.

(...) Эта библиотека работает, считывая поток во временный файл. В рамках действия автоматического закрытия временный файл удаляется.

Если вам требуется больше контроля над созданием/удалением файла, существует возможность инициализировать библиотеку с помощью java.io.File. Этот файл не будет записан или удален

Так что не имеет значения, если вы используете File или InputStream API - весь файл нужно будет загрузить в любом случае.

Самое простое решение передать SmbFile.getInputStream() в

StreamingReader.builder().read(smbFile.getInputStream()) 

в качестве альтернативы, но вы можете сначала загрузить файл, например. с помощью IOUtils.copy() или Files.copy()

File file = new File("..."); 
try (
    in = smbFile.getInputStream(); 
    out = new FileOutputStream(file) 
) { 
    IOUtils.copy(in, out); 
} 

или

try (in = smbFile.getInputStream()) { 
    Files.copy(smbFile.getInputStream(), file.toPath()); 
} 

и передать file в

StreamingReader.builder().read(file) 
+0

Большое вам спасибо за то, что потратили время на проверку этой библиотеки. Позвольте мне объяснить главный вопрос здесь. Я не могу скопировать файл на свой локальный сервер из-за размера файла, который увеличивает время (есть много проверок проверки, которые должны произойти с 1kk + строками с 338 столбцами, поэтому загрузка файла происходит из таблицы. –

+0

Причина, по которой я бы предпочел не использовать inputStream и передавать его в эту библиотеку, так это то, что она не предоставляет никакого способа узнать, сколько листов там до чтения, оно просто говорит вам, доступен ли лист, если вы указываете имя для него, и мне нужен номер Таким образом, моя работа заключалась в том, чтобы распаковать файл и проверить папку и количество листов, что можно сделать с помощью Apache POI, но использование InputStream вызовет исключение из-за размера файла, поэтому это можно сделать только в том случае, если файл может читайте как файл Java –

+0

Я пытаюсь разместить файл полностью в папке своего сервера, чтобы иметь локальный доступ к нему, что упростит все для него. Но еще раз большое спасибо за вашу помощь –

0

Недавно у меня была подобная ситуация, однако, я не нашел хорошее решение в в Интернете, но я написал базовый код, который делал то, что мне было нужно.

В вашем случае вам необходимо скопировать файл excel из источника (Remote Directory) с помощью SmbFile с аутентификацией в пункт назначения (Local Directory) и только после этого, преобразовать путь к файлу excel адресата (getCanonicalPath() функция) и преобразовать его из формата SmbFile в формат файла с помощью кода ниже. После этого создайте объект File с помощью пути назначения файла и сделайте то, что хотите.

Я использую JCIFS для работы с удаленными общими каталогами, используя класс SMBFILE.

Во-первых, вам необходимо импортировать основные библиотеки:

import java.io.File; 
import java.io.IOException; 
import jcifs.smb.SmbFile; 

Во-вторых, вам нужно создать статический метод для преобразования из SmbFile формат Формат файла:

/** 
* This method convert a directory path from SmbFile format to File format.<br /> 
* <p><strong>Sintax:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertSmbFileToFile("Canonical Path")</p> 
* <p><strong>Example:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertSmbFileToFile("smb://localhost/D$/DOCUMENTOS/workspace/tests2/access")</p> 
* @param smbFileCanonicalPath String 
* @see String 
*/ 
public static String convertSmbFileToFile(String smbFileCanonicalPath) { 
    String[] tempVar = smbFileCanonicalPath.substring(6).replace("$", ":").split("/"); 
    String bar = "\\"; 
    String finalDirectory = ""; 
    for (int i = 1; i < tempVar.length; i++) { 
     finalDirectory += tempVar[i] + bar; 
     if (i == tempVar.length - 1) { 
      finalDirectory = finalDirectory.substring(0,finalDirectory.length()-1); 
     } 
    } 
    return finalDirectory; 
} 

Opcional, вы также можете создать статический метод для преобразования из Файл формат в SmbFile Формат:

/** 
* This method convert a directory path from File format to SmbFile format.<br /> 
* <p><strong>Sintax:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertFileToSmbFile("Canonical Path")</p> 
* <p><strong>Example:</strong> <br />&nbsp;&nbsp;&nbsp;&nbsp;convertFileToSmbFile("D:\DOCUMENTOS\workspace\tests2\access")</p> 
* @param fileCanonicalPath String 
* @see String 
*/ 
public static String convertFileToSmbFile(String fileCanonicalPath) { 
    return "smb://localhost/" + fileCanonicalPath.toString().replace(":", "$").replace("\\", "/"); 
} 

Наконец, вы можете назвать такие методы, как на примере ниже:

String dirDest = "access/"; 

    try { 

     File localDirFile = new File(dirDest); 

     SmbFile localSmbDirFile = new SmbFile(convertFileToSmbFile(localDirFile.getCanonicalPath())); 
     File localDirFile2 = new File(convertSmbFileToFile(localSmbDirFile.getCanonicalPath())); 

     System.out.println("Original File Format: " + localDirFile.getCanonicalPath()); 
     System.out.println("Original File Format to SmbFile Format: " + localSmbDirFile.getCanonicalPath()); 
     System.out.println("Converted SmbFile Format to File Format: " + localDirFile2.getCanonicalPath()); 

    } catch (IOException e) { 

     System.err.println("[ERR] IO Exception - " + e); 

    } 

Результат предыдущего кода запуска:

Original File Format: D:\DOCUMENTOS\workspace\tests2\access 
Original File Format to SmbFile Format: smb://localhost/D$/DOCUMENTOS/workspace/tests2/access 
Converted SmbFile Format to File Format: D:\DOCUMENTOS\workspace\tests2\access 

Дополнительная информация: getCanonicalPath()

Возможно, этот код поможет вам, и я могу поговорить, если вы хотите.

Удачи!