powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Стримы для простых смертных
25 сообщений из 46, страница 1 из 2
Стримы для простых смертных
    #39406562
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все время нет четкого понимания разницы между InputStream и OutputStream.
Т.к. все относительно, то не врубаюсь когда какие классы (инпут- или аутпут-) использовать.
Входящий поток это относительно чего он входящий и то же самое с исходящим?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39406569
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Например, если мы пишем файл, то понятно, что это аутпут, если читаем, то инпут.
Но если например у нас есть массив байт, который надо прочитать и записать в другой массив байт?
Надо сначала поместить этот исходный массив в InputStream прочитать в буфер, потом записать его через OutputStream в другой массив?
Сори, что бред какой-то )
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39406577
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSВходящий поток это относительно чего он входящий и то же самое с исходящим?
Относительно кода, который его использует.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39406600
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну запиши в InputStream, или прочитай с OutputStream, если получится, то можно продолжить тему.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39406662
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSНапример, если мы пишем файл, то понятно, что это аутпут, если читаем, то инпут.
Но если например у нас есть массив байт, который надо прочитать и записать в другой массив байт?
Надо сначала поместить этот исходный массив в InputStream прочитать в буфер, потом записать его через OutputStream в другой массив?
Сори, что бред какой-то )

Моя учительница математики в школе говорила, что через деньги можно обьяснить если не все, то многое!
А типы "ПолучитьДеньги" и "ОтдатьДеньги" вы тоже путаете?
В магазине на кассе получив чек требуете от кассира деньги?
Продаете свой телефон и вместе с зарядным устройством кладете в упаковку бабло за него?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39406665
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDS Но если например у нас есть массив байт, который надо прочитать и записать в другой массив байт?
Смотрите на все глазами буфера для чтения.
Читаем инпутом, пишем отуптом.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39407544
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSВсе время нет четкого понимания разницы между InputStream и OutputStream.
Т.к. все относительно, то не врубаюсь когда какие классы (инпут- или аутпут-) использовать.
Входящий поток это относительно чего он входящий и то же самое с исходящим?
В JDK действительно есть определенная путаница в базовых интерфейсах и классах I/O.
Особенно в части реализации текстовых интерфейсов, таких как Reade/Writer. Должен
признаться что после кодинга под Microsoft C#.net (где-то в 2004) мне было трудно
привыкнуть к способам правильной инициализации конструктора текстового стрима
(с кодировками и с буферизацией). Даже сейчас я наизусть это не помню
и каждый раз заглядываю в справочник.

Но в остальном API достаточно понятный.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411585
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вернулся.
Пока не выходит каменный цветок в потоках.
Задача есть массив байт, представляющих собой архив, его надо распаковать в новый массив байт или в строку (в памяти то бишь).
Пробовал по-разному, текущий вариант:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
private static byte[] getUnzippedFile(ZipInputStream zin, 
                                      String fileExt) throws IOException, Exception {
    byte[] res = null;
    ZipEntry entry;
    try {    
        while ((entry = zin.getNextEntry()) != null) {
            if (entry.isDirectory()) 
                continue;            
            if (entry.getName().endsWith("." + fileExt)) {
               ByteArrayOutputStream streamBuilder = new ByteArrayOutputStream();
               int bytesRead;
               byte[] tempBuffer = new byte[1024];
               while ((bytesRead = zin.read(tempBuffer)) != -1) {
                  streamBuilder.write(tempBuffer, 0, bytesRead);
               }
               res = streamBuilder.toByteArray();               
            }
            zin.closeEntry();
        }
    } catch (Exception e) {
        throw new Exception("Can't unzip ZipInputStream: " + e.getMessage() + "\n" +res, e);
    } finally {
        zin.close();
    }
    
    return res;
}



Вызов:
Код: java
1.
2.
3.
 byte[] arch = ....; // массив байт (архив)
 ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(arch));
 byte[] bRes = getUnzippedFile(zip, "xml");


