PDF в байтовый массив и наоборот
Мне нужно преобразовать 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);
}
Ответы
Ответ 1
В основном вам нужен вспомогательный метод для чтения потока в память. Это работает очень хорошо:
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();
}
}
}
Не смешивайте текстовые и двоичные данные - это только приводит к слезам.
Ответ 2
В 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:
Спасибо Farooque за указание: это будет работать для чтения любого файла, а не только PDF файлов. Все файлы в конечном счете представляют собой просто пучок байтов и, как таковой, можно читать в byte[]
.
Ответ 3
Проблема заключается в том, что вы вызываете 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);
Ответ 4
Вы можете сделать это, используя Apache Commons IO
, не беспокоясь о внутренних деталях.
Используйте org.apache.commons.io.FileUtils.readFileToByteArray(File file)
, которые возвращают данные типа byte[]
.
Нажмите здесь для Javadoc
Ответ 5
Вызов 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();
Ответ 6
Не создаете ли вы файл pdf, но на самом деле не записываете массив байтов? Поэтому вы не можете открыть PDF файл.
out = new FileOutputStream("D:/ABC_XYZ/1.pdf");
out.Write(b, 0, b.Length);
out.Position = 0;
out.Close();
Это дополнение к правильному чтению в массиве PDF в байтах.
Ответ 7
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();
}
Ответ 8
Это работает для меня:
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);
}
}
Но ответ Джона не работает для меня, если используется следующим образом:
try(InputStream pdfin = new FileInputStream("input.pdf");OutputStream pdfout = new FileOutputStream("output.pdf")){
int k = readFully(pdfin).length;
System.out.println(k);
}
Выводит ноль как длину. Почему это?
Ответ 9
Ни один из них не сработал для нас, возможно, потому что наш inputstream
был byte
от вызова для отдыха, а не из локально размещенного 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));
Ответ 10
Чтобы преобразовать 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;
}
Ответ 11
PDF файлы могут содержать двоичные данные и, скорее всего, они становятся искалеченными, когда вы делаете ToString.
Мне кажется, что вы этого хотите:
FileInputStream inputStream = new FileInputStream(sourcePath);
int numberBytes = inputStream .available();
byte bytearray[] = new byte[numberBytes];
inputStream .read(bytearray);