简体   繁体   中英

How to read binary data which is in bytea-format from postgres-db in java (or groovy) and save as jpeg-file?

We have a postgres-DB-dump where all kinds of files (png, jpg, pdf etc..) are stored as binary data in bytea format. We'd have to read them out and store them as a file (eg .jpg) on the server using grooy or java.

The problem is at the moment that the files, whichare are created, are corrupted (altough the same code worked in an earlier db-dump on another server). No valid files are created.

data in db-column with sql-query looks like this: \x1f8b0800000000000000ed5adb6edb38107ddfaf10f45a14be245d20852320698316089214a9fb2c50d2d8264c912e49b5f57ecffec9fed892badf68c9 ... 2048 bytes per row. some files spread over multiple rows..

//Get data from DB: binary data, mime_type, file_ID
    GroovyRowResult[] data = sql.rows("""
      SELECT lo.loid loid, lo.pageno pageno, lo.data d, nb.hash  hash, nb.size size, nb.mime_type mime_type,
      nb.data nb_loid, nb.file_extension ext FROM <tablename containing binary data> lo
      LEFT JOIN <tablename helptable metainfo> nb ON lo.loid = nb.data
      WHERE lo.loid = $loid
      """)

    def fileId = data[0].loid.toString()
    def mimeType = data[0].mime_type.toString()
    def temp = []

    //read out binary data into a byte array
    data.each { GroovyRowResult row ->
      temp << row.d
    }
    //read the byte array into an input stream
    InputStream inputStream = new ByteArrayInputStream((byte[]) temp.flatten(), 0, temp.flatten().size())

    def systemSettings = SystemSettings.getInstance(application)

    def newFileId = FileInBinaryFormat.detectTypeAndSave(<folderID on Server>, application.getRealPath(systemSettings.getDocumentPath()), fileId, mimeType, inputStream)

which calls the following method, after having identified the mime-type from metainformation in db: FileEntry represents an uploaded document on our server.

  static String saveAsImage(InputStream inputStream, String fileName, Folder folder, String path, Connection conn, String fileExtension) {

    BufferedImage bufferedImage = null
    try {
      bufferedImage = ImageIO.read(inputStream)
   } catch (IOException e){
      ...
    }

    try{ 
      def newFile = new File(path,"${UniqueID.createHexId()}"+fileExtension)
      ImageIO.write(bufferedImage, fileExtension, newFile)
        def fileEntry = FileEntry.createNewEntry(newFile, conn, folder, Customer.getCustomer(<CustomerNumber>),
        "", fileName + fileExtension)
      return fileEntry.id   
    } catch (IOException e) {
      ...
    } 
  }

Does anybody see some obvious mistakes causing the Problem or can help me in any way? Many thanks in Advance!

EDIT: Some more information:

When one logs "newFile", it shows a path to a file. However there is no file found on the server in the directory. so no file is created.

The log of the buffered image looks like this:

[Date:Time] BufferedImage@57c0c3cb: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@6bcd3bb4 transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 277 height = 368 #numDataElements 3 dataOff[0] = 2

The byte array is an array in the form: [-1, 125, 5, 6, ..., ] (signed 2 complement of hex values in DB column). So this seems to work.

I added "Order BY pageno" in the query in order to make sure the ordering of the rows is correct.

I found the solution. The Problem was in the ImageIO.write(bufferedImage, fileExtension, newFile) secion. the variable 'fileExtension' included a dot: ".jpeg", ".png" etc. It need to be without a dot. So after changeing that and changeing the row above to: def newFile = new File(path,UniqueID.createHexId()+"."+fileExtension) did the job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM