betacode

Руководство Java PushbackInputStream

  1. PushbackInputStream
  2. Examples

1. PushbackInputStream

Иногда при работе с двоичным входным потоком (binary input stream) вам нужно прочитать несколько bytes заранее, чтобы увидеть, что произойдет, прежде чем вы сможете определить интерпретацию текущего byte, а затем вы можете отодвинуть их назад. Класс PushbackInputStream позволяет вам это сделать.
PushbackInputStream управляет объектом InputStream, который считывает данные из источника (например, файла). В то же время PushbackInputStream также управляет массивом byte - buffer.
В начале нет byte, назначенного массиву buffer, метод PushbackInputStream.read возвращает bytes из InputStream.read.
Если вы вызываете метод PushbackInputStream.unread для возврата bytes, они будут сохранены в массиве buffer.
При следующем вызове метода PushbackInputStream.read он возвращает bytes, хранящиеся в массиве buffer. Метод InputStream.read будет вызван только в том случае, если в массиве buffer нет byte.
PushbackReader​ constructors
public PushbackReader​(Reader in, int size)

public PushbackReader​(Reader in)
  • Конструктор PushbackInputStream(InputStream,int) создает объект PushbackInputStream с массивом buffer заданного размера.
  • Конструктор PushbackInputStream(InputStream) создает объект PushbackInputStream с массивом buffer, имеющим размер по умолчанию (size =1).

2. Examples

Предположим, что вы храните все данные 3 изображений в одном файле, они разделены "@@@". Как прочитать этот файл и записать в 3 файла изображения, соответствующие данным?

..bytes..of..image1..@@@..bytes..of..image2..@@@..bytes..of..image3..

Используйте PushbackInputStream для чтения содержимого вышеуказанного файла данных. Когда вы сталкиваетесь с byte 64 ( @ ), вам нужно прочитать следующие 2 bytes, чтобы решить, что делать с текущим byte.
PushbackInputStreamEx1.java
package org.o7planning.pushbackinputstream.ex;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.net.URL;

public class PushbackInputStreamEx1 {

    private static final String OUT_FOLDER = "/Volumes/Data/test/icons";
    
    private static final String url = "https://s3.o7planning.com/txt/google-emoticons-data.txt";

    public static void main(String[] args) throws IOException {
        InputStream is = new URL(url).openStream();

        PushbackInputStream pis = new PushbackInputStream(is, 2);
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int fileIdx = 0;

        int code;
        while ((code = pis.read()) != -1) {
            if (code == (int)'@') {
                int next1 = pis.read();
                int next2 = pis.read();

                if (next1 == '@' && next2 == '@') {
                    byte[] imageData = baos.toByteArray();
                    fileIdx++;
                    writeToFile(imageData,fileIdx); // Write Image file.

                    baos = new ByteArrayOutputStream();
                } else {
                    baos.write(code);
                    pis.unread(next2);
                    pis.unread(next1);
                }
            } else {
                baos.write(code);
            }
        }
        byte[] imageData = baos.toByteArray();
        fileIdx++;
        writeToFile(imageData,fileIdx);  // Write Image file.

        pis.close();
    }
    
    private static void writeToFile(byte[] data, int fileIdx) throws IOException {
        File file = new File(OUT_FOLDER +"/" + fileIdx + ".png");
        file.getParentFile().mkdirs();
        System.out.println("Write file: " + file.getAbsolutePath());
        
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(data);
        fos.close();
    }
}
Output:
Write file: /Volumes/Data/test/icons/1.png
Write file: /Volumes/Data/test/icons/2.png
Write file: /Volumes/Data/test/icons/3.png
Использование обычного InputStream для чтения каждого byte займет много времени, поэтому вы должны использовать BufferedInputStream для повышения производительности приведенного выше примера:
PushbackInputStreamEx1b.java
package org.o7planning.pushbackinputstream.ex;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.net.URL;

public class PushbackInputStreamEx1b {

    private static final String OUT_FOLDER = "/Volumes/Data/test/icons";
    
    private static final String url = "https://s3.o7planning.com/txt/google-emoticons-data.txt";

    public static void main(String[] args) throws IOException {
        InputStream is = new URL(url).openStream();
        // Create BufferedInputStream object.
        BufferedInputStream bis = new BufferedInputStream(is);

        PushbackInputStream pis = new PushbackInputStream(bis, 2);
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int fileIdx = 0;

        int code;
        while ((code = pis.read()) != -1) {
            if (code == (int)'@') {
                int next1 = pis.read();
                int next2 = pis.read();

                if (next1 == '@' && next2 == '@') {
                    byte[] imageData = baos.toByteArray();
                    fileIdx++;
                    writeToFile(imageData,fileIdx); // Write Image file.

                    baos = new ByteArrayOutputStream();
                } else {
                    baos.write(code);
                    pis.unread(next2);
                    pis.unread(next1);
                }
            } else {
                baos.write(code);
            }
        }
        byte[] imageData = baos.toByteArray();
        fileIdx++;
        writeToFile(imageData,fileIdx);  // Write Image file.

        pis.close();
    }
    
    private static void writeToFile(byte[] data, int fileIdx) throws IOException {
        File file = new File(OUT_FOLDER +"/" + fileIdx + ".png");
        file.getParentFile().mkdirs();
        System.out.println("Write file: " + file.getAbsolutePath());
        
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(data);
        fos.close();
    }
}

Руководства Java IO

Show More