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);
}
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.
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[]
.
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);
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[]
.
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;
}
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();
}
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();
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.
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 ?
Aucune de ces méthodes ne fonctionnait pour nous, peut-être parce que notre inputstream
était byte
s à 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));
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;
}