Ломается на zin.read(tempBuffer):
invalid entry compressed size (expected 5127 but got 5123 bytes)
Что не так пока не пойму.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411668
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал сделать то же самое, но с записью в файл.
Ошибка лезет та же, но при этом файл из архива достается и создается нормально.
Т.е. распаковывается на диск нормально, хоть и с этой же ошибкой.
Поэтому заглушил эксепшн и оставил все как было с потоками:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
private static byte[] getUnzippedFile(ZipInputStream zin, 
                                      String fileExt) throws IOException, Exception {
    byte[] res = null;
    ZipEntry entry;
    try {    
        while ((entry = new ZipEntry(zin.getNextEntry())) != null) {
            if (entry.isDirectory()) 
                continue;            
            if (entry.getName().endsWith("." + fileExt)) {
               ByteArrayOutputStream streamBuilder = new ByteArrayOutputStream();
               int bytesRead;               
               byte[] tempBuffer = new byte[2048];
               
               try {
                    bytesRead = zin.read(tempBuffer);
                    while (bytesRead  > 0) {
                       streamBuilder.write(tempBuffer, 0, bytesRead);
                       bytesRead = zin.read(tempBuffer);
                    }                    
               }  catch (Exception ex) {
                   //System.out.println(ex.getMessage());
               }
               res = streamBuilder.toByteArray();
            }
        }
    } catch (Exception e) {
        //System.out.println(e.getMessage());        
    } finally {
        zin.close();
    }
    
    return res;
}


Хоть и работает, но по-моему корявая бредятина, т.к. глушить ошибки это... ну вы понимаете )
Можно заглушить конкретно эту ошибку, но это тоже не норма имхо.
В общем вопрос пока открыт.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411708
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще проще:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
private static void printFilesInZIP(ZipInputStream zin) throws IOException, Exception {
    ZipEntry entry;
    try {    
        while ((entry = zin.getNextEntry()) != null) 
            System.out.println(entry.getName());        
    } finally {
        zin.close();
    }
}


Один файл проходит, а дальше снова invalid entry compressed size.
То есть даже не прочитать содержимое архива, только первый файл.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411714
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDS,

Ну, так может проблема не в чтении архива а в формировании?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411757
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczНу, так может проблема не в чтении архива а в формировании?
Тоже закралось такое подозрение.
Сохраняем архив в zip-файл.
Он нормально распаковывается архиваторами, которые стоят на машине по дефолту.
Но если пытаться прочитать, этот архив c диска явой, то снова вылезает эта же ошибка:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
    public static void main(String[] args) {
        try(ZipInputStream zin = new ZipInputStream(new FileInputStream("C:\\test\\test.zip")))
        {
            ZipEntry entry;
            String name;
            long size;
            while((entry=zin.getNextEntry())!=null){                 
                name = entry.getName(); // получим название файла
                size=entry.getSize();  // получим его размер в байтах
                System.out.printf("Название: %s \t размер: %d \n", name, size);
            }
        }
        catch(Exception ex){             
            System.out.println(ex.getMessage());
        }

    }


Создаем руками на машине архив, читаем его в яве, все нормально читается.

