2009-07-15 43 views
23

Tôi cần chuyển đổi mảng pdf sang byte và ngược lại.Mảng PDF sang byte và ngược lại

Bất kỳ ai có thể giúp tôi không?

Đây là cách tôi đang chuyển sang mảng byte

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

Nếu tôi sử dụng mã sau đây để chuyển đổi nó trở lại tài liệu, pdf được nhận được tạo ra. Nhưng nó nói rằng '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); 
    } 

Trả lời

-2

Các tệp PDF có thể chứa dữ liệu nhị phân và rất có thể là nó bị xáo trộn khi bạn thực hiện. Dường như với tôi rằng bạn muốn điều này:

 FileInputStream inputStream = new FileInputStream(sourcePath); 

     int numberBytes = inputStream .available(); 
     byte bytearray[] = new byte[numberBytes]; 

     inputStream .read(bytearray); 
+0

Đó là một cách khủng khiếp của việc đọc dữ liệu - vui lòng đừng cho rằng có sẵn() sẽ chứa tất cả các dữ liệu trong một suối. –

+1

@Jon - seconded. available() sẽ (thường) trả về số byte có thể đọc ngay lập tức mà không bị chặn. Nó có rất ít để làm với bao nhiêu dữ liệu thực sự trong tập tin .. –

10

Vấn đề là bạn đang gọi toString() trên đối tượng InputStream riêng của mình. Điều này sẽ trả về một biểu thị String của đối tượng InputStream không phải là tài liệu PDF thực tế.

Bạn muốn đọc tệp PDF chỉ dưới dạng byte dưới dạng PDF là định dạng nhị phân. Sau đó bạn sẽ có thể viết ra rằng cùng một mảng byte và nó sẽ là một tệp PDF hợp lệ vì nó chưa được sửa đổi.

ví dụ: để đọc một tập tin như byte

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

Thậm chí điều này chuyển đổi các đối tượng InputStream không phải là PDF thành một mảng Byte – nisha

1

Calling toString() trên một InputStream không làm những gì bạn nghĩ rằng nó. Ngay cả khi nó đã làm, một PDF chứa dữ liệu nhị phân, vì vậy bạn sẽ không muốn chuyển đổi nó thành một chuỗi đầu tiên.

Những gì bạn cần làm là đọc từ stream, viết kết quả vào một ByteArrayOutputStream, sau đó chuyển đổi ByteArrayOutputStream thành một byte mảng thực tế bằng cách gọi 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

Đọc một byte đơn tại một thời điểm không phải là khủng khiếp hiệu quả. Tốt hơn là sao chép một khối tại một thời điểm. –

+0

@Jon - đúng, nhưng tôi đã cố gắng giữ ti đơn giản. Ngoài ra, không FileInputStream làm đệm nội bộ anyways mà sẽ giảm thiểu điều đó? –

27

Bạn về cơ bản cần một phương pháp helper để đọc một luồng vào bộ nhớ. Này hoạt động khá tốt:

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

Sau đó, bạn muốn gọi nó với:

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

Đừng trộn lên văn bản và dữ liệu nhị phân - nó chỉ dẫn đến rơi nước mắt.

+1

Tôi đoán có cần phải có một khung phụ trong readFully trong khi tuyên bố .. như trong khi ((bytesRead = stream.read (buffer))! = -1) – Skeptor

+0

@Skeptor: Xong, cảm ơn. –

1

Bạn không tạo tệp pdf nhưng không thực sự ghi mảng byte trở lại? Do đó bạn không thể mở tệp PDF.

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

Đây là ngoài việc đọc chính xác trong mảng PDF sang byte.

+0

out.position = 0 ?? Tôi dint có được nó –

+0

này có thể không có ích như bạn đang lưu nó vào tập tin nhưng tôi chạy vào các vấn đề mà tôi đã đặt mảng byte vào một đối tượng MemoryStream và tải nó về cho khách hàng. Tôi phải đặt lại vị trí 0 để làm việc này. – David

5

Bạn có thể làm điều đó bằng cách sử dụng Apache Commons IO mà không phải lo lắng về chi tiết nội bộ.

Sử dụng org.apache.commons.io.FileUtils.readFileToByteArray(File file) để trả về dữ liệu loại byte[].

Click here for Javadoc

0

này làm việc cho tôi:

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

Nhưng câu trả lời của Jon không làm việc cho tôi nếu được sử dụng theo cách sau:

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

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

Đầu ra không như chiều dài. Tại sao vậy ?

0

Không có cách nào trong số này phù hợp với chúng tôi, có thể vì chúng tôi inputstreambyte s từ cuộc gọi còn lại chứ không phải từ tệp pdf được lưu trữ cục bộ. Những gì đã làm việc là sử dụng RestAssured để đọc tệp PDF dưới dạng luồng đầu vào và sau đó sử dụng trình đọc pdf Tika để phân tích cú pháp và sau đó gọi phương thức 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)); 
15

Java 7 giới thiệu Files.readAllBytes(), có thể đọc một PDF thành một byte[] như vậy:

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:

Cảm ơn Farooque để chỉ ra: điều này sẽ làm việc để đọc bất kỳ loại tệp, không chỉ các tệp PDF. Tất cả các tập tin cuối cùng chỉ là một loạt các byte, và như vậy có thể được đọc vào một byte[].

+0

Cảm ơn bạn đã chỉnh sửa bản nhập @Farooque! Những gì bạn có nghĩa là bởi "Nói chung nó có thể đọc một tập tin nhất định vào một byte []"? –

+1

Tôi đã thử nghiệm các tệp pdf, jpg, gif, png, txt hoạt động hoàn hảo. Vì nó hỗ trợ tất cả các loại tập tin, nếu ai đó cần tất cả các loại thì "Nói chung nó có thể đọc một tập tin nào đó thành một byte []" thông tin sẽ hữu ích – Farooque

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

Để chuyển đổi 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; 

    } 
Các vấn đề liên quan