blobfilevalue.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 549 行 · 第 1/2 页
JAVA
549 行
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.value;import org.apache.jackrabbit.core.fs.FileSystemException;import org.apache.jackrabbit.core.fs.FileSystemResource;import org.apache.jackrabbit.util.ISO8601;import org.apache.jackrabbit.util.TransientFileFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.PropertyType;import javax.jcr.RepositoryException;import javax.jcr.Value;import javax.jcr.ValueFormatException;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.util.Arrays;import java.util.Calendar;/** * <code>BLOBFileValue</code> represents a binary <code>Value</code> which is * backed by a resource or byte[]. Unlike <code>BinaryValue</code> it has no * state, i.e. the <code>getStream()</code> method always returns a fresh * <code>InputStream</code> instance. * <p/> * <b>Important Note:</b><p/> * This is class is for Jackrabbit-internal use only. Applications should * use <code>javax.jcr.ValueFactory</code> to create binary values. */public class BLOBFileValue implements Value { /** * The default logger */ private static Logger log = LoggerFactory.getLogger(BLOBFileValue.class); /** * the property type */ public static final int TYPE = PropertyType.BINARY; /** * the default encoding */ protected static final String DEFAULT_ENCODING = "UTF-8"; /** * empty array */ private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; /** * max size for keeping tmp data in memory */ private static final int MAX_BUFFER_SIZE = 0x10000; /** * underlying file */ private final File file; /** * flag indicating if this instance represents a <i>temporary</i> value * whose dynamically allocated resources can be explicitly freed on * {@link #discard()}. */ private final boolean temp; /** * buffer for small-sized data */ private byte[] buffer = EMPTY_BYTE_ARRAY; /** * underlying file system resource */ private final FileSystemResource fsResource; /** * converted text */ private String text = null; /** * Creates a new <code>BLOBFileValue</code> instance from an * <code>InputStream</code>. The contents of the stream is spooled * to a temporary file or to a byte buffer if its size is smaller than * {@link #MAX_BUFFER_SIZE}. * <p/> * The new instance represents a <i>temporary</i> value whose dynamically * allocated resources will be freed explicitly on {@link #discard()}. * * @param in stream to be represented as a <code>BLOBFileValue</code> instance * @throws IOException if an error occurs while reading from the stream or * writing to the temporary file */ public BLOBFileValue(InputStream in) throws IOException { this(in, true); } /** * Creates a new <code>BLOBFileValue</code> instance from an * <code>InputStream</code>. The contents of the stream is spooled * to a temporary file or to a byte buffer if its size is smaller than * {@link #MAX_BUFFER_SIZE}. * <p/> * The <code>temp</code> parameter governs whether dynamically allocated * resources will be freed explicitly on {@link #discard()}. Note that any * dynamically allocated resources (temp file/buffer) will be freed * implicitly once this instance has been gc'ed. * * @param in stream to be represented as a <code>BLOBFileValue</code> instance * @param temp flag indicating whether this instance represents a * <i>temporary</i> value whose resources can be explicitly freed * on {@link #discard()}. * @throws IOException if an error occurs while reading from the stream or * writing to the temporary file */ public BLOBFileValue(InputStream in, boolean temp) throws IOException { byte[] spoolBuffer = new byte[0x2000]; int read; int len = 0; OutputStream out = null; File spoolFile = null; try { while ((read = in.read(spoolBuffer)) > 0) { if (out != null) { // spool to temp file out.write(spoolBuffer, 0, read); len += read; } else if (len + read > MAX_BUFFER_SIZE) { // threshold for keeping data in memory exceeded; // create temp file and spool buffer contents TransientFileFactory fileFactory = TransientFileFactory.getInstance(); spoolFile = fileFactory.createTransientFile("bin", null, null); out = new FileOutputStream(spoolFile); out.write(buffer, 0, len); out.write(spoolBuffer, 0, read); buffer = null; len += read; } else { // reallocate new buffer and spool old buffer contents byte[] newBuffer = new byte[len + read]; System.arraycopy(buffer, 0, newBuffer, 0, len); System.arraycopy(spoolBuffer, 0, newBuffer, len, read); buffer = newBuffer; len += read; } } } finally { if (out != null) { out.close(); } } // init vars file = spoolFile; fsResource = null; this.temp = temp; } /** * Creates a new <code>BLOBFileValue</code> instance from a * <code>byte[]</code> array. * * @param bytes byte array to be represented as a <code>BLOBFileValue</code> * instance */ public BLOBFileValue(byte[] bytes) { buffer = bytes; file = null; fsResource = null; // this instance is not backed by a temporarily allocated buffer temp = false; } /** * Creates a new <code>BLOBFileValue</code> instance from a <code>File</code>. * * @param file file to be represented as a <code>BLOBFileValue</code> instance * @throws IOException if the file can not be read */ public BLOBFileValue(File file) throws IOException { String path = file.getCanonicalPath(); if (!file.isFile()) { throw new IOException(path + ": the specified file does not exist"); } if (!file.canRead()) { throw new IOException(path + ": the specified file can not be read"); } this.file = file; // this instance is backed by a 'real' file; set virtual fs resource to null fsResource = null; // this instance is not backed by temporarily allocated resource/buffer temp = false; } /** * Creates a new <code>BLOBFileValue</code> instance from a resource in the * virtual file system. * * @param fsResource resource in virtual file system * @throws IOException if the resource can not be read */ public BLOBFileValue(FileSystemResource fsResource) throws IOException { try { if (!fsResource.exists()) { throw new IOException(fsResource.getPath() + ": the specified resource does not exist"); } } catch (FileSystemException fse) { throw new IOException(fsResource.getPath() + ": Error while creating value: " + fse.toString()); } // this instance is backed by a resource in the virtual file system this.fsResource = fsResource; // set 'real' file to null file = null; // this instance is not backed by temporarily allocated resource/buffer temp = false; } /** * Returns the length of this <code>BLOBFileValue</code>. * * @return The length, in bytes, of this <code>BLOBFileValue</code>, * or -1L if the length can't be determined. */ public long getLength() { if (file != null) { // this instance is backed by a 'real' file if (file.exists()) { return file.length(); } else { return -1; } } else if (fsResource != null) { // this instance is backed by a resource in the virtual file system try { return fsResource.length(); } catch (FileSystemException fse) { return -1; } } else { // this instance is backed by an in-memory buffer return buffer.length; } } /** * Frees temporarily allocated resources such as temporary file, buffer, etc. * If this <code>BLOBFileValue</code> is backed by a persistent resource
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?