Буду пытаться понять, что не так в формировании архива, но они приходят извне...
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411763
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSБуду пытаться понять, что не так в формировании архива, но они приходят извне...
В формировании не так ровно то о чем написано в исключении. У файлов в архиве есть заголовок, внутри которого указан размер файла.
https://en.wikipedia.org/wiki/Zip_(file_format)#File_headers
Этот размер не совпадает с фактическим и на то могут быть две причины
1) Ошибка в формировании файла
2) Формат файла не классический Zip из-за чего и возникает разница
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411808
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ой не нравится мне такая конструкция
Код: java
1.
2.
               byte[] tempBuffer = new byte[1024];
               while ((bytesRead = zin.read(tempBuffer)) != -1) {


Откуда zin может знать сколько ему считывать байт в буфер?
Дочитает до конца буфера и скажет -1?
Разве здесь smart-указатель?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411829
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008Дочитает до конца буфера и скажет -1?
Согласен, выглядит подозрительно, но подозреваю, что -1 придет, когда уже нечего читать, т.е. все прочитал ) (хвостик должен бы вернуть >0).
Подключил апачевскую либу org.apache.tools.zip.
Она во всяком случае прочитала содержимое архива и не ругнулась.
Придется попробовать изобразить то же самое с потоками и этой либой.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411837
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как новичок в Java рекомендую использовать библиотеку net.lingala.zip4j
За полдня я написал класс, который зипует файл в памяти, ставит пароль на архив и возвращает его в виде массива байт.
Вот работающий пример. Вам соответственно нужно изучить работу net.lingala.zip4j.io.ZipInputStream
ZipCreationInMemory
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import net.lingala.zip4j.io.ZipOutputStream;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

public class ZipCreationInMemory {
	private InMemoryOutputStream inMemoryOutputStream = null;
    ZipOutputStream zos = null;
    private byte[] buffer = null;
	public ZipCreationInMemory() {
	}
	
	public byte[] ZipCreationInMemory(byte[] source,String strFileName, String strPassword) {
		try {
						
			inMemoryOutputStream = new InMemoryOutputStream();
			
			zos = new ZipOutputStream(inMemoryOutputStream);
			
			ZipParameters params = new ZipParameters();
			params.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
			params.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
            params.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256 );
            params.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); 
            params.setPassword(strPassword);
            params.setEncryptFiles(true);
			params.setFileNameInZip(strFileName);
			params.setSourceExternalStream(true);
			
			zos.putNextEntry(null, params);
			zos.write(source);
			zos.closeEntry();
			zos.finish();
			zos.close();
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
        return inMemoryOutputStream.getZipContent();
	}
}



InMemoryOutputStream
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class InMemoryOutputStream extends OutputStream {

	private List byteList;
	
	private boolean closed;
	
	public InMemoryOutputStream() {
		byteList = new ArrayList();
		closed = false;
	}
	
	public void write(int b) throws IOException {
		if (closed) {
			throw new IOException("trying to write on a closed output stream");
		}
		
		byteList.add(Integer.toString(b));
	}
	
	public void write(byte[] b) throws IOException {
		if (b == null) return;
		write(b, 0, b.length);
	}
	
	public void write(byte[] b, int off, int len) throws IOException {
		if (closed) {
			throw new IOException("trying to write on a closed output stream");
		}
		
		if (b != null && len > 0) {
			for (int i = 0; i < len; i++) {
				byteList.add(Byte.toString(b[i]));
			}
		}
	}
	
	public byte[] getZipContent() {
		if (byteList.size() <= 0) {
			return null;
		}
		
		byte[] zipContent = new byte[byteList.size()];
		
		for (int i = 0; i < byteList.size(); i++) {
			zipContent[i] = Byte.parseByte((String)byteList.get(i));
		}
		
		return zipContent;
	}
	
	public void close() throws IOException {
		closed = true;
	}
}

...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39411905
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В варианте с апачесвкой библиотекой не нашел возможности распаковки из потока, из файла нормально читает:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
    public static void main(String[] args) throws IOException {
        ZipFile zip = new ZipFile("C:\\test\\ttt.zip");
        Enumeration zipEntries = zip.getEntries();
        byte[] res = null;

        while (zipEntries.hasMoreElements()) {
           ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
           System.out.println(zipEntry + "  *********************************************");           
           InputStream is = zip.getInputStream(zipEntry);
           int bytesRead;
           ByteArrayOutputStream streamBuilder = new ByteArrayOutputStream();
           byte[] tempBuffer = new byte[1024];          
           bytesRead = is.read(tempBuffer);
           while (bytesRead  > 0) {
              streamBuilder.write(tempBuffer, 0, bytesRead);
              bytesRead = is.read(tempBuffer);
           }           
           is.close();
           res = streamBuilder.toByteArray();
           streamBuilder.close();
           String st = new String(res, "Cp1251");
           System.out.println(st);           
        }
    }


