/** * Copyright 2011 Intuit Inc. All Rights Reserved */ package com.intuit.tank.service.impl.v1.report; /* * #%L * Reporting Rest Service Implementation * %% * Copyright (C) 2011 - 2015 Intuit Inc. * %% * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * #L% */ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.WritableByteChannel; import java.util.Collections; import java.util.List; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * FileServiceV1 * * @author dangleton * */ public final class FileReader { private FileReader() { // empty private constructor } private static final Logger LOG = LogManager.getLogger(FileReader.class); /** * Gets a StreamingOutput from the passedin file from start to end or from beginning to end if start is greater than * end. if a negative number is passed, it will get the last n lines of the file. If 0 is passed it will return the * entire file. * * @param total * * @return a StreamingOutput */ public static StreamingOutput getFileStreamingOutput(final File f, long total, String start) { long l = 0; if (start != null) { try { l = Long.parseLong(start); // num lines to get from end if (l < 0) { l = getStartChar(f, Math.abs(l), total); } } catch (Exception e) { LOG.error("Error parsing start " + start + ": " + e); } } final long to = l > total ? 0 : total; final long from = l; StreamingOutput streamer = new StreamingOutput() { @SuppressWarnings("resource") @Override public void write(final OutputStream output) throws IOException, WebApplicationException { final FileChannel inputChannel = new FileInputStream(f).getChannel(); final WritableByteChannel outputChannel = Channels.newChannel(output); try { inputChannel.transferTo(from, to, outputChannel); } finally { // closing the channels inputChannel.close(); outputChannel.close(); } } }; LOG.debug("returning data from " + from + " - " + to + " of total " + total); return streamer; } /** * @param f * @param l * @return * @throws IOException */ @SuppressWarnings({ "unchecked" }) private static long getStartChar(File f, long numLines, long total) throws IOException { List<String> lines = FileUtils.readLines(f); long count = 0; if (lines.size() > numLines) { Collections.reverse(lines); for (int i = 0; i < numLines; i++) { count += lines.get(i).length() + 1; } count = total - (count + 1); } return count; } }