web-dev-qa-db-fra.com

PDF à tableau d'octets et vice versa

J'ai besoin de convertir pdf en tableau d'octets et vice versa.

Quelqu'un peut-il m'aider?

Voici comment je convertis en tableau d'octets

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;
}

Si j'utilise le code suivant pour le reconvertir en document, le format pdf est créé. Mais cela dit '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);
    }
24
abhishek

Vous avez essentiellement besoin d'une méthode d'assistance pour lire un flux en mémoire. Cela fonctionne plutôt bien:

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();
}

Ensuite, vous l'appelez avec:

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();
        }
    }
}

Ne pas mélanger du texte et des données binaires - cela ne fait que déchirer.

30
Jon Skeet

Java 7 a introduit Files.readAllBytes(), qui peut lire un PDF dans un byte[] comme ceci:

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);

MODIFIER:

Merci Farooque de nous l'avoir signalé: cela fonctionnera pour la lecture de tout type de fichier, pas seulement des PDF. Tous les fichiers ne sont finalement qu’un tas d’octets et peuvent donc être lus dans un byte[].

23
Chris Clark

Le problème est que vous appelez toString() sur l'objet InputStream lui-même. Cela renverra une représentation String de l'objet InputStream et non le document PDF réel.

Vous voulez lire le PDF uniquement sous forme d'octets, car PDF est un format binaire. Vous pourrez alors écrire ce même tableau byte et ce sera un PDF valide car il n'a pas été modifié.

par exemple. lire un fichier sous forme d'octets

File file = new File(sourcePath);
InputStream inputStream = new FileInputStream(file); 
byte[] bytes = new byte[file.length()];
inputStream.read(bytes);
11
Mark

Vous pouvez le faire en utilisant Apache Commons IO sans vous soucier des détails internes.

Utilisez org.Apache.commons.io.FileUtils.readFileToByteArray(File file) qui renvoie des données de type byte[].

Cliquez ici pour Javadoc

5
Narendra

Convertir un fichier pdf en 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
Riddhi Gohil
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
Sami Youssef

L'appel de toString() sur une InputStream ne fait pas ce que vous pensez qu'il fait. Même si c'était le cas, un PDF contient des données binaires, vous ne voudriez donc pas le convertir en chaîne auparavant.

Ce que vous devez faire, c'est lire dans le flux, écrire les résultats dans un ByteArrayOutputStream, puis convertir le ByteArrayOutputStream dans un tableau byte réel en appelant 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();
1
Eric Petroelje

Ne créez-vous pas le fichier pdf mais n'écrivez-vous pas réellement le tableau d'octets? Par conséquent, vous ne pouvez pas ouvrir le PDF. 

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

Cela s'ajoute à la lecture correcte du tableau PDF en octets.

1
David

Cela fonctionne pour moi:

try(InputStream pdfin = new FileInputStream("input.pdf");OutputStream pdfout = new FileOutputStream("output.pdf")){
    byte[] buffer = new byte[1024];
    int bytesRead;
    while((bytesRead = pdfin.read(buffer))!=-1){
        pdfout.write(buffer,0,bytesRead);
    }
}

Mais la réponse de Jon ne fonctionne pas pour moi si elle est utilisée de la manière suivante:

try(InputStream pdfin = new FileInputStream("input.pdf");OutputStream pdfout = new FileOutputStream("output.pdf")){

    int k = readFully(pdfin).length;
    System.out.println(k);
}

Affiche zéro comme longueur. Pourquoi donc ? 

0
Sridhar

Aucune de ces méthodes ne fonctionnait pour nous, peut-être parce que notre inputstream était bytes à partir d'un appel de repos et non à partir d'un fichier pdf hébergé localement. Ce qui a fonctionné a été d'utiliser RestAssured pour lire le PDF en tant que flux d'entrée, puis d'utiliser le lecteur de PDF Tika pour l'analyser, puis d'appeler la méthode 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));
0
gorbysbm

J'ai également implémenté un comportement similaire dans mon application. Ci-dessous ma version de code et il est fonctionnel.

    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
Akash Roy