PDF в байтовый массив и наоборот - PullRequest
27 голосов
/ 15 июля 2009

Мне нужно преобразовать pdf в байтовый массив и наоборот.

Может ли кто-нибудь мне помочь?

Вот так я конвертирую в байтовый массив

public static byte[] convertDocToByteArray(String sourcePath) {

    byte[] byteArray=null;
    try {
        InputStream inputStream = new FileInputStream(sourcePath);


        String inputStreamToString = inputStream.toString();
        byteArray = inputStreamToString.getBytes();

        inputStream.close();
    } catch (FileNotFoundException e) {
        System.out.println("File Not found"+e);
    } catch (IOException e) {
                System.out.println("IO Ex"+e);
    }
    return byteArray;
}

Если я использую следующий код для преобразования его обратно в документ, создается PDF. Но это говорит 'Bad Format. Not a pdf'.

public static void convertByteArrayToDoc(byte[] b) {          

    OutputStream out;
    try {       
        out = new FileOutputStream("D:/ABC_XYZ/1.pdf");
        out.close();
        System.out.println("write success");
    }catch (Exception e) {
        System.out.println(e);
    }

Ответы [ 12 ]

31 голосов
/ 15 июля 2009

Вам нужен вспомогательный метод для чтения потока в память. Это работает довольно хорошо:

public static byte[] readFully(InputStream stream) throws IOException
{
    byte[] buffer = new byte[8192];
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    int bytesRead;
    while ((bytesRead = stream.read(buffer)) != -1)
    {
        baos.write(buffer, 0, bytesRead);
    }
    return baos.toByteArray();
}

Тогда вы бы назвали это с:

public static byte[] loadFile(String sourcePath) throws IOException
{
    InputStream inputStream = null;
    try 
    {
        inputStream = new FileInputStream(sourcePath);
        return readFully(inputStream);
    } 
    finally
    {
        if (inputStream != null)
        {
            inputStream.close();
        }
    }
}

Не смешивайте текстовые и двоичные данные - это только приводит к разрывам.

26 голосов
/ 29 октября 2014

Java 7 представила Files.readAllBytes(), которая может читать PDF в byte[] примерно так:

import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;

Path pdfPath = Paths.get("/path/to/file.pdf");
byte[] pdf = Files.readAllBytes(pdfPath);

EDIT:

Спасибо Фаруку за то, что он указал: это будет работать для чтения любого типа файла, не только PDF-файлов. В конечном итоге все файлы представляют собой просто набор байтов и могут быть прочитаны в byte[].

11 голосов
/ 15 июля 2009

Проблема в том, что вы вызываете toString() для самого объекта InputStream. Это вернет String представление InputStream объекта, а не фактического документа PDF.

Вы хотите читать PDF только в байтах, поскольку PDF является двоичным форматом. После этого вы сможете записать тот же массив byte, и он будет действительным PDF, поскольку он не был изменен.

например. читать файл как байты

File file = new File(sourcePath);
InputStream inputStream = new FileInputStream(file); 
byte[] bytes = new byte[file.length()];
inputStream.read(bytes);
5 голосов
/ 10 февраля 2011

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

Используйте org.apache.commons.io.FileUtils.readFileToByteArray(File file), которые возвращают данные типа byte[].

Нажмите здесь для Javadoc

1 голос
/ 26 апреля 2016

Для преобразования PDF в byteArray :

public byte[] pdfToByte(String filePath)throws JRException {

         File file = new File(<filePath>);
         FileInputStream fileInputStream;
         byte[] data = null;
         byte[] finalData = null;
         ByteArrayOutputStream byteArrayOutputStream = null;

         try {
            fileInputStream = new FileInputStream(file);
            data = new byte[(int)file.length()];
            finalData = new byte[(int)file.length()];
            byteArrayOutputStream = new ByteArrayOutputStream();

            fileInputStream.read(data);
            byteArrayOutputStream.write(data);
            finalData = byteArrayOutputStream.toByteArray();

            fileInputStream.close(); 

        } catch (FileNotFoundException e) {
            LOGGER.info("File not found" + e);
        } catch (IOException e) {
            LOGGER.info("IO exception" + e);
        }

        return finalData;

    }
1 голос
/ 16 августа 2015
public static void main(String[] args) throws FileNotFoundException, IOException {
        File file = new File("java.pdf");

        FileInputStream fis = new FileInputStream(file);
        //System.out.println(file.exists() + "!!");
        //InputStream in = resource.openStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        try {
            for (int readNum; (readNum = fis.read(buf)) != -1;) {
                bos.write(buf, 0, readNum); //no doubt here is 0
                //Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
                System.out.println("read " + readNum + " bytes,");
            }
        } catch (IOException ex) {
            Logger.getLogger(genJpeg.class.getName()).log(Level.SEVERE, null, ex);
        }
        byte[] bytes = bos.toByteArray();

        //below is the different part
        File someFile = new File("java2.pdf");
        FileOutputStream fos = new FileOutputStream(someFile);
        fos.write(bytes);
        fos.flush();
        fos.close();
    }
