001 /* 002 * Copyright 2008-2009 the original author or authors. 003 * The contents of this file are subject to the Mozilla Public License 004 * Version 1.1 (the "License"); you may not use this file except in 005 * compliance with the License. You may obtain a copy of the License at 006 * http://www.mozilla.org/MPL/ 007 * 008 * Software distributed under the License is distributed on an "AS IS" 009 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 010 * License for the specific language governing rights and limitations 011 * under the License. 012 */ 013 014 package com.mtgi.io; 015 016 import java.io.EOFException; 017 import java.io.File; 018 import java.io.FileInputStream; 019 import java.io.FileOutputStream; 020 import java.io.IOException; 021 import java.io.ObjectInputStream; 022 import java.io.ObjectOutputStream; 023 import java.io.Serializable; 024 025 /** 026 * A custom data transfer class that serializes data from a local file to an ObjectOutputStream, 027 * which is then stored in a temporary file (rather than memory) on read. Useful for returning large 028 * files from RMI methods (e.g. JMX operations). 029 */ 030 public class RelocatableFile implements Serializable { 031 032 private static final long serialVersionUID = 6034331005472005195L; 033 private transient File localPath; 034 035 public RelocatableFile(File localPath) { 036 this.localPath = localPath; 037 } 038 039 /** get the local path where the file data is stored */ 040 public File getLocalFile() { 041 return localPath; 042 } 043 044 /** return the absolute path of the local data file */ 045 @Override 046 public String toString() { 047 return localPath.getAbsolutePath(); 048 } 049 050 private void writeObject(ObjectOutputStream out) 051 throws IOException 052 { 053 out.writeUTF(localPath.getName()); 054 out.writeLong(localPath.length()); 055 056 byte[] xfer = new byte[4096]; 057 FileInputStream fis = new FileInputStream(localPath); 058 try { 059 for (int read = fis.read(xfer); read >= 0; read = fis.read(xfer)) 060 out.write(xfer, 0, read); 061 } finally { 062 fis.close(); 063 } 064 } 065 066 private void readObject(ObjectInputStream in) 067 throws IOException, ClassNotFoundException 068 { 069 String remote = in.readUTF(); 070 String ext = ".data"; 071 int dot = remote.lastIndexOf('.'); 072 if (dot > 0) { 073 ext = remote.substring(dot); 074 remote = remote.substring(0, dot); 075 } 076 localPath = File.createTempFile(remote, ext); 077 078 FileOutputStream fos = new FileOutputStream(localPath); 079 try { 080 long length = in.readLong(); 081 byte[] xfer = new byte[4096]; 082 while (length > 0) { 083 int read = in.read(xfer, 0, (int)Math.min(xfer.length, length)); 084 if (read < 0) 085 throw new EOFException("Unexpected EOF (" + length + " bytes remaining)"); 086 fos.write(xfer, 0, read); 087 length -= read; 088 } 089 } finally { 090 fos.close(); 091 } 092 } 093 }