Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Стримы для простых смертных / 25 сообщений из 46, страница 1 из 2
17.02.2017, 13:39
    #39406562
JDS
JDS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
Все время нет четкого понимания разницы между InputStream и OutputStream.
Т.к. все относительно, то не врубаюсь когда какие классы (инпут- или аутпут-) использовать.
Входящий поток это относительно чего он входящий и то же самое с исходящим?
...
Рейтинг: 0 / 0
17.02.2017, 13:44
    #39406569
JDS
JDS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
Например, если мы пишем файл, то понятно, что это аутпут, если читаем, то инпут.
Но если например у нас есть массив байт, который надо прочитать и записать в другой массив байт?
Надо сначала поместить этот исходный массив в InputStream прочитать в буфер, потом записать его через OutputStream в другой массив?
Сори, что бред какой-то )
...
Рейтинг: 0 / 0
17.02.2017, 13:48
    #39406577
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
JDSВходящий поток это относительно чего он входящий и то же самое с исходящим?
Относительно кода, который его использует.
...
Рейтинг: 0 / 0
17.02.2017, 14:07
    #39406600
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
Ну запиши в InputStream, или прочитай с OutputStream, если получится, то можно продолжить тему.
...
Рейтинг: 0 / 0
17.02.2017, 14:55
    #39406662
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
JDSНапример, если мы пишем файл, то понятно, что это аутпут, если читаем, то инпут.
Но если например у нас есть массив байт, который надо прочитать и записать в другой массив байт?
Надо сначала поместить этот исходный массив в InputStream прочитать в буфер, потом записать его через OutputStream в другой массив?
Сори, что бред какой-то )

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

Но в остальном API достаточно понятный.
...
Рейтинг: 0 / 0
28.02.2017, 13:28
    #39411585
JDS
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
28.02.2017, 14:47
    #39411668
JDS
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
28.02.2017, 15:18
    #39411708
JDS
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
28.02.2017, 15:21
    #39411714
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
JDS,

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


Откуда zin может знать сколько ему считывать байт в буфер?
Дочитает до конца буфера и скажет -1?
Разве здесь smart-указатель?
...
Рейтинг: 0 / 0
28.02.2017, 17:05
    #39411829
JDS
JDS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
SQL2008Дочитает до конца буфера и скажет -1?
Согласен, выглядит подозрительно, но подозреваю, что -1 придет, когда уже нечего читать, т.е. все прочитал ) (хвостик должен бы вернуть >0).
Подключил апачевскую либу org.apache.tools.zip.
Она во всяком случае прочитала содержимое архива и не ругнулась.
Придется попробовать изобразить то же самое с потоками и этой либой.
...
Рейтинг: 0 / 0
28.02.2017, 17:15
    #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
28.02.2017, 18:23
    #39411905
JDS
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
01.03.2017, 15:32
    #39412528
JDS
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
01.03.2017, 15:34
    #39412530
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
JDS,

И зачем понадобился именно ZipFile? Можно создать виртуальный диск. Только зачем?
...
Рейтинг: 0 / 0
01.03.2017, 15:41
    #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
01.03.2017, 15:42
    #39412544
JDS
JDS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
Blazkowicz , залез в примеры по net.lingala.zip4j . Там везде ноги начинают расти от ZipFile.
То есть создается новый ZipFile, который на вход берет или File или строку с указанием пути к архиву.
Далее в этом ZipFile или ищется конкретный FileHeader по имени (если заранее известно) или перебираются все.
Далее для каждого FileHeader создается ZipInputStream и читается файл из архива в буфер.
Как без ZipFile сразу сразу достать файл из архива в ZipInputStream, не втыкаю.
...
Рейтинг: 0 / 0
01.03.2017, 15:45
    #39412548
JDS
JDS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
SQL2008Можно! Сделайте временный файл и работайте с ним. Поищу код, если найду, то поделюсь.
С временным файлом понятно, но это ведь тоже операции с диском, хотелось бы обойтись без них.
Вирт. диск вариант, но не подходит.
...
Рейтинг: 0 / 0
01.03.2017, 15:57
    #39412571
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
JDS Blazkowicz , залез в примеры по net.lingala.zip4j . Там везде ноги начинают расти от ZipFile.
Ну, и на кой черт тогда это счастье нужно?
...
Рейтинг: 0 / 0
01.03.2017, 16:02
    #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
01.03.2017, 16:10
    #39412580
JDS
JDS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стримы для простых смертных
BlazkowiczНу, и на кой черт тогда это счастье нужно?
Примеры или lingala? Сам тоже спрашиваю себя, но в отношении библиотеки )
Но например и апачевская либа вроде тоже работает от файла, а стандартный java.util.zip не ест приходящие архивы, хотя с ним и получается подсунуть поток на распаковку.
Остается или все-таки через временные файлы, или искать еще какие-то библиотеки, или найти возможность в этих библиотеках все-таки работать без записи на диск, или написать свой архиватор )
Самый простой и быстрый вариант - это первый конечно.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Стримы для простых смертных / 25 сообщений из 46, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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