1 голос
/ 15 июля 2009

Разве вы не создаете файл PDF, но на самом деле не записываете байтовый массив обратно? Поэтому вы не можете открыть PDF.

out = new FileOutputStream("D:/ABC_XYZ/1.pdf");
out.Write(b, 0, b.Length);
out.Position = 0;
out.Close();

Это в дополнение к правильному чтению в массиве PDF в байты.

1 голос
/ 15 июля 2009

Вызов toString() на InputStream не делает то, что вы думаете. Даже если это так, PDF-файл содержит двоичные данные, поэтому вам не нужно сначала преобразовывать его в строку.

Что вам нужно сделать, это прочитать из потока, записать результаты в ByteArrayOutputStream, а затем преобразовать ByteArrayOutputStream в фактический byte массив, вызвав toByteArray():

InputStream inputStream = new FileInputStream(sourcePath);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

int data;
while( (data = inputStream.read()) >= 0 ) {
    outputStream.write(data);
}

inputStream.close();
return outputStream.toByteArray();
0 голосов
/ 31 мая 2018

В приложении я тоже реализовал похожее поведение. Ниже приведена моя версия кода, и она работает.

    byte[] getFileInBytes(String filename) {
    File file  = new File(filename);
    int length = (int)file.length();
    byte[] bytes = new byte[length];
    try {
        BufferedInputStream reader = new BufferedInputStream(new 
    FileInputStream(file));
    reader.read(bytes, 0, length);
    System.out.println(reader);
    // setFile(bytes);

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return bytes;
    }
0 голосов
/ 07 марта 2014

Ничто из этого не сработало для нас, возможно, потому что наш inputstream был byte s из вызова rest, а не из локально размещенного pdf файла. Что работало, так это использование RestAssured для чтения PDF как входного потока, а затем использование Tika pdf reader для его анализа и последующего вызова метода toString().

import com.jayway.restassured.RestAssured;
import com.jayway.restassured.response.Response;
import com.jayway.restassured.response.ResponseBody;

import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.BodyContentHandler;
import org.apache.tika.parser.Parser;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

            InputStream stream = response.asInputStream();
            Parser parser = new AutoDetectParser(); // Should auto-detect!
            ContentHandler handler = new BodyContentHandler();
            Metadata metadata = new Metadata();
            ParseContext context = new ParseContext();

            try {
                parser.parse(stream, handler, metadata, context);
            } finally {
                stream.close();
            }
            for (int i = 0; i < metadata.names().length; i++) {
                String item = metadata.names()[i];
                System.out.println(item + " -- " + metadata.get(item));
            }

            System.out.println("!!Printing pdf content: \n" +handler.toString());
            System.out.println("content type: " + metadata.get(Metadata.CONTENT_TYPE));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...