/********************************************************************** * This file is part of iDempiere ERP Open Source * * http://www.idempiere.org * * * * Copyright (C) Contributors * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * * MA 02110-1301, USA. * * * * Contributors: * * - Trek Global Corporation * * - Heng Sin Low * **********************************************************************/ package com.trekglobal.idempiere.rest.api.v1.resource.file; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.RandomAccessFile; import java.io.Serializable; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.concurrent.Callable; import java.util.logging.Level; import org.compiere.util.CLogger; import org.compiere.util.Util; /** * @author hengsin * */ public class ReadFileCallable implements Callable, Serializable { /** * generated serial id */ private static final long serialVersionUID = -1423690018599866128L; private String parentFolderName; private String fileName; private int blockSize; private int blockNo; private static final CLogger log = CLogger.getCLogger(ReadFileCallable.class); /** * * @param parentFolderName * @param fileName * @param blockSize size of each block. 0 to load all as one block * @param blockNo 0 base block index */ public ReadFileCallable(String parentFolderName, String fileName, int blockSize, int blockNo) { this.parentFolderName = parentFolderName; this.fileName = fileName; this.blockSize = blockSize; this.blockNo = blockNo; } @Override public byte[] call() throws Exception { File parentFolder = null; if ("java.io.tmpdir".equals(parentFolderName)) parentFolder = new File(System.getProperty("java.io.tmpdir")); else if (!Util.isEmpty(parentFolderName, true)) parentFolder = new File(parentFolderName); File file = parentFolder != null ? new File(parentFolder, fileName) : new File(fileName); if (file.length() == 0) { return new byte[0]; } try(RandomAccessFile raf = new RandomAccessFile(file, "r"); FileChannel channel = raf.getChannel();) { if (blockNo > 0 && blockSize > 0) { channel.position(blockNo * blockSize); } ByteBuffer buffer = ByteBuffer.allocate(1024); ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); int bytesRead = 0; int totalRead = 0; while((bytesRead = channel.read(buffer)) > 0) { totalRead += bytesRead; if (blockSize > 0 && totalRead > blockSize) { int diff = totalRead - blockSize; bytesRead = bytesRead - diff; totalRead = blockSize; } baos.write(buffer.array(), 0, bytesRead); buffer.clear(); if (totalRead == blockSize) break; } return baos.toByteArray(); } catch (Exception ex) { log.log(Level.SEVERE, "stream" + ex); return null; } } }