Как создать java.io.File из ByteArrayOutputStream? - PullRequest
2 голосов
/ 20 октября 2010

Я читаю кучу файлов с FTP.Затем мне нужно распаковать эти файлы и записать их на файловый ресурс.

Я не хочу сначала записывать файлы, а затем читать их обратно и разархивировать.Я хочу сделать все это за один раз.Это возможно?

Это мой код

FTPClient fileclient = new FTPClient();
..

ByteArrayOutputStream out = new ByteArrayOutputStream();
fileclient.retrieveFile(filename, out);

??????? //How do I get my out-stream into a File-object? 

File file = new File(?);

ZipFile zipFile = new ZipFile(file,ZipFile.OPEN_READ);

Есть идеи?

Ответы [ 6 ]

4 голосов
/ 20 октября 2010

Вы должны использовать ZipInputStream, обернутый вокруг InputStream, возвращенного из FTPClient s retrieveFileStream(String remote).

3 голосов
/ 20 октября 2010

Вам не нужно создавать объект File.

Если вы хотите сохранить файл, вам следует направить поток непосредственно в ZipOutputStream

ByteArrayOutputStream out = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(out);

// do whatever with your zip file

Есливместо этого вы хотите открыть только что полученный файл с помощью ZipInputStream:

new ZipInputStream(fileClient.retrieveFileStream(String remote));

Просто прочитайте документ здесь и здесь

2 голосов
/ 20 октября 2010

Я думаю, что вы хотите:

ZipInputStream zis = new ZipInputStream( new ByteArrayInputStream( out.toByteArray() ) );

Затем прочитайте ваши данные из ZipInputStream.

1 голос
/ 20 октября 2010

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

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

В Java объект File вообще не представляет файл. Скорее, он представляет файл имя или * путь ". Хотя это имя или путь часто соответствует реальному файлу, это не обязательно должно быть так.

Это может звучать как расчесывание волос, но рассмотрим следующий сценарий:

File dir = new File("/tmp/foo");
boolean isDirectory = dir.isDirectory();
if (isDirectory) {
    // spend a long time computing some result
    ...
    // create an output file in 'dir' containing the result
}

Теперь, если экземпляры класса File представляют объекты в файловой системе, то можно ожидать, что код, создающий выходной файл, будет успешным (по модулю разрешений). Но на самом деле создание может завершиться неудачно, потому что что-то удалило «/ tmp / foo» или заменило его обычным файлом.

Надо сказать, что некоторые методов класса File, похоже, предполагают, что объект File соответствует реальному объекту файловой системы. Примерами являются методы получения размера файла или временных меток или для перечисления имен в каталоге. Однако в каждом случае указывается, что метод вызывает исключение, если фактический файл не существует или имеет неправильный тип для запрошенной операции.

1 голос
/ 20 октября 2010

Ну, вы можете просто создать FileOutputStream и затем записать данные из этого:

FileOutputStream fos = new FileOutputStream(filename);
try {
  out.writeTo(fos);
} finally {
  fos.close();
}

Затем просто создайте объект File:

File file = new File(filename);

Вам нужнопонять, что объект File не представляет никаких реальных данных на диске - это просто имя файла, по сути.Файл даже не должен существовать.Если вы хотите на самом деле записать данные , для этого и нужен FileOutputStream.

РЕДАКТИРОВАТЬ: я только что заметил, что вы не хотите сначала записывать данные - но эточто вы должны сделать , если вы собираетесь передать файл чему-то, что ожидает подлинный файл с данными.

Если вы не хотите этого делать,вам придется использовать другой API, который не ожидает, что файл будет существовать ... согласно ответу Qwerky.

0 голосов
/ 21 мая 2013

Просто измените ByteArrayOutputStream на FileOutputStream.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...