public class Storage extends Object implements Closeable
This class handles all aspects of storing and retrieving torrent pieces:
Storage implements Closeable and should be properly closed after use.
The storage must be checked via check() before reading or writing pieces.
Thread safety: This class uses synchronized methods and concurrent collections for thread-safe access to file handles and metadata.
MetaInfo,
BitField,
StorageListener| Modifier and Type | Field and Description |
|---|---|
static int | MAX_PIECE_SIZEMaximum permitted piece size. |
static int | MAX_PIECESThe maximum number of pieces allowed in a single torrent. |
static long | MAX_TOTAL_SIZEMaximum total torrent size (MAX_PIECE_SIZE * MAX_PIECES). |
(package private) static String | PAD_DIRBEP 47 directory holding synthetic padding files; skipped when walking a source dir. |
static int | PRIORITY_NORMALDefault priority value for files. |
static int | PRIORITY_SKIPPriority value indicating a file should be skipped during download. |
| Constructor and Description |
|---|
Storage(I2PSnarkUtil util,
File baseFile,
MetaInfo metainfo,
StorageListener listener,
boolean preserveFileNames)Creates a new storage based on the supplied MetaInfo. |
Storage(I2PSnarkUtil util,
File baseFile,
String announce,
List<List<String>> announce_list,
String created_by,
boolean privateTorrent,
List<String> url_list,
String comment,
StorageListener listener,
List<TorrentCreateFilter> filters)Creates a storage from the existing file or directory. |
Storage(I2PSnarkUtil util,
File baseFile,
String announce,
List<List<String>> announce_list,
String created_by,
boolean privateTorrent,
StorageListener listener,
List<TorrentCreateFilter> filters)Creates a storage from the existing file or directory. |
| Modifier and Type | Method and Description |
|---|---|
void | check()Creates (and/or checks) all files from the metainfo file list. |
void | check(long savedTime,
BitField savedBitField)Creates (and/or checks) all files from the metainfo file list. |
void | cleanRAFs()Close unused RAFs - call periodically |
(package private) void | clearChanged()Clear the storage changed variable |
void | close()Closes the Storage and makes sure that all RandomAccessFiles are closed. |
boolean | complete()Whether or not this storage contains all pieces if the MetaInfo. |
(package private) static int | countNonPad(File[] files)Count the entries in a directory listing for the max files per torrent
check, excluding padding directories. |
void | deleteStagingData()Removes all partially downloaded data from the staging directory for
this torrent. |
static String | filterName(String name)Removes 'suspicious' characters from the given file name. |
long | getActivity()The last activity timestamp. |
File | getBase()The base file or directory. |
String | getBaseName()The base file or directory name of the data, as specified in the .torrent file, but filtered
to remove illegal characters. |
BitField | getBitField()The BitField that tells which pieces this storage contains. |
double | getCheckingProgress()If checking is in progress, return completion 0.0 ... |
SortedSet<File> | getDirectories()Includes the base for a multi-file torrent. |
List<String> | getExcludedFiles(File base)The excluded files. |
int | getFileCount()Does not include directories. |
int[] | getFilePriorities()The file priorities array. |
List<File> | getFiles()Does not include directories. |
boolean | getInOrder()Whether in-order download mode is enabled. |
MetaInfo | getMetaInfo()Returns the MetaInfo associated with this Storage. |
ByteArray | getPiece(int piece,
int off,
int len)Returns a byte array containing a portion of the requested piece or null if the storage
doesn't contain the piece yet. |
int[] | getPiecePriorities()Call setPriority() for all changed files first, then call this. |
boolean | getPreserveFileNames()Whether original file names are being preserved, false if filtered. |
int | getPriority(int fileIndex)The priority of the file at the index. |
long | getSkippedLength()Call setPriority() for all changed files first, then call this. |
(package private) static File | getStagingBase(String tempDir,
String baseName,
MetaInfo metainfo)The staging directory for a torrent: the configured temp dir plus a
subdirectory unique to the torrent. |
File | getStagingDir()The directory this torrent's incomplete files are staged in while
downloading, or null when the staging feature is disabled. |
(package private) static int | getVerifyThreads(I2PAppContext ctx)Worker threads for a parallel piece verification: the i2psnark.verifyThreads property
when set, otherwise scaled to the CPU count (at least 4). |
int | indexOf(File file)Index to pass to remaining(), getPriority(), setPriority() |
boolean | isAllocating()Disk allocation (ballooning) in progress. |
boolean | isChanged()Has the storage changed since instantiation? |
boolean | isChecking()File checking in progress. |
(package private) static boolean | isPadDir(String name)Is this a padding directory (BEP 47 ".pad" or a parse-renamed "_pad")?
Padding entries hold only synthetic zero files: they must not count
toward the max files per torrent limit, nor be included as data when
creating a torrent. |
File[] | listMerged(String pathInTorrent)Lists a directory within the torrent, merging the staging tree while
the download is incomplete, so completed files already moved to the
data directory and files still staged in the temp dir both appear. |
static void | main(String[] args)Create a metainfo. |
int | needed()How many pieces are still missing from this storage. |
(package private) static String | noDataMessage(File base,
List<String> unreadable)The message for a failed torrent creation with no readable data, so a
permission problem is reported as such rather than as an empty folder. |
boolean | putPiece(PartialPiece pp)Put the piece in the Storage if it is correct. |
boolean | recheck()Blocking. |
long[] | remaining()For efficiency, calculate remaining bytes for all files at once |
long[][] | remaining2()For efficiency, calculate remaining bytes for all files at once. |
void | reopen()Doesn't really reopen the file descriptors for a restart. |
void | setActivity(long time)Store the activity timestamp. |
(package private) void | setFilePriorities(int[] p)The file priorities array. |
void | setInOrder(boolean yes)Enable or disable in-order download mode. |
void | setPriority(int fileIndex,
int pri)Must call Snark.updatePiecePriorities() (which calls getPiecePriorities()) after calling
this. |
public static final int MAX_PIECE_SIZE
public static final int MAX_PIECES
public static final long MAX_TOTAL_SIZE
static final String PAD_DIR
public static final int PRIORITY_NORMAL
public static final int PRIORITY_SKIP
public Storage(I2PSnarkUtil util, File baseFile, MetaInfo metainfo, StorageListener listener, boolean preserveFileNames)
Does not check storage. Caller MUST call check(), which will try to create and/or check all needed files in the MetaInfo.
baseFile - the torrent data file or dirpreserveFileNames - if true, do not remap names to a 'safe' charsetpublic Storage(I2PSnarkUtil util, File baseFile, String announce, List<List<String>> announce_list, String created_by, boolean privateTorrent, List<String> url_list, String comment, StorageListener listener, List<TorrentCreateFilter> filters) throws IOException
Creates the metainfo, this may take a LONG time. BLOCKING.
announce - may be nulllistener - may be nullcreated_by - may be nullurl_list - may be nullcomment - may be nullIOException - when creating and/or checking files fails.public Storage(I2PSnarkUtil util, File baseFile, String announce, List<List<String>> announce_list, String created_by, boolean privateTorrent, StorageListener listener, List<TorrentCreateFilter> filters) throws IOException
Creates the metainfo, this may take a LONG time. BLOCKING.
announce - may be nulllistener - may be nullcreated_by - may be nullIOException - when creating and/or checking files fails.public void check()
throws IOExceptionIllegalStateException - if called more than onceIOExceptionpublic void check(long savedTime,
BitField savedBitField)
throws IOExceptionIllegalStateException - if called more than onceIOExceptionpublic void cleanRAFs()
void clearChanged()
public void close()
throws IOExceptionclose in interface Closeableclose in interface AutoCloseableIOExceptionpublic boolean complete()
static int countNonPad(File[] files)
files - directory listing, may be nullpublic void deleteStagingData()
public static String filterName(String name)
This is called frequently and it can be pretty slow so cache the result.
TODO: If multiple files in the same torrent map to the same filter name, the whole torrent will blow up. Check at torrent creation?
public long getActivity()
public File getBase()
public String getBaseName()
public BitField getBitField()
public double getCheckingProgress()
public SortedSet<File> getDirectories()
public List<String> getExcludedFiles(File base)
public int getFileCount()
public int[] getFilePriorities()
public List<File> getFiles()
In staging mode, returns the final data-directory location of each file, even while the data is still being written to the staging dir.
public boolean getInOrder()
public MetaInfo getMetaInfo()
public ByteArray getPiece(int piece, int off, int len) throws IOException
IOExceptionpublic int[] getPiecePriorities()
public boolean getPreserveFileNames()
public int getPriority(int fileIndex)
fileIndex - as obtained from indexOfpublic long getSkippedLength()
static File getStagingBase(String tempDir, String baseName, MetaInfo metainfo)
tempDir - the configured staging directory, or nullbaseName - the torrent's base namemetainfo - the torrentpublic File getStagingDir()
static int getVerifyThreads(I2PAppContext ctx)
public int indexOf(File file)
file - non-canonical path (non-directory)public boolean isAllocating()
public boolean isChanged()
public boolean isChecking()
static boolean isPadDir(String name)
name - directory namepublic File[] listMerged(String pathInTorrent)
pathInTorrent - the directory path within the torrent, "/" or empty for the rootpublic static void main(String[] args)
public int needed()
static String noDataMessage(File base, List<String> unreadable)
base - the data folder or fileunreadable - paths that exist but could not be read, may be emptypublic boolean putPiece(PartialPiece pp) throws IOException
IOException - when some storage related error occurs.public boolean recheck()
throws IOExceptionIOExceptionpublic long[] remaining()
public long[][] remaining2()
public void reopen()
throws IOExceptionIOException - on failpublic void setActivity(long time)
time - timestamp in milliseconds since epochvoid setFilePriorities(int[] p)
p - may be nullpublic void setInOrder(boolean yes)
yes - true to enable in-order mode, false to disablepublic void setPriority(int fileIndex,
int pri)fileIndex - as obtained from indexOfpri - default 0; <0 to disable