SQL2008 , спасибо большое, подключил ее, будем посмотреть )
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412528
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока не выходит ибо на вход принимается только файл.
То есть распаковать в памяти можно конечно, но исходный файл требуется, чтобы был на диске, т.е. только два конструктора:
Код: java
1.
2.
3.
ZipFile zipFile = new ZipFile("C:\\test\\ttt.zip");
или
ZipFile zipFile = new ZipFile(new File("C:\\test\\ttt.zip"));



Вопрос: можно ли имеющийся массив байт преобразовать в File, чтобы засунуть его в конструктор ZipFile, не создавая файл на диске?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412530
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDS,

И зачем понадобился именно ZipFile? Можно создать виртуальный диск. Только зачем?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412543
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSПока не выходит ибо на вход принимается только файл.
То есть распаковать в памяти можно конечно, но исходный файл требуется, чтобы был на диске, т.е. только два конструктора:
Код: java
1.
2.
3.
ZipFile zipFile = new ZipFile("C:\\test\\ttt.zip");
или
ZipFile zipFile = new ZipFile(new File("C:\\test\\ttt.zip"));



Вопрос: можно ли имеющийся массив байт преобразовать в File, чтобы засунуть его в конструктор ZipFile, не создавая файл на диске?
Можно! Сделайте временный файл и работайте с ним. Поищу код, если найду, то поделюсь.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412544
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz , залез в примеры по net.lingala.zip4j . Там везде ноги начинают расти от ZipFile.
То есть создается новый ZipFile, который на вход берет или File или строку с указанием пути к архиву.
Далее в этом ZipFile или ищется конкретный FileHeader по имени (если заранее известно) или перебираются все.
Далее для каждого FileHeader создается ZipInputStream и читается файл из архива в буфер.
Как без ZipFile сразу сразу достать файл из архива в ZipInputStream, не втыкаю.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412548
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008Можно! Сделайте временный файл и работайте с ним. Поищу код, если найду, то поделюсь.
С временным файлом понятно, но это ведь тоже операции с диском, хотелось бы обойтись без них.
Вирт. диск вариант, но не подходит.
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412571
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDS Blazkowicz , залез в примеры по net.lingala.zip4j . Там везде ноги начинают расти от ZipFile.
Ну, и на кой черт тогда это счастье нужно?
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412575
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDSSQL2008Можно! Сделайте временный файл и работайте с ним. Поищу код, если найду, то поделюсь.
С временным файлом понятно, но это ведь тоже операции с диском, хотелось бы обойтись без них.
Вирт. диск вариант, но не подходит.

Примерно так (код выдернут из большого алгоритма поэтому чего-то может не хватать)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public File GetFileFromBytes(byte[] buffer) {
	File tmpFile = File.createTempFile("~tmp", ".tmp");
	FileOutputStream os = new FileOutputStream(tmpFile);
	os.write(buffer,0,buffer.length);
	os.flush();
	os.close();
	return tmpFile;
}



Ну и после использования не забывайте удалять временный файл - за вас это никто не сделает :)
...
Рейтинг: 0 / 0
Стримы для простых смертных
    #39412580
JDS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczНу, и на кой черт тогда это счастье нужно?
Примеры или lingala? Сам тоже спрашиваю себя, но в отношении библиотеки )
Но например и апачевская либа вроде тоже работает от файла, а стандартный java.util.zip не ест приходящие архивы, хотя с ним и получается подсунуть поток на распаковку.
Остается или все-таки через временные файлы, или искать еще какие-то библиотеки, или найти возможность в этих библиотеках все-таки работать без записи на диск, или написать свой архиватор )
Самый простой и быстрый вариант - это первый конечно.
...
Рейтинг: 0 / 0
25 сообщений из 46, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Стримы для простых смертных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]