[英]PDF to byte array and vice versa
我需要將 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'
'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);
}
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);
編輯:
感謝 Farooque 指出:這適用於閱讀任何類型的文件,而不僅僅是 PDF。 所有文件最終都只是一堆字節,因此可以讀入byte[]
。
您基本上需要一個輔助方法來將流讀入內存。 這很好用:
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();
}
}
}
不要混淆文本和二進制數據 - 它只會導致流淚。
問題是您在InputStream
對象本身上調用toString()
。 這將返回InputStream
對象的String
表示,而不是實際的 PDF 文檔。
您只想將 PDF 作為字節讀取,因為 PDF 是二進制格式。 然后,您將能夠寫出相同的byte
數組,它將是一個有效的 PDF,因為它沒有被修改。
例如以字節形式讀取文件
File file = new File(sourcePath);
InputStream inputStream = new FileInputStream(file);
byte[] bytes = new byte[file.length()];
inputStream.read(bytes);
您可以通過使用Apache Commons IO
而無需擔心內部細節。
使用org.apache.commons.io.FileUtils.readFileToByteArray(File file)
返回byte[]
類型的數據。
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();
}
這對我有用。 我沒有使用任何第三方庫。 只是 Java 附帶的那些。
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class PDFUtility {
public static void main(String[] args) throws IOException {
/**
* Converts byte stream into PDF.
*/
PDFUtility pdfUtility = new PDFUtility();
byte[] byteStreamPDF = pdfUtility.convertPDFtoByteStream();
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\aseem\\Desktop\\BlaFolder\\BlaFolder2\\aseempdf.pdf");
fileOutputStream.write(byteStreamPDF);
fileOutputStream.close();
System.out.println("File written successfully");
}
/**
* Creates PDF to Byte Stream
*
* @return
* @throws IOException
*/
protected byte[] convertPDFtoByteStream() throws IOException {
Path path = Paths.get("C:\\Users\\aseem\\aaa.pdf");
return Files.readAllBytes(path);
}
}
在InputStream
上調用toString()
不會做您認為的那樣。 即使是這樣,PDF 也包含二進制數據,因此您不希望先將其轉換為字符串。
您需要做的是從流中讀取,將結果寫入ByteArrayOutputStream
,然后通過調用toByteArray()
將ByteArrayOutputStream
轉換為實際的byte
數組:
InputStream inputStream = new FileInputStream(sourcePath);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int data;
while( (data = inputStream.read()) >= 0 ) {
outputStream.write(data);
}
inputStream.close();
return outputStream.toByteArray();
你不是在創建 pdf 文件但實際上沒有寫回字節數組嗎? 因此您無法打開 PDF。
out = new FileOutputStream("D:/ABC_XYZ/1.pdf");
out.Write(b, 0, b.Length);
out.Position = 0;
out.Close();
這是正確讀取 PDF 到字節數組的補充。
將 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;
}
這對我有用:
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);
}
輸出零作為長度。 這是為什么 ?
這些都不適合我們,可能是因為我們的輸入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));
我也沒有失敗地在我的應用程序中實現了類似的行為。 下面是我的代碼版本,它是功能性的。
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;
}
public String encodeFileToBase64Binary(String fileName)
throws IOException {
System.out.println("encodeFileToBase64Binary: "+ fileName);
File file = new File(fileName);
byte[] bytes = loadFile(file);
byte[] encoded = Base64.encodeBase64(bytes);
String encodedString = new String(encoded);
System.out.println("ARCHIVO B64: "+encodedString);
return encodedString;
}
@SuppressWarnings("resource")
public static byte[] loadFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
long length = file.length();
if (length > Integer.MAX_VALUE) {
// File is too large
}
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
is.close();
return bytes;
}
PDF 可能包含二進制數據,並且在您執行 ToString 時它可能會被破壞。 在我看來,你想要這個:
FileInputStream inputStream = new FileInputStream(sourcePath);
int numberBytes = inputStream .available();
byte bytearray[] = new byte[numberBytes];
inputStream .read(bytearray);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.