Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ab2f646c
提交
ab2f646c
authored
9月 16, 2011
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improved compatibility with the Java 7 FileSystem abstraction.
上级
6e710caa
隐藏空白字符变更
内嵌
并排
正在显示
33 个修改的文件
包含
3336 行增加
和
122 行删除
+3336
-122
Database.java
h2/src/main/org/h2/engine/Database.java
+2
-3
TraceSystem.java
h2/src/main/org/h2/message/TraceSystem.java
+1
-1
FileObjectDiskMapped.java
h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java
+21
-10
FileObjectRec.java
h2/src/main/org/h2/store/fs/FileObjectRec.java
+73
-0
FilePath.java
h2/src/main/org/h2/store/fs/FilePath.java
+317
-0
FilePathDisk.java
h2/src/main/org/h2/store/fs/FilePathDisk.java
+397
-0
FilePathMem.java
h2/src/main/org/h2/store/fs/FilePathMem.java
+205
-0
FilePathNio.java
h2/src/main/org/h2/store/fs/FilePathNio.java
+38
-0
FilePathNioMapped.java
h2/src/main/org/h2/store/fs/FilePathNioMapped.java
+30
-0
FilePathRec.java
h2/src/main/org/h2/store/fs/FilePathRec.java
+110
-0
FilePathSplit.java
h2/src/main/org/h2/store/fs/FilePathSplit.java
+233
-0
FilePathWrapper.java
h2/src/main/org/h2/store/fs/FilePathWrapper.java
+139
-0
FilePathZip.java
h2/src/main/org/h2/store/fs/FilePathZip.java
+247
-0
FileSystem.java
h2/src/main/org/h2/store/fs/FileSystem.java
+0
-8
FileSystemDisk.java
h2/src/main/org/h2/store/fs/FileSystemDisk.java
+1
-7
FileSystemMemory.java
h2/src/main/org/h2/store/fs/FileSystemMemory.java
+4
-8
FileSystemWrapper.java
h2/src/main/org/h2/store/fs/FileSystemWrapper.java
+2
-6
FileSystemZip.java
h2/src/main/org/h2/store/fs/FileSystemZip.java
+2
-6
FileUtils.java
h2/src/main/org/h2/store/fs/FileUtils.java
+18
-18
FileUtils2.java
h2/src/main/org/h2/store/fs/FileUtils2.java
+343
-0
IOUtils.java
h2/src/main/org/h2/util/IOUtils.java
+0
-27
SourceCompiler.java
h2/src/main/org/h2/util/SourceCompiler.java
+1
-5
TestLinkedTable.java
h2/src/test/org/h2/test/db/TestLinkedTable.java
+1
-1
TestLob.java
h2/src/test/org/h2/test/db/TestLob.java
+1
-1
FileSystemDatabase.java
h2/src/test/org/h2/test/unit/FileSystemDatabase.java
+2
-6
TestFilePath.java
h2/src/test/org/h2/test/unit/TestFilePath.java
+421
-0
DebugFile.java
h2/src/test/org/h2/test/utils/DebugFile.java
+96
-0
DebugFilePath.java
h2/src/test/org/h2/test/utils/DebugFilePath.java
+218
-0
DebugFileSystem.java
h2/src/test/org/h2/test/utils/DebugFileSystem.java
+3
-8
FilePathCrypt.java
h2/src/tools/org/h2/dev/fs/FilePathCrypt.java
+98
-0
FilePathZip2.java
h2/src/tools/org/h2/dev/fs/FilePathZip2.java
+309
-0
FileShell.java
h2/src/tools/org/h2/dev/fs/FileShell.java
+1
-1
FileSystemZip2.java
h2/src/tools/org/h2/dev/fs/FileSystemZip2.java
+2
-6
没有找到文件。
h2/src/main/org/h2/engine/Database.java
浏览文件 @
ab2f646c
...
@@ -506,9 +506,8 @@ public class Database implements DataHandler {
...
@@ -506,9 +506,8 @@ public class Database implements DataHandler {
throw
DbException
.
get
(
ErrorCode
.
FILE_VERSION_ERROR_1
,
throw
DbException
.
get
(
ErrorCode
.
FILE_VERSION_ERROR_1
,
"Old database: "
+
dataFileName
+
" - please convert the database to a SQL script and re-create it."
);
"Old database: "
+
dataFileName
+
" - please convert the database to a SQL script and re-create it."
);
}
}
if
(
existsPage
&&
FileUtils
.
isReadOnly
(
pageFileName
))
{
if
(
existsPage
&&
!
FileUtils
.
canWrite
(
pageFileName
))
{
// if it is already read-only because ACCESS_MODE_DATA=r
readOnly
=
true
;
readOnly
=
readOnly
|
FileUtils
.
isReadOnly
(
pageFileName
);
}
}
if
(
readOnly
)
{
if
(
readOnly
)
{
traceSystem
=
new
TraceSystem
(
null
);
traceSystem
=
new
TraceSystem
(
null
);
...
...
h2/src/main/org/h2/message/TraceSystem.java
浏览文件 @
ab2f646c
...
@@ -296,7 +296,7 @@ public class TraceSystem implements TraceWriter {
...
@@ -296,7 +296,7 @@ public class TraceSystem implements TraceWriter {
if
(
printWriter
==
null
)
{
if
(
printWriter
==
null
)
{
try
{
try
{
FileUtils
.
createDirectories
(
FileUtils
.
getParent
(
fileName
));
FileUtils
.
createDirectories
(
FileUtils
.
getParent
(
fileName
));
if
(
FileUtils
.
exists
(
fileName
)
&&
FileUtils
.
isReadOnly
(
fileName
))
{
if
(
FileUtils
.
exists
(
fileName
)
&&
!
FileUtils
.
canWrite
(
fileName
))
{
// read only database: don't log error if the trace file
// read only database: don't log error if the trace file
// can't be opened
// can't be opened
return
false
;
return
false
;
...
...
h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java
浏览文件 @
ab2f646c
...
@@ -132,6 +132,10 @@ public class FileObjectDiskMapped implements FileObject {
...
@@ -132,6 +132,10 @@ public class FileObjectDiskMapped implements FileObject {
return
pos
;
return
pos
;
}
}
public
String
toString
()
{
return
FileSystemDiskNioMapped
.
PREFIX
+
name
;
}
public
synchronized
long
size
()
throws
IOException
{
public
synchronized
long
size
()
throws
IOException
{
return
file
.
length
();
return
file
.
length
();
}
}
...
@@ -161,9 +165,24 @@ public class FileObjectDiskMapped implements FileObject {
...
@@ -161,9 +165,24 @@ public class FileObjectDiskMapped implements FileObject {
if
(
newLength
>=
size
())
{
if
(
newLength
>=
size
())
{
return
;
return
;
}
}
setFileLength
(
newLength
);
}
public
synchronized
void
setFileLength
(
long
newLength
)
throws
IOException
{
checkFileSizeLimit
(
newLength
);
int
oldPos
=
pos
;
int
oldPos
=
pos
;
unMap
();
unMap
();
file
.
setLength
(
newLength
);
for
(
int
i
=
0
;;
i
++)
{
try
{
file
.
setLength
(
newLength
);
break
;
}
catch
(
IOException
e
)
{
if
(
i
>
16
||
e
.
toString
().
indexOf
(
"user-mapped section open"
)
<
0
)
{
throw
e
;
}
}
System
.
gc
();
}
reMap
();
reMap
();
pos
=
(
int
)
Math
.
min
(
newLength
,
oldPos
);
pos
=
(
int
)
Math
.
min
(
newLength
,
oldPos
);
}
}
...
@@ -176,11 +195,7 @@ public class FileObjectDiskMapped implements FileObject {
...
@@ -176,11 +195,7 @@ public class FileObjectDiskMapped implements FileObject {
public
synchronized
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
public
synchronized
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
// check if need to expand file
// check if need to expand file
if
(
mapped
.
capacity
()
<
pos
+
len
)
{
if
(
mapped
.
capacity
()
<
pos
+
len
)
{
int
oldPos
=
pos
;
setFileLength
(
pos
+
len
);
unMap
();
file
.
setLength
(
pos
+
len
);
reMap
();
pos
=
oldPos
;
}
}
mapped
.
position
(
pos
);
mapped
.
position
(
pos
);
mapped
.
put
(
b
,
off
,
len
);
mapped
.
put
(
b
,
off
,
len
);
...
@@ -210,8 +225,4 @@ public class FileObjectDiskMapped implements FileObject {
...
@@ -210,8 +225,4 @@ public class FileObjectDiskMapped implements FileObject {
}
}
}
}
public
String
toString
()
{
return
name
;
}
}
}
h2/src/main/org/h2/store/fs/FileObjectRec.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
/**
* A file object that records all write operations and can re-play them.
*/
public
class
FileObjectRec
implements
FileObject
{
private
final
FilePathRec
fs
;
private
final
FileObject
file
;
private
final
String
name
;
FileObjectRec
(
FilePathRec
fs
,
FileObject
file
,
String
fileName
)
{
this
.
fs
=
fs
;
this
.
file
=
file
;
this
.
name
=
fileName
;
}
public
void
close
()
throws
IOException
{
file
.
close
();
}
public
long
position
()
throws
IOException
{
return
file
.
position
();
}
public
long
size
()
throws
IOException
{
return
file
.
size
();
}
public
void
readFully
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
file
.
readFully
(
b
,
off
,
len
);
}
public
void
position
(
long
pos
)
throws
IOException
{
file
.
position
(
pos
);
}
public
void
truncate
(
long
newLength
)
throws
IOException
{
fs
.
log
(
Recorder
.
TRUNCATE
,
name
,
null
,
newLength
);
file
.
truncate
(
newLength
);
}
public
void
sync
()
throws
IOException
{
file
.
sync
();
}
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
byte
[]
buff
=
b
;
if
(
off
!=
0
||
len
!=
b
.
length
)
{
buff
=
new
byte
[
len
];
System
.
arraycopy
(
b
,
off
,
buff
,
0
,
len
);
}
file
.
write
(
b
,
off
,
len
);
fs
.
log
(
Recorder
.
WRITE
,
name
,
buff
,
file
.
position
());
}
public
boolean
tryLock
()
{
return
file
.
tryLock
();
}
public
void
releaseLock
()
{
file
.
releaseLock
();
}
}
\ No newline at end of file
h2/src/main/org/h2/store/fs/FilePath.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
org.h2.util.MathUtils
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
/**
* A path to a file. It similar to the Java 7 <code>java.nio.file.Path</code>,
* but simpler, and works with older versions of Java. It also implements the
* relevant methods found in <code>java.nio.file.FileSystem</code> and
* <code>FileSystems</code>
*/
public
abstract
class
FilePath
{
private
static
final
FilePath
DEFAULT
=
new
FilePathDisk
();
private
static
Map
<
String
,
FilePath
>
providers
;
/**
* The prefix for temporary files. See also TestClearReferences.
*/
private
static
String
tempRandom
;
private
static
long
tempSequence
;
protected
String
name
;
/**
* Get the file path object for the given path.
*
* @param path the path
* @return the file path object
*/
public
static
FilePath
get
(
String
path
)
{
int
index
=
path
.
indexOf
(
':'
);
if
(
index
<
2
)
{
// use the default provider if no prefix or
// only a single character (drive name)
return
DEFAULT
.
getPath
(
path
);
}
String
scheme
=
path
.
substring
(
0
,
index
);
registerDefaultProviders
();
FilePath
p
=
providers
.
get
(
scheme
);
if
(
p
==
null
)
{
// provider not found - use the default
p
=
DEFAULT
;
}
return
p
.
getPath
(
path
);
}
private
static
void
registerDefaultProviders
()
{
if
(
providers
==
null
)
{
Map
<
String
,
FilePath
>
map
=
Collections
.
synchronizedMap
(
New
.<
String
,
FilePath
>
hashMap
());
for
(
String
c
:
new
String
[]
{
"org.h2.store.fs.FilePathMem"
,
"org.h2.store.fs.FilePathMemLZF"
,
"org.h2.store.fs.FilePathSplit"
,
"org.h2.store.fs.FilePathNio"
,
"org.h2.store.fs.FilePathNioMapped"
,
"org.h2.store.fs.FilePathZip"
})
{
try
{
FilePath
p
=
(
FilePath
)
Class
.
forName
(
c
).
newInstance
();
map
.
put
(
p
.
getScheme
(),
p
);
}
catch
(
Exception
e
)
{
// ignore - the files may be excluded in purpose
}
}
providers
=
map
;
}
}
/**
* Register a file provider.
*
* @param provider the file provider
*/
public
static
void
register
(
FilePath
provider
)
{
registerDefaultProviders
();
providers
.
put
(
provider
.
getScheme
(),
provider
);
}
/**
* Unregister a file provider.
*
* @param provider the file provider
*/
public
static
void
unregister
(
FilePath
provider
)
{
registerDefaultProviders
();
providers
.
remove
(
provider
.
getScheme
());
}
/**
* Get the size of a file in bytes
*
* @return the size in bytes
*/
public
abstract
long
size
();
/**
* Rename a file if this is allowed.
*
* @param newName the new fully qualified file name
*/
public
abstract
void
moveTo
(
FilePath
newName
);
/**
* Create a new file.
*
* @return true if creating was successful
*/
public
abstract
boolean
createFile
();
/**
* Checks if a file exists.
*
* @return true if it exists
*/
public
abstract
boolean
exists
();
/**
* Delete a file or directory if it exists.
* Directories may only be deleted if they are empty.
*/
public
abstract
void
delete
();
/**
* List the files in the given directory.
*
* @return the list of fully qualified file names
*/
public
abstract
List
<
FilePath
>
listFiles
();
/**
* Normalize a file name.
*
* @return the normalized file name
*/
public
abstract
FilePath
getCanonicalPath
();
/**
* Get the parent directory of a file or directory.
*
* @return the parent directory name
*/
public
abstract
FilePath
getParent
();
/**
* Check if it is a file or a directory.
*
* @return true if it is a directory
*/
public
abstract
boolean
isDirectory
();
/**
* Check if the file name includes a path.
*
* @return if the file name is absolute
*/
public
abstract
boolean
isAbsolute
();
/**
* Get the last modified date of a file
*
* @return the last modified date
*/
public
abstract
long
lastModified
();
/**
* Check if the file is writable.
*
* @return if the file is writable
*/
public
abstract
boolean
canWrite
();
/**
* Create a directory (all required parent directories already exist).
*/
public
abstract
void
createDirectory
();
/**
* Get the file or directory name (the last element of the path).
*
* @return the last element of the path
*/
public
String
getName
()
{
int
idx
=
Math
.
max
(
name
.
indexOf
(
':'
),
name
.
lastIndexOf
(
'/'
));
return
idx
<
0
?
name
:
name
.
substring
(
idx
+
1
);
}
/**
* Check if a file starts with a given prefix.
*
* @param prefix the prefix
* @return true if it starts with the prefix
*/
public
abstract
boolean
fileStartsWith
(
String
prefix
);
/**
* Create an output stream to write into the file.
*
* @param append if true, the file will grow, if false, the file will be
* truncated first
* @return the output stream
*/
public
abstract
OutputStream
newOutputStream
(
boolean
append
);
/**
* Open a random access file object.
*
* @param mode the access mode. Supported are r, rw, rws, rwd
* @return the file object
*/
public
abstract
FileObject
openFileObject
(
String
mode
)
throws
IOException
;
/**
* Create an input stream to read from the file.
*
* @return the input stream
*/
public
abstract
InputStream
newInputStream
()
throws
IOException
;
/**
* Disable the ability to write.
*
* @return true if the call was successful
*/
public
abstract
boolean
setReadOnly
();
/**
* Create a new temporary file.
*
* @param suffix the suffix
* @param deleteOnExit if the file should be deleted when the virtual
* machine exists
* @param inTempDir if the file should be stored in the temporary directory
* @return the name of the created file
*/
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
while
(
true
)
{
FilePath
p
=
getPath
(
name
+
getNextTempFileNamePart
(
false
)
+
suffix
);
if
(
p
.
exists
()
||
!
p
.
createFile
())
{
// in theory, the random number could collide
getNextTempFileNamePart
(
true
);
continue
;
}
p
.
openFileObject
(
"rw"
).
close
();
return
p
;
}
}
/**
* Get the next temporary file name part (the part in the middle).
*
* @param newRandom if the random part of the filename should change
* @return the file name part
*/
protected
static
synchronized
String
getNextTempFileNamePart
(
boolean
newRandom
)
{
if
(
newRandom
||
tempRandom
==
null
)
{
byte
[]
prefix
=
new
byte
[
8
];
MathUtils
.
randomBytes
(
prefix
);
tempRandom
=
StringUtils
.
convertBytesToHex
(
prefix
)
+
"."
;
}
return
tempRandom
+
tempSequence
++;
}
/**
* Get the string representation. The returned string can be used to
* construct a new object.
*
* @return the path as a string
*/
public
String
toString
()
{
return
name
;
}
/**
* Get the scheme (prefix) for this file provider.
* This is similar to <code>java.nio.file.spi.FileSystemProvider.getScheme</code>.
*
* @return the scheme
*/
public
abstract
String
getScheme
();
/**
* Convert a file to a path. This is similar to
* <code>java.nio.file.spi.FileSystemProvider.getPath</code>, but may
* return an object even if the scheme doesn't match in case of the the
* default file provider.
*
* @param path
* @return the file path
*/
public
abstract
FilePath
getPath
(
String
path
);
/**
* Get the unwrapped file name (without wrapper prefixes if wrapping /
* delegating file systems are used).
*
* @return the unwrapped path
*/
public
FilePath
unwrap
()
{
return
this
;
}
}
h2/src/main/org/h2/store/fs/FilePathDisk.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
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.RandomAccessFile
;
import
java.net.URL
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.util.IOUtils
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
/**
* This file system stores files on disk.
* This is the most common file system.
*/
public
class
FilePathDisk
extends
FilePath
{
private
static
final
boolean
IS_FILE_SYSTEM_CASE_INSENSITIVE
=
File
.
separatorChar
==
'\\'
;
private
static
final
String
CLASSPATH_PREFIX
=
"classpath:"
;
public
FilePathDisk
getPath
(
String
path
)
{
FilePathDisk
p
=
new
FilePathDisk
();
p
.
name
=
path
;
return
p
;
}
public
long
size
()
{
return
new
File
(
name
).
length
();
}
/**
* Translate the file name to the native format.
* This will expand the home directory (~).
*
* @param fileName the file name
* @return the native file name
*/
protected
static
String
translateFileName
(
String
fileName
)
{
return
expandUserHomeDirectory
(
fileName
);
}
/**
* Expand '~' to the user home directory. It is only be expanded if the ~
* stands alone, or is followed by / or \.
*
* @param fileName the file name
* @return the native file name
*/
public
static
String
expandUserHomeDirectory
(
String
fileName
)
{
if
(
fileName
==
null
)
{
return
null
;
}
boolean
prefix
=
false
;
if
(
fileName
.
startsWith
(
"file:"
))
{
prefix
=
true
;
fileName
=
fileName
.
substring
(
"file:"
.
length
());
}
if
(
fileName
.
startsWith
(
"~"
)
&&
(
fileName
.
length
()
==
1
||
fileName
.
startsWith
(
"~/"
)
||
fileName
.
startsWith
(
"~\\"
)))
{
String
userDir
=
SysProperties
.
USER_HOME
;
fileName
=
userDir
+
fileName
.
substring
(
1
);
}
return
prefix
?
"file:"
+
fileName
:
fileName
;
}
public
void
moveTo
(
FilePath
newName
)
{
File
oldFile
=
new
File
(
name
);
File
newFile
=
new
File
(
newName
.
name
);
if
(
oldFile
.
getAbsolutePath
().
equals
(
newFile
.
getAbsolutePath
()))
{
DbException
.
throwInternalError
(
"rename file old=new"
);
}
if
(!
oldFile
.
exists
())
{
throw
DbException
.
get
(
ErrorCode
.
FILE_RENAME_FAILED_2
,
name
+
" (not found)"
,
newName
.
name
);
}
if
(
newFile
.
exists
())
{
throw
DbException
.
get
(
ErrorCode
.
FILE_RENAME_FAILED_2
,
new
String
[]
{
name
,
newName
+
" (exists)"
});
}
for
(
int
i
=
0
;
i
<
SysProperties
.
MAX_FILE_RETRY
;
i
++)
{
IOUtils
.
trace
(
"rename"
,
name
+
" >"
+
newName
,
null
);
boolean
ok
=
oldFile
.
renameTo
(
newFile
);
if
(
ok
)
{
return
;
}
wait
(
i
);
}
throw
DbException
.
get
(
ErrorCode
.
FILE_RENAME_FAILED_2
,
new
String
[]{
name
,
newName
.
name
});
}
private
static
void
wait
(
int
i
)
{
if
(
i
==
8
)
{
System
.
gc
();
}
try
{
// sleep at most 256 ms
long
sleep
=
Math
.
min
(
256
,
i
*
i
);
Thread
.
sleep
(
sleep
);
}
catch
(
InterruptedException
e
)
{
// ignore
}
}
public
boolean
createFile
()
{
File
file
=
new
File
(
name
);
for
(
int
i
=
0
;
i
<
SysProperties
.
MAX_FILE_RETRY
;
i
++)
{
try
{
return
file
.
createNewFile
();
}
catch
(
IOException
e
)
{
// 'access denied' is really a concurrent access problem
wait
(
i
);
}
}
return
false
;
}
public
boolean
exists
()
{
return
new
File
(
name
).
exists
();
}
public
void
delete
()
{
System
.
out
.
println
(
"delete "
+
name
);
// if (true)return;
File
file
=
new
File
(
name
);
for
(
int
i
=
0
;
i
<
SysProperties
.
MAX_FILE_RETRY
;
i
++)
{
IOUtils
.
trace
(
"delete"
,
name
,
null
);
boolean
ok
=
file
.
delete
();
if
(
ok
||
!
file
.
exists
())
{
return
;
}
wait
(
i
);
}
throw
DbException
.
get
(
ErrorCode
.
FILE_DELETE_FAILED_1
,
name
);
}
public
List
<
FilePath
>
listFiles
()
{
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
File
f
=
new
File
(
name
);
try
{
String
[]
files
=
f
.
list
();
if
(
files
!=
null
)
{
String
base
=
f
.
getCanonicalPath
();
if
(!
base
.
endsWith
(
SysProperties
.
FILE_SEPARATOR
))
{
base
+=
SysProperties
.
FILE_SEPARATOR
;
}
for
(
int
i
=
0
,
len
=
files
.
length
;
i
<
len
;
i
++)
{
list
.
add
(
getPath
(
base
+
files
[
i
]));
}
}
return
list
;
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
boolean
canWrite
()
{
return
canWriteInternal
(
new
File
(
name
));
}
public
boolean
setReadOnly
()
{
File
f
=
new
File
(
name
);
return
f
.
setReadOnly
();
}
public
FilePathDisk
getCanonicalPath
()
{
return
getPath
(
getCanonicalPath
(
name
));
}
private
static
String
getCanonicalPath
(
String
fileName
)
{
fileName
=
translateFileName
(
fileName
);
File
f
=
new
File
(
fileName
);
try
{
return
f
.
getCanonicalPath
();
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
fileName
);
}
}
public
FilePath
getParent
()
{
String
p
=
new
File
(
name
).
getParent
();
return
p
==
null
?
null
:
getPath
(
p
);
}
public
boolean
isDirectory
()
{
return
new
File
(
name
).
isDirectory
();
}
public
boolean
isAbsolute
()
{
return
new
File
(
name
).
isAbsolute
();
}
public
long
lastModified
()
{
return
new
File
(
name
).
lastModified
();
}
private
static
boolean
canWriteInternal
(
File
file
)
{
try
{
if
(!
file
.
canWrite
())
{
return
false
;
}
}
catch
(
Exception
e
)
{
// workaround for GAE which throws a
// java.security.AccessControlException
return
false
;
}
// File.canWrite() does not respect windows user permissions,
// so we must try to open it using the mode "rw".
// See also http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4420020
RandomAccessFile
r
=
null
;
try
{
r
=
new
RandomAccessFile
(
file
,
"rw"
);
return
true
;
}
catch
(
FileNotFoundException
e
)
{
return
false
;
}
finally
{
if
(
r
!=
null
)
{
try
{
r
.
close
();
}
catch
(
IOException
e
)
{
// ignore
}
}
}
}
public
void
createDirectory
()
{
File
f
=
new
File
(
name
);
if
(!
f
.
exists
())
{
File
dir
=
new
File
(
name
);
for
(
int
i
=
0
;
i
<
SysProperties
.
MAX_FILE_RETRY
;
i
++)
{
if
((
dir
.
exists
()
&&
dir
.
isDirectory
())
||
dir
.
mkdir
())
{
return
;
}
wait
(
i
);
}
throw
DbException
.
get
(
ErrorCode
.
FILE_CREATION_FAILED_1
,
name
);
}
}
public
String
getName
(
String
path
)
{
path
=
translateFileName
(
path
);
return
new
File
(
path
).
getName
();
}
public
boolean
fileStartsWith
(
String
prefix
)
{
prefix
=
translateFileName
(
prefix
);
String
fileName
=
name
;
if
(
IS_FILE_SYSTEM_CASE_INSENSITIVE
)
{
fileName
=
StringUtils
.
toUpperEnglish
(
fileName
);
prefix
=
StringUtils
.
toUpperEnglish
(
prefix
);
}
return
fileName
.
startsWith
(
prefix
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
File
file
=
new
File
(
name
);
File
parent
=
file
.
getParentFile
();
if
(
parent
!=
null
)
{
FileUtils
.
createDirectories
(
parent
.
getAbsolutePath
());
}
FileOutputStream
out
=
new
FileOutputStream
(
name
,
append
);
IOUtils
.
trace
(
"openFileOutputStream"
,
name
,
out
);
return
out
;
}
catch
(
IOException
e
)
{
freeMemoryAndFinalize
();
try
{
return
new
FileOutputStream
(
name
);
}
catch
(
IOException
e2
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
}
public
InputStream
newInputStream
()
throws
IOException
{
if
(
name
.
indexOf
(
':'
)
>
1
)
{
// if the : is in position 1, a windows file access is assumed: C:.. or D:
if
(
name
.
startsWith
(
CLASSPATH_PREFIX
))
{
String
fileName
=
name
.
substring
(
CLASSPATH_PREFIX
.
length
());
if
(!
fileName
.
startsWith
(
"/"
))
{
fileName
=
"/"
+
fileName
;
}
InputStream
in
=
getClass
().
getResourceAsStream
(
fileName
);
if
(
in
==
null
)
{
Thread
.
currentThread
().
getContextClassLoader
().
getResourceAsStream
(
fileName
);
}
if
(
in
==
null
)
{
throw
new
FileNotFoundException
(
"resource "
+
fileName
);
}
return
in
;
}
// otherwise an URL is assumed
URL
url
=
new
URL
(
name
);
InputStream
in
=
url
.
openStream
();
return
in
;
}
FileInputStream
in
=
new
FileInputStream
(
name
);
IOUtils
.
trace
(
"openFileInputStream"
,
name
,
in
);
return
in
;
}
/**
* Call the garbage collection and run finalization. This close all files that
* were not closed, and are no longer referenced.
*/
static
void
freeMemoryAndFinalize
()
{
IOUtils
.
trace
(
"freeMemoryAndFinalize"
,
null
,
null
);
Runtime
rt
=
Runtime
.
getRuntime
();
long
mem
=
rt
.
freeMemory
();
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
rt
.
gc
();
long
now
=
rt
.
freeMemory
();
rt
.
runFinalization
();
if
(
now
==
mem
)
{
break
;
}
mem
=
now
;
}
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
FileObjectDisk
f
;
try
{
f
=
new
FileObjectDisk
(
name
,
mode
);
IOUtils
.
trace
(
"openFileObject"
,
name
,
f
);
}
catch
(
IOException
e
)
{
freeMemoryAndFinalize
();
try
{
f
=
new
FileObjectDisk
(
name
,
mode
);
}
catch
(
IOException
e2
)
{
throw
e
;
}
}
return
f
;
}
protected
boolean
accepts
()
{
return
true
;
}
public
String
unwrap
(
String
fileName
)
{
return
fileName
;
}
public
String
getScheme
()
{
return
"file"
;
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
String
fileName
=
translateFileName
(
name
);
fileName
+=
"."
;
String
prefix
=
new
File
(
fileName
).
getName
();
File
dir
;
if
(
inTempDir
)
{
dir
=
new
File
(
Utils
.
getProperty
(
"java.io.tmpdir"
,
"."
));
}
else
{
dir
=
new
File
(
fileName
).
getAbsoluteFile
().
getParentFile
();
FileUtils
.
createDirectories
(
dir
.
getAbsolutePath
());
}
while
(
true
)
{
File
f
=
new
File
(
dir
,
prefix
+
getNextTempFileNamePart
(
false
)
+
suffix
);
if
(
f
.
exists
()
||
!
f
.
createNewFile
())
{
// in theory, the random number could collide
getNextTempFileNamePart
(
true
);
continue
;
}
if
(
deleteOnExit
)
{
try
{
f
.
deleteOnExit
();
}
catch
(
Throwable
e
)
{
// sometimes this throws a NullPointerException
// at java.io.DeleteOnExitHook.add(DeleteOnExitHook.java:33)
// we can ignore it
}
}
return
get
(
f
.
getCanonicalPath
());
}
}
}
h2/src/main/org/h2/store/fs/FilePathMem.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.TreeMap
;
import
org.h2.message.DbException
;
import
org.h2.util.New
;
/**
* This file system keeps files fully in memory. There is an option to compress
* file blocks to safe memory.
*/
public
class
FilePathMem
extends
FilePath
{
private
static
final
TreeMap
<
String
,
FileObjectMemoryData
>
MEMORY_FILES
=
new
TreeMap
<
String
,
FileObjectMemoryData
>();
public
FilePathMem
getPath
(
String
path
)
{
FilePathMem
p
=
new
FilePathMem
();
p
.
name
=
getCanonicalPath
(
path
);
return
p
;
}
public
long
size
()
{
return
getMemoryFile
().
length
();
}
public
void
moveTo
(
FilePath
newName
)
{
synchronized
(
MEMORY_FILES
)
{
FileObjectMemoryData
f
=
getMemoryFile
();
f
.
setName
(
newName
.
name
);
MEMORY_FILES
.
remove
(
name
);
MEMORY_FILES
.
put
(
newName
.
name
,
f
);
}
}
public
boolean
createFile
()
{
synchronized
(
MEMORY_FILES
)
{
if
(
exists
())
{
return
false
;
}
getMemoryFile
();
}
return
true
;
}
public
boolean
exists
()
{
if
(
isRoot
())
{
return
true
;
}
synchronized
(
MEMORY_FILES
)
{
return
MEMORY_FILES
.
get
(
name
)
!=
null
;
}
}
public
void
delete
()
{
if
(
isRoot
())
{
return
;
}
synchronized
(
MEMORY_FILES
)
{
MEMORY_FILES
.
remove
(
name
);
}
}
public
List
<
FilePath
>
listFiles
()
{
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
synchronized
(
MEMORY_FILES
)
{
for
(
String
n
:
MEMORY_FILES
.
tailMap
(
name
).
keySet
())
{
if
(
n
.
startsWith
(
name
))
{
list
.
add
(
getPath
(
n
));
}
else
{
break
;
}
}
return
list
;
}
}
public
boolean
setReadOnly
()
{
return
getMemoryFile
().
setReadOnly
();
}
public
boolean
canWrite
()
{
return
getMemoryFile
().
canWrite
();
}
public
FilePathMem
getParent
()
{
int
idx
=
name
.
lastIndexOf
(
'/'
);
return
idx
<
0
?
null
:
getPath
(
name
.
substring
(
0
,
idx
));
}
public
boolean
isDirectory
()
{
// TODO in memory file system currently
// does not really support directories
return
false
;
}
public
boolean
isAbsolute
()
{
// TODO relative files are not supported
return
true
;
}
public
FilePathMem
getCanonicalPath
()
{
return
this
;
}
public
long
lastModified
()
{
return
getMemoryFile
().
getLastModified
();
}
public
void
createDirectory
()
{
// TODO directories are not really supported
}
public
boolean
fileStartsWith
(
String
prefix
)
{
prefix
=
getCanonicalPath
(
prefix
);
return
name
.
startsWith
(
prefix
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
FileObjectMemoryData
obj
=
getMemoryFile
();
FileObjectMemory
m
=
new
FileObjectMemory
(
obj
,
false
);
return
new
FileObjectOutputStream
(
m
,
append
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
InputStream
newInputStream
()
{
FileObjectMemoryData
obj
=
getMemoryFile
();
FileObjectMemory
m
=
new
FileObjectMemory
(
obj
,
true
);
return
new
FileObjectInputStream
(
m
);
}
public
FileObject
openFileObject
(
String
mode
)
{
FileObjectMemoryData
obj
=
getMemoryFile
();
return
new
FileObjectMemory
(
obj
,
"r"
.
equals
(
mode
));
}
private
FileObjectMemoryData
getMemoryFile
()
{
synchronized
(
MEMORY_FILES
)
{
FileObjectMemoryData
m
=
MEMORY_FILES
.
get
(
name
);
if
(
m
==
null
)
{
m
=
new
FileObjectMemoryData
(
name
,
compressed
());
MEMORY_FILES
.
put
(
name
,
m
);
}
return
m
;
}
}
private
boolean
isRoot
()
{
return
name
.
equals
(
getScheme
());
}
protected
boolean
accepts
(
String
fileName
)
{
return
fileName
.
startsWith
(
getScheme
());
}
public
String
unwrap
(
String
fileName
)
{
return
fileName
;
}
private
static
String
getCanonicalPath
(
String
fileName
)
{
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
int
idx
=
fileName
.
indexOf
(
':'
)
+
1
;
if
(
fileName
.
length
()
>
idx
&&
fileName
.
charAt
(
idx
)
!=
'/'
)
{
fileName
=
fileName
.
substring
(
0
,
idx
)
+
"/"
+
fileName
.
substring
(
idx
);
}
return
fileName
;
}
public
String
getScheme
()
{
return
"memFS"
;
}
boolean
compressed
()
{
return
false
;
}
}
/**
* A memory file system that compresses blocks to conserve memory.
*/
class
FilePathMemLZF
extends
FilePathMem
{
boolean
compressed
()
{
return
true
;
}
public
String
getScheme
()
{
return
"memLZF"
;
}
}
h2/src/main/org/h2/store/fs/FilePathNio.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
/**
* This file system stores files on disk and uses java.nio to access the files.
* This class uses FileChannel.
*/
public
class
FilePathNio
extends
FilePathWrapper
{
/**
* Try to open a file with this name and mode.
*
* @param fileName the file name
* @param mode the open mode
* @return the file object
* @throws IOException if opening fails
*/
protected
FileObject
open
(
String
fileName
,
String
mode
)
throws
IOException
{
return
new
FileObjectDiskChannel
(
fileName
,
mode
);
}
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
public
String
getScheme
()
{
return
"nio"
;
}
}
h2/src/main/org/h2/store/fs/FilePathNioMapped.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
/**
* This file system stores files on disk and uses java.nio to access the files.
* This class used memory mapped files.
*/
public
class
FilePathNioMapped
extends
FilePathNio
{
protected
FileObject
open
(
String
mode
)
throws
IOException
{
return
new
FileObjectDiskMapped
(
name
,
mode
);
}
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
public
String
getScheme
()
{
return
"nioMapped"
;
}
}
h2/src/main/org/h2/store/fs/FilePathRec.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.OutputStream
;
/**
* A file system that records all write operations and can re-play them.
*/
public
class
FilePathRec
extends
FilePathWrapper
{
private
static
final
FilePathRec
INSTANCE
=
new
FilePathRec
();
private
static
Recorder
recorder
;
private
boolean
trace
;
/**
* Register the file system.
*/
public
static
void
register
()
{
FilePath
.
register
(
INSTANCE
);
}
/**
* Set the recorder class.
*
* @param recorder the recorder
*/
public
static
void
setRecorder
(
Recorder
recorder
)
{
FilePathRec
.
recorder
=
recorder
;
}
public
boolean
createFile
()
{
log
(
Recorder
.
CREATE_NEW_FILE
,
name
);
return
super
.
createFile
();
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
log
(
Recorder
.
CREATE_TEMP_FILE
,
unwrap
(
name
)
+
":"
+
suffix
+
":"
+
deleteOnExit
+
":"
+
inTempDir
);
return
super
.
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
);
}
public
void
delete
()
{
log
(
Recorder
.
DELETE
,
name
);
super
.
delete
();
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
return
new
FileObjectRec
(
this
,
super
.
openFileObject
(
mode
),
name
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
log
(
Recorder
.
OPEN_OUTPUT_STREAM
,
name
);
return
super
.
newOutputStream
(
append
);
}
public
void
moveTo
(
FilePath
newPath
)
{
log
(
Recorder
.
RENAME
,
unwrap
(
name
)
+
":"
+
unwrap
(
newPath
.
name
));
super
.
moveTo
(
newPath
);
}
public
boolean
isTrace
()
{
return
trace
;
}
public
void
setTrace
(
boolean
trace
)
{
this
.
trace
=
trace
;
}
/**
* Log the operation.
*
* @param op the operation
* @param fileName the file name(s)
*/
void
log
(
int
op
,
String
fileName
)
{
log
(
op
,
fileName
,
null
,
0
);
}
/**
* Log the operation.
*
* @param op the operation
* @param fileName the file name
* @param data the data or null
* @param x the value or 0
*/
void
log
(
int
op
,
String
fileName
,
byte
[]
data
,
long
x
)
{
if
(
recorder
!=
null
)
{
recorder
.
log
(
op
,
fileName
,
data
,
x
);
}
}
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
public
String
getScheme
()
{
return
"rec"
;
}
}
h2/src/main/org/h2/store/fs/FilePathSplit.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.SequenceInputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.h2.constant.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.util.New
;
/**
* A file system that may split files into multiple smaller files.
* (required for a FAT32 because it only support files up to 2 GB).
*/
public
class
FilePathSplit
extends
FilePathWrapper
{
private
static
final
String
PART_SUFFIX
=
".part"
;
protected
String
getPrefix
()
{
return
getScheme
()
+
":"
+
parse
(
name
)[
0
]
+
":"
;
}
public
FilePath
unwrap
(
String
fileName
)
{
return
FilePath
.
get
(
parse
(
fileName
)[
1
]);
}
public
boolean
setReadOnly
()
{
boolean
result
=
false
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
result
=
f
.
setReadOnly
();
}
else
{
break
;
}
}
return
result
;
}
public
void
delete
()
{
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
f
.
delete
();
}
else
{
break
;
}
}
}
public
long
lastModified
()
{
long
lastModified
=
0
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
long
l
=
f
.
lastModified
();
lastModified
=
Math
.
max
(
lastModified
,
l
);
}
else
{
break
;
}
}
return
lastModified
;
}
public
long
size
()
{
long
length
=
0
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
length
+=
f
.
size
();
}
else
{
break
;
}
}
return
length
;
}
public
ArrayList
<
FilePath
>
listFiles
()
{
List
<
FilePath
>
list
=
getBase
().
listFiles
();
ArrayList
<
FilePath
>
newList
=
New
.
arrayList
();
for
(
int
i
=
0
,
size
=
list
.
size
();
i
<
size
;
i
++)
{
FilePath
f
=
list
.
get
(
i
);
if
(!
f
.
getName
().
endsWith
(
PART_SUFFIX
))
{
newList
.
add
(
wrap
(
f
));
}
}
return
newList
;
}
public
InputStream
newInputStream
()
throws
IOException
{
InputStream
input
=
getBase
().
newInputStream
();
for
(
int
i
=
1
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
InputStream
i2
=
f
.
newInputStream
();
input
=
new
SequenceInputStream
(
input
,
i2
);
}
else
{
break
;
}
}
return
input
;
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
ArrayList
<
FileObject
>
list
=
New
.
arrayList
();
FileObject
o
=
getBase
().
openFileObject
(
mode
);
list
.
add
(
o
);
for
(
int
i
=
1
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
o
=
f
.
openFileObject
(
mode
);
list
.
add
(
o
);
}
else
{
break
;
}
}
FileObject
[]
array
=
new
FileObject
[
list
.
size
()];
list
.
toArray
(
array
);
long
maxLength
=
array
[
0
].
size
();
long
length
=
maxLength
;
if
(
array
.
length
==
1
)
{
long
defaultMaxLength
=
getDefaultMaxLength
();
if
(
maxLength
<
defaultMaxLength
)
{
maxLength
=
defaultMaxLength
;
}
}
else
{
if
(
maxLength
==
0
)
{
closeAndThrow
(
0
,
array
,
array
[
0
],
maxLength
);
}
for
(
int
i
=
1
;
i
<
array
.
length
-
1
;
i
++)
{
o
=
array
[
i
];
long
l
=
o
.
size
();
length
+=
l
;
if
(
l
!=
maxLength
)
{
closeAndThrow
(
i
,
array
,
o
,
maxLength
);
}
}
o
=
array
[
array
.
length
-
1
];
long
l
=
o
.
size
();
length
+=
l
;
if
(
l
>
maxLength
)
{
closeAndThrow
(
array
.
length
-
1
,
array
,
o
,
maxLength
);
}
}
FileObjectSplit
fo
=
new
FileObjectSplit
(
name
,
mode
,
array
,
length
,
maxLength
);
return
fo
;
}
private
long
getDefaultMaxLength
()
{
return
1L
<<
Integer
.
decode
(
parse
(
name
)[
0
]).
intValue
();
}
private
void
closeAndThrow
(
int
id
,
FileObject
[]
array
,
FileObject
o
,
long
maxLength
)
throws
IOException
{
String
message
=
"Expected file length: "
+
maxLength
+
" got: "
+
o
.
size
()
+
" for "
+
getName
(
id
);
for
(
FileObject
f
:
array
)
{
f
.
close
();
}
throw
new
IOException
(
message
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
return
new
FileObjectOutputStream
(
openFileObject
(
"rw"
),
append
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
void
moveTo
(
FilePath
path
)
{
FilePathSplit
newName
=
(
FilePathSplit
)
path
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
o
=
getBase
(
i
);
if
(
o
.
exists
())
{
o
.
moveTo
(
newName
.
getBase
(
i
));
}
else
{
break
;
}
}
}
/**
* Split the file name into size and base file name.
*
* @param fileName the file name
* @return an array with size and file name
*/
private
String
[]
parse
(
String
fileName
)
{
if
(!
fileName
.
startsWith
(
getScheme
()))
{
DbException
.
throwInternalError
(
fileName
+
" doesn't start with "
+
getScheme
());
}
fileName
=
fileName
.
substring
(
getScheme
().
length
()
+
1
);
String
size
;
if
(
fileName
.
length
()
>
0
&&
Character
.
isDigit
(
fileName
.
charAt
(
0
)))
{
int
idx
=
fileName
.
indexOf
(
':'
);
size
=
fileName
.
substring
(
0
,
idx
);
try
{
fileName
=
fileName
.
substring
(
idx
+
1
);
}
catch
(
NumberFormatException
e
)
{
// ignore
}
}
else
{
size
=
Long
.
toString
(
SysProperties
.
SPLIT_FILE_SIZE_SHIFT
);
}
return
new
String
[]
{
size
,
fileName
};
}
/**
* Get the file name of a part file.
*
* @param id the part id
* @return the file name including the part id
*/
private
FilePath
getBase
(
int
id
)
{
return
FilePath
.
get
(
getName
(
id
));
}
private
String
getName
(
int
id
)
{
return
id
>
0
?
getBase
().
name
+
"."
+
id
+
PART_SUFFIX
:
getBase
().
name
;
}
public
String
getScheme
()
{
return
"split"
;
}
}
\ No newline at end of file
h2/src/main/org/h2/store/fs/FilePathWrapper.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.List
;
import
org.h2.message.DbException
;
/**
* The base class for wrapping / delegating file systems such as
* the split file system.
*/
public
abstract
class
FilePathWrapper
extends
FilePath
{
private
FilePath
base
;
public
FilePathWrapper
getPath
(
String
path
)
{
return
create
(
path
,
unwrap
(
path
));
}
public
FilePathWrapper
wrap
(
FilePath
base
)
{
return
create
(
getPrefix
()
+
base
.
name
,
base
);
}
public
FilePath
unwrap
()
{
return
unwrap
(
name
);
}
private
FilePathWrapper
create
(
String
path
,
FilePath
base
)
{
try
{
FilePathWrapper
p
=
getClass
().
newInstance
();
p
.
name
=
path
;
p
.
base
=
base
;
return
p
;
}
catch
(
Exception
e
)
{
throw
DbException
.
convert
(
e
);
}
}
protected
String
getPrefix
()
{
return
getScheme
()
+
":"
;
}
protected
FilePath
unwrap
(
String
path
)
{
return
FilePath
.
get
(
path
.
substring
(
getScheme
().
length
()
+
1
));
}
protected
FilePath
getBase
()
{
return
base
;
}
public
boolean
canWrite
()
{
return
base
.
canWrite
();
}
public
void
createDirectory
()
{
base
.
createDirectory
();
}
public
boolean
createFile
()
{
return
base
.
createFile
();
}
public
void
delete
()
{
base
.
delete
();
}
public
boolean
exists
()
{
return
base
.
exists
();
}
public
boolean
fileStartsWith
(
String
prefix
)
{
return
name
.
startsWith
(
prefix
);
}
public
FilePath
getParent
()
{
return
wrap
(
base
.
getParent
());
}
public
boolean
isAbsolute
()
{
return
base
.
isAbsolute
();
}
public
boolean
isDirectory
()
{
return
base
.
isDirectory
();
}
public
long
lastModified
()
{
return
base
.
lastModified
();
}
public
FilePath
getCanonicalPath
()
{
return
wrap
(
base
.
getCanonicalPath
());
}
public
List
<
FilePath
>
listFiles
()
{
List
<
FilePath
>
list
=
base
.
listFiles
();
for
(
int
i
=
0
,
len
=
list
.
size
();
i
<
len
;
i
++)
{
list
.
set
(
i
,
wrap
(
list
.
get
(
i
)));
}
return
list
;
}
public
void
moveTo
(
FilePath
newName
)
{
base
.
moveTo
(((
FilePathWrapper
)
newName
).
base
);
}
public
InputStream
newInputStream
()
throws
IOException
{
return
base
.
newInputStream
();
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
return
base
.
newOutputStream
(
append
);
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
return
base
.
openFileObject
(
mode
);
}
public
boolean
setReadOnly
()
{
return
base
.
setReadOnly
();
}
public
long
size
()
{
return
base
.
size
();
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
return
wrap
(
base
.
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
));
}
}
h2/src/main/org/h2/store/fs/FilePathZip.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
org.h2.message.DbException
;
import
org.h2.util.New
;
/**
* This is a read-only file system that allows
* to access databases stored in a .zip or .jar file.
*/
public
class
FilePathZip
extends
FilePath
{
public
FilePathZip
getPath
(
String
path
)
{
FilePathZip
p
=
new
FilePathZip
();
p
.
name
=
path
;
return
p
;
}
public
void
createDirectory
()
{
// ignore
}
public
boolean
createFile
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
String
createTempFile
(
String
prefix
,
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
if
(!
inTempDir
)
{
throw
new
IOException
(
"File system is read-only"
);
}
return
FileSystemDisk
.
getInstance
().
createTempFile
(
prefix
,
suffix
,
deleteOnExit
,
true
);
}
public
void
delete
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
boolean
exists
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipFile
file
=
openZipFile
();
return
file
.
getEntry
(
entryName
)
!=
null
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
fileStartsWith
(
String
fileName
,
String
prefix
)
{
return
fileName
.
startsWith
(
prefix
);
}
// public String _getName(String name) {
// name = getEntryName(name);
// if (name.endsWith("/")) {
// name = name.substring(0, name.length() - 1);
// }
// int idx = name.lastIndexOf('/');
// if (idx >= 0) {
// name = name.substring(idx + 1);
// }
// return name;
// }
public
long
lastModified
()
{
return
0
;
}
public
FilePath
getParent
()
{
int
idx
=
name
.
lastIndexOf
(
'/'
);
return
idx
<
0
?
null
:
getPath
(
name
.
substring
(
0
,
idx
));
}
public
boolean
isAbsolute
()
{
return
true
;
}
public
boolean
isDirectory
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipFile
file
=
openZipFile
();
Enumeration
<?
extends
ZipEntry
>
en
=
file
.
entries
();
while
(
en
.
hasMoreElements
())
{
ZipEntry
entry
=
en
.
nextElement
();
String
n
=
entry
.
getName
();
if
(
n
.
equals
(
entryName
))
{
return
entry
.
isDirectory
();
}
else
if
(
n
.
startsWith
(
entryName
))
{
if
(
n
.
length
()
==
entryName
.
length
()
+
1
)
{
if
(
n
.
equals
(
entryName
+
"/"
))
{
return
true
;
}
}
}
}
return
false
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
canWrite
()
{
return
false
;
}
public
boolean
setReadOnly
()
{
return
true
;
}
public
long
size
()
{
try
{
ZipFile
file
=
openZipFile
();
ZipEntry
entry
=
file
.
getEntry
(
getEntryName
());
return
entry
==
null
?
0
:
entry
.
getSize
();
}
catch
(
IOException
e
)
{
return
0
;
}
}
public
ArrayList
<
FilePath
>
listFiles
()
{
String
path
=
name
;
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
try
{
if
(
path
.
indexOf
(
'!'
)
<
0
)
{
path
+=
"!"
;
}
if
(!
path
.
endsWith
(
"/"
))
{
path
+=
"/"
;
}
ZipFile
file
=
openZipFile
();
String
dirName
=
getEntryName
();
String
prefix
=
path
.
substring
(
0
,
path
.
length
()
-
dirName
.
length
());
Enumeration
<?
extends
ZipEntry
>
en
=
file
.
entries
();
while
(
en
.
hasMoreElements
())
{
ZipEntry
entry
=
en
.
nextElement
();
String
name
=
entry
.
getName
();
if
(!
name
.
startsWith
(
dirName
))
{
continue
;
}
if
(
name
.
length
()
<=
dirName
.
length
())
{
continue
;
}
int
idx
=
name
.
indexOf
(
'/'
,
dirName
.
length
());
if
(
idx
<
0
||
idx
>=
name
.
length
()
-
1
)
{
list
.
add
(
getPath
(
prefix
+
name
));
}
}
return
list
;
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
"listFiles "
+
path
);
}
}
public
InputStream
newInputStream
()
throws
IOException
{
return
new
FileObjectInputStream
(
openFileObject
(
"r"
));
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
ZipFile
file
=
openZipFile
();
ZipEntry
entry
=
file
.
getEntry
(
getEntryName
());
if
(
entry
==
null
)
{
throw
new
FileNotFoundException
(
name
);
}
return
new
FileObjectZip
(
file
,
entry
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
void
moveTo
(
FilePath
newName
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
private
static
String
translateFileName
(
String
fileName
)
{
if
(
fileName
.
startsWith
(
"zip:"
))
{
fileName
=
fileName
.
substring
(
"zip:"
.
length
());
}
int
idx
=
fileName
.
indexOf
(
'!'
);
if
(
idx
>=
0
)
{
fileName
=
fileName
.
substring
(
0
,
idx
);
}
return
FileSystemDisk
.
expandUserHomeDirectory
(
fileName
);
}
public
FilePath
getCanonicalPath
()
{
return
this
;
}
private
String
getEntryName
()
{
int
idx
=
name
.
indexOf
(
'!'
);
String
fileName
;
if
(
idx
<=
0
)
{
fileName
=
""
;
}
else
{
fileName
=
name
.
substring
(
idx
+
1
);
}
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
if
(
fileName
.
startsWith
(
"/"
))
{
fileName
=
fileName
.
substring
(
1
);
}
return
fileName
;
}
private
ZipFile
openZipFile
()
throws
IOException
{
String
fileName
=
translateFileName
(
name
);
return
new
ZipFile
(
fileName
);
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
if
(!
inTempDir
)
{
throw
new
IOException
(
"File system is read-only"
);
}
return
new
FilePathDisk
().
getPath
(
name
).
createTempFile
(
suffix
,
deleteOnExit
,
true
);
}
// protected boolean accepts(String fileName) {
// return fileName.startsWith(PREFIX);
// }
public
boolean
fileStartsWith
(
String
prefix
)
{
return
name
.
startsWith
(
prefix
);
}
public
String
getScheme
()
{
return
"zip"
;
}
}
h2/src/main/org/h2/store/fs/FileSystem.java
浏览文件 @
ab2f646c
...
@@ -143,14 +143,6 @@ public abstract class FileSystem {
...
@@ -143,14 +143,6 @@ public abstract class FileSystem {
*/
*/
public
abstract
String
[]
listFiles
(
String
directory
);
public
abstract
String
[]
listFiles
(
String
directory
);
/**
* Check if a file is read-only.
*
* @param fileName the file name
* @return if it is read only
*/
public
abstract
boolean
isReadOnly
(
String
fileName
);
/**
/**
* Normalize a file name.
* Normalize a file name.
*
*
...
...
h2/src/main/org/h2/store/fs/FileSystemDisk.java
浏览文件 @
ab2f646c
...
@@ -162,7 +162,7 @@ public class FileSystemDisk extends FileSystem {
...
@@ -162,7 +162,7 @@ public class FileSystemDisk extends FileSystem {
dir
=
new
File
(
Utils
.
getProperty
(
"java.io.tmpdir"
,
"."
));
dir
=
new
File
(
Utils
.
getProperty
(
"java.io.tmpdir"
,
"."
));
}
else
{
}
else
{
dir
=
new
File
(
name
).
getAbsoluteFile
().
getParentFile
();
dir
=
new
File
(
name
).
getAbsoluteFile
().
getParentFile
();
IOUtils
.
mkdirs
(
dir
);
FileUtils
.
createDirectories
(
dir
.
getAbsolutePath
()
);
}
}
File
f
;
File
f
;
while
(
true
)
{
while
(
true
)
{
...
@@ -207,12 +207,6 @@ public class FileSystemDisk extends FileSystem {
...
@@ -207,12 +207,6 @@ public class FileSystemDisk extends FileSystem {
}
}
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
fileName
=
translateFileName
(
fileName
);
File
f
=
new
File
(
fileName
);
return
f
.
exists
()
&&
!
canWriteInternal
(
f
);
}
public
boolean
canWrite
(
String
fileName
)
{
public
boolean
canWrite
(
String
fileName
)
{
fileName
=
translateFileName
(
fileName
);
fileName
=
translateFileName
(
fileName
);
return
canWriteInternal
(
new
File
(
fileName
));
return
canWriteInternal
(
new
File
(
fileName
));
...
...
h2/src/main/org/h2/store/fs/FileSystemMemory.java
浏览文件 @
ab2f646c
...
@@ -103,14 +103,14 @@ public class FileSystemMemory extends FileSystem {
...
@@ -103,14 +103,14 @@ public class FileSystemMemory extends FileSystem {
}
}
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
return
!
getMemoryFile
(
fileName
).
canWrite
();
}
public
boolean
setReadOnly
(
String
fileName
)
{
public
boolean
setReadOnly
(
String
fileName
)
{
return
getMemoryFile
(
fileName
).
setReadOnly
();
return
getMemoryFile
(
fileName
).
setReadOnly
();
}
}
public
boolean
canWrite
(
String
fileName
)
{
return
getMemoryFile
(
fileName
).
canWrite
();
}
public
String
getCanonicalPath
(
String
fileName
)
{
public
String
getCanonicalPath
(
String
fileName
)
{
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
int
idx
=
fileName
.
indexOf
(
':'
)
+
1
;
int
idx
=
fileName
.
indexOf
(
':'
)
+
1
;
...
@@ -144,10 +144,6 @@ public class FileSystemMemory extends FileSystem {
...
@@ -144,10 +144,6 @@ public class FileSystemMemory extends FileSystem {
return
getMemoryFile
(
fileName
).
getLastModified
();
return
getMemoryFile
(
fileName
).
getLastModified
();
}
}
public
boolean
canWrite
(
String
fileName
)
{
return
true
;
}
public
void
createDirectory
(
String
directoryName
)
{
public
void
createDirectory
(
String
directoryName
)
{
// TODO directories are not really supported
// TODO directories are not really supported
}
}
...
...
h2/src/main/org/h2/store/fs/FileSystemWrapper.java
浏览文件 @
ab2f646c
...
@@ -24,10 +24,6 @@ public abstract class FileSystemWrapper extends FileSystem {
...
@@ -24,10 +24,6 @@ public abstract class FileSystemWrapper extends FileSystem {
*/
*/
protected
abstract
String
getPrefix
();
protected
abstract
String
getPrefix
();
public
boolean
canWrite
(
String
fileName
)
{
return
FileUtils
.
canWrite
(
unwrap
(
fileName
));
}
public
boolean
setReadOnly
(
String
fileName
)
{
public
boolean
setReadOnly
(
String
fileName
)
{
return
FileUtils
.
setReadOnly
(
unwrap
(
fileName
));
return
FileUtils
.
setReadOnly
(
unwrap
(
fileName
));
}
}
...
@@ -77,8 +73,8 @@ public abstract class FileSystemWrapper extends FileSystem {
...
@@ -77,8 +73,8 @@ public abstract class FileSystemWrapper extends FileSystem {
return
FileUtils
.
isDirectory
(
unwrap
(
fileName
));
return
FileUtils
.
isDirectory
(
unwrap
(
fileName
));
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
public
boolean
canWrite
(
String
fileName
)
{
return
FileUtils
.
isReadOnly
(
unwrap
(
fileName
));
return
FileUtils
.
canWrite
(
unwrap
(
fileName
));
}
}
public
long
size
(
String
fileName
)
{
public
long
size
(
String
fileName
)
{
...
...
h2/src/main/org/h2/store/fs/FileSystemZip.java
浏览文件 @
ab2f646c
...
@@ -29,10 +29,6 @@ public class FileSystemZip extends FileSystem {
...
@@ -29,10 +29,6 @@ public class FileSystemZip extends FileSystem {
FileSystem
.
register
(
new
FileSystemZip
());
FileSystem
.
register
(
new
FileSystemZip
());
}
}
public
boolean
canWrite
(
String
fileName
)
{
return
false
;
}
public
void
createDirectory
(
String
directoryName
)
{
public
void
createDirectory
(
String
directoryName
)
{
// ignore
// ignore
}
}
...
@@ -124,8 +120,8 @@ public class FileSystemZip extends FileSystem {
...
@@ -124,8 +120,8 @@ public class FileSystemZip extends FileSystem {
}
}
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
public
boolean
canWrite
(
String
fileName
)
{
return
tru
e
;
return
fals
e
;
}
}
public
boolean
setReadOnly
(
String
fileName
)
{
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
h2/src/main/org/h2/store/fs/FileUtils.java
浏览文件 @
ab2f646c
...
@@ -3,6 +3,8 @@ package org.h2.store.fs;
...
@@ -3,6 +3,8 @@ package org.h2.store.fs;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
org.h2.constant.ErrorCode
;
import
org.h2.message.DbException
;
import
org.h2.util.IOUtils
;
import
org.h2.util.IOUtils
;
/**
/**
...
@@ -191,10 +193,10 @@ public class FileUtils {
...
@@ -191,10 +193,10 @@ public class FileUtils {
return
getFileSystem
(
fileName
).
newOutputStream
(
fileName
,
append
);
return
getFileSystem
(
fileName
).
newOutputStream
(
fileName
,
append
);
}
}
// special methods =======================================
/**
/**
* Check if the file is writable.
* Check if the file is writable.
* This method is similar to Java 7
* <code>java.nio.file.Path.checkAccess(AccessMode.WRITE)</code>
*
*
* @param fileName the file name
* @param fileName the file name
* @return if the file is writable
* @return if the file is writable
...
@@ -203,20 +205,10 @@ public class FileUtils {
...
@@ -203,20 +205,10 @@ public class FileUtils {
return
getFileSystem
(
fileName
).
canWrite
(
fileName
);
return
getFileSystem
(
fileName
).
canWrite
(
fileName
);
}
}
/**
// special methods =======================================
* Check if a file is read-only.
* This method is similar to Java 7
* <code>java.nio.file.Path.checkAccess(AccessMode.WRITE)</code>
*
* @param fileName the file name
* @return if it is read only
*/
public
static
boolean
isReadOnly
(
String
fileName
)
{
return
getFileSystem
(
fileName
).
isReadOnly
(
fileName
);
}
/**
/**
* Disable the ability to write.
* Disable the ability to write.
The file can still be deleted afterwards.
*
*
* @param fileName the file name
* @param fileName the file name
* @return true if the call was successful
* @return true if the call was successful
...
@@ -292,10 +284,18 @@ public class FileUtils {
...
@@ -292,10 +284,18 @@ public class FileUtils {
* @param dir the directory name
* @param dir the directory name
*/
*/
public
static
void
createDirectories
(
String
dir
)
{
public
static
void
createDirectories
(
String
dir
)
{
if
(
dir
!=
null
&&
!
FileUtils
.
exists
(
dir
))
{
if
(
dir
!=
null
)
{
String
parent
=
FileUtils
.
getParent
(
dir
);
if
(
FileUtils
.
exists
(
dir
))
{
createDirectories
(
parent
);
if
(!
FileUtils
.
isDirectory
(
dir
))
{
createDirectory
(
dir
);
DbException
.
get
(
ErrorCode
.
FILE_CREATION_FAILED_1
,
"Could not create directory, "
+
"because a file with the same name already exists: "
+
dir
);
}
}
else
{
String
parent
=
FileUtils
.
getParent
(
dir
);
createDirectories
(
parent
);
createDirectory
(
dir
);
}
}
}
}
}
...
...
h2/src/main/org/h2/store/fs/FileUtils2.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.List
;
import
org.h2.constant.ErrorCode
;
import
org.h2.message.DbException
;
import
org.h2.util.IOUtils
;
/**
* This utility class contains utility functions that use the file system abstraction.
*/
public
class
FileUtils2
{
/**
* Checks if a file exists.
* This method is similar to Java 7 <code>java.nio.file.Path.exists</code>.
*
* @param fileName the file name
* @return true if it exists
*/
public
static
boolean
exists
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
exists
();
}
/**
* Create a directory (all required parent directories must already exist).
* This method is similar to Java 7 <code>java.nio.file.Path.createDirectory</code>.
*
* @param directoryName the directory name
*/
public
static
void
createDirectory
(
String
directoryName
)
{
FilePath
.
get
(
directoryName
).
createDirectory
();
}
/**
* Create a new file.
* This method is similar to Java 7 <code>java.nio.file.Path.createFile</code>, but returns
* false instead of throwing a exception if the file already existed.
*
* @param fileName the file name
* @return true if creating was successful
*/
public
static
boolean
createFile
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
createFile
();
}
/**
* Delete a file or directory if it exists.
* Directories may only be deleted if they are empty.
* This method is similar to Java 7 <code>java.nio.file.Path.deleteIfExists</code>.
*
* @param path the file or directory name
*/
public
static
void
delete
(
String
path
)
{
FilePath
.
get
(
path
).
delete
();
}
/**
* Normalize a file name.
* This method is similar to Java 7 <code>java.nio.file.Path.toRealPath</code>.
*
* @param fileName the file name
* @return the normalized file name
*/
public
static
String
getCanonicalPath
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
getCanonicalPath
().
toString
();
}
/**
* Get the parent directory of a file or directory.
* This method returns null if there is no parent.
* This method is similar to Java 7 <code>java.nio.file.Path.getParent</code>.
*
* @param fileName the file or directory name
* @return the parent directory name
*/
public
static
String
getParent
(
String
fileName
)
{
FilePath
p
=
FilePath
.
get
(
fileName
).
getParent
();
return
p
==
null
?
null
:
p
.
toString
();
}
/**
* Check if the file name includes a path.
* This method is similar to Java 7 <code>java.nio.file.Path.isAbsolute</code>.
*
* @param fileName the file name
* @return if the file name is absolute
*/
public
static
boolean
isAbsolute
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
isAbsolute
();
}
/**
* Rename a file if this is allowed.
* This method is similar to Java 7 <code>java.nio.file.Path.moveTo</code>.
*
* @param oldName the old fully qualified file name
* @param newName the new fully qualified file name
*/
public
static
void
moveTo
(
String
oldName
,
String
newName
)
{
FilePath
.
get
(
oldName
).
moveTo
(
FilePath
.
get
(
newName
));
}
/**
* Get the file or directory name (the last element of the path).
* This method is similar to Java 7 <code>java.nio.file.Path.getName</code>.
*
* @param path the directory and file name
* @return just the file name
*/
public
static
String
getName
(
String
path
)
{
return
FilePath
.
get
(
path
).
getName
();
}
/**
* List the files in the given directory.
* This method is similar to Java 7 <code>java.nio.file.Path.newDirectoryStream</code>.
*
* @param path the directory
* @return the list of fully qualified file names
*/
public
static
String
[]
listFiles
(
String
path
)
{
List
<
FilePath
>
list
=
FilePath
.
get
(
path
).
listFiles
();
String
[]
array
=
new
String
[
list
.
size
()];
for
(
int
i
=
0
,
len
=
list
.
size
();
i
<
len
;
i
++)
{
array
[
i
]
=
list
.
get
(
i
).
toString
();
}
return
array
;
}
/**
* Get the last modified date of a file.
* This method is similar to Java 7
* <code>java.nio.file.attribute.Attributes.readBasicFileAttributes(file).lastModified().toMillis()</code>
*
* @param fileName the file name
* @return the last modified date
*/
public
static
long
lastModified
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
lastModified
();
}
/**
* Get the size of a file in bytes
* This method is similar to Java 7
* <code>java.nio.file.attribute.Attributes.readBasicFileAttributes(file).size()</code>
*
* @param fileName the file name
* @return the size in bytes
*/
public
static
long
size
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
size
();
}
/**
* Check if it is a file or a directory.
* <code>java.nio.file.attribute.Attributes.readBasicFileAttributes(file).isDirectory()</code>
*
* @param fileName the file or directory name
* @return true if it is a directory
*/
public
static
boolean
isDirectory
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
isDirectory
();
}
/**
* Open a random access file object.
* This method is similar to Java 7 <code>java.nio.channels.FileChannel.open</code>.
*
* @param fileName the file name
* @param mode the access mode. Supported are r, rw, rws, rwd
* @return the file object
*/
public
static
FileObject
openFileObject
(
String
fileName
,
String
mode
)
throws
IOException
{
return
FilePath
.
get
(
fileName
).
openFileObject
(
mode
);
}
/**
* Create an input stream to read from the file.
* This method is similar to Java 7 <code>java.nio.file.Path.newInputStream</code>.
*
* @param fileName the file name
* @return the input stream
*/
public
static
InputStream
newInputStream
(
String
fileName
)
throws
IOException
{
return
FilePath
.
get
(
fileName
).
newInputStream
();
}
/**
* Create an output stream to write into the file.
* This method is similar to Java 7 <code>java.nio.file.Path.newOutputStream</code>.
*
* @param fileName the file name
* @param append if true, the file will grow, if false, the file will be
* truncated first
* @return the output stream
*/
public
static
OutputStream
newOutputStream
(
String
fileName
,
boolean
append
)
{
return
FilePath
.
get
(
fileName
).
newOutputStream
(
append
);
}
/**
* Check if the file is writable.
* This method is similar to Java 7
* <code>java.nio.file.Path.checkAccess(AccessMode.WRITE)</code>
*
* @param fileName the file name
* @return if the file is writable
*/
public
static
boolean
canWrite
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
canWrite
();
}
// special methods =======================================
/**
* Disable the ability to write. The file can still be deleted afterwards.
*
* @param fileName the file name
* @return true if the call was successful
*/
public
static
boolean
setReadOnly
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
setReadOnly
();
}
/**
* Get the unwrapped file name (without wrapper prefixes if wrapping /
* delegating file systems are used).
*
* @param fileName the file name
* @return the unwrapped
*/
public
static
String
unwrap
(
String
fileName
)
{
return
FilePath
.
get
(
fileName
).
unwrap
().
toString
();
}
/**
* Check if a file starts with a given prefix.
*
* @param fileName the complete file name
* @param prefix the prefix
* @return true if it starts with the prefix
*/
public
static
boolean
fileStartsWith
(
String
fileName
,
String
prefix
)
{
return
FilePath
.
get
(
fileName
).
fileStartsWith
(
prefix
);
}
// utility methods =======================================
/**
* Delete a directory or file and all subdirectories and files.
*
* @param path the path
* @param tryOnly whether errors should be ignored
*/
public
static
void
deleteRecursive
(
String
path
,
boolean
tryOnly
)
{
if
(
exists
(
path
))
{
if
(
isDirectory
(
path
))
{
for
(
String
s
:
listFiles
(
path
))
{
deleteRecursive
(
s
,
tryOnly
);
}
}
if
(
tryOnly
)
{
tryDelete
(
path
);
}
else
{
delete
(
path
);
}
}
}
/**
* Create the directory and all required parent directories.
*
* @param dir the directory name
*/
public
static
void
createDirectories
(
String
dir
)
{
if
(
dir
!=
null
)
{
if
(
exists
(
dir
))
{
if
(!
isDirectory
(
dir
))
{
DbException
.
get
(
ErrorCode
.
FILE_CREATION_FAILED_1
,
"Could not create directory, "
+
"because a file with the same name already exists: "
+
dir
);
}
}
else
{
String
parent
=
getParent
(
dir
);
createDirectories
(
parent
);
createDirectory
(
dir
);
}
}
}
/**
* Copy a file from one directory to another, or to another file.
*
* @param original the original file name
* @param copy the file name of the copy
*/
public
static
void
copy
(
String
original
,
String
copy
)
throws
IOException
{
InputStream
in
=
newInputStream
(
original
);
OutputStream
out
=
newOutputStream
(
copy
,
false
);
IOUtils
.
copyAndClose
(
in
,
out
);
}
/**
* Try to delete a file (ignore errors).
*
* @param fileName the file name
* @return true if it worked
*/
public
static
boolean
tryDelete
(
String
fileName
)
{
try
{
FilePath
.
get
(
fileName
).
delete
();
return
true
;
}
catch
(
Exception
e
)
{
return
false
;
}
}
/**
* Create a new temporary file.
*
* @param prefix the prefix of the file name (including directory name if
* required)
* @param suffix the suffix
* @param deleteOnExit if the file should be deleted when the virtual
* machine exists
* @param inTempDir if the file should be stored in the temporary directory
* @return the name of the created file
*/
public
static
String
createTempFile
(
String
prefix
,
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
return
FilePath
.
get
(
prefix
).
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
).
toString
();
}
}
h2/src/main/org/h2/util/IOUtils.java
浏览文件 @
ab2f646c
...
@@ -11,7 +11,6 @@ import java.io.BufferedWriter;
...
@@ -11,7 +11,6 @@ import java.io.BufferedWriter;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.EOFException
;
import
java.io.EOFException
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.InputStreamReader
;
...
@@ -449,32 +448,6 @@ public class IOUtils {
...
@@ -449,32 +448,6 @@ public class IOUtils {
}
}
}
}
/**
* Create the directory and all parent directories if required.
*
* @param directory the directory
* @throws IOException
*/
public
static
void
mkdirs
(
File
directory
)
throws
IOException
{
int
todo
;
// loop, to deal with race conditions (if another thread creates or
// deletes the same directory at the same time).
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
if
(
directory
.
exists
())
{
if
(
directory
.
isDirectory
())
{
return
;
}
throw
new
IOException
(
"Could not create directory, "
+
"because a file with the same name already exists: "
+
directory
.
getAbsolutePath
());
}
if
(
directory
.
mkdirs
())
{
return
;
}
}
throw
new
IOException
(
"Could not create directory: "
+
directory
.
getAbsolutePath
());
}
/**
/**
* Trace input or output operations if enabled.
* Trace input or output operations if enabled.
*
*
...
...
h2/src/main/org/h2/util/SourceCompiler.java
浏览文件 @
ab2f646c
...
@@ -139,11 +139,7 @@ public class SourceCompiler {
...
@@ -139,11 +139,7 @@ public class SourceCompiler {
File
dir
=
new
File
(
compileDir
);
File
dir
=
new
File
(
compileDir
);
if
(
packageName
!=
null
)
{
if
(
packageName
!=
null
)
{
dir
=
new
File
(
dir
,
packageName
.
replace
(
'.'
,
'/'
));
dir
=
new
File
(
dir
,
packageName
.
replace
(
'.'
,
'/'
));
try
{
FileUtils
.
createDirectories
(
dir
.
getAbsolutePath
());
IOUtils
.
mkdirs
(
dir
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
compileDir
);
}
}
}
File
javaFile
=
new
File
(
dir
,
className
+
".java"
);
File
javaFile
=
new
File
(
dir
,
className
+
".java"
);
File
classFile
=
new
File
(
dir
,
className
+
".class"
);
File
classFile
=
new
File
(
dir
,
className
+
".class"
);
...
...
h2/src/test/org/h2/test/db/TestLinkedTable.java
浏览文件 @
ab2f646c
...
@@ -637,7 +637,7 @@ public class TestLinkedTable extends TestBase {
...
@@ -637,7 +637,7 @@ public class TestLinkedTable extends TestBase {
String
name
=
FileUtils
.
getName
(
file
);
String
name
=
FileUtils
.
getName
(
file
);
if
((
name
.
startsWith
(
"testLinkedTableInReadOnlyDb"
))
&&
(!
name
.
endsWith
(
".trace.db"
)))
{
if
((
name
.
startsWith
(
"testLinkedTableInReadOnlyDb"
))
&&
(!
name
.
endsWith
(
".trace.db"
)))
{
FileUtils
.
setReadOnly
(
file
);
FileUtils
.
setReadOnly
(
file
);
boolean
isReadOnly
=
FileUtils
.
isReadOnly
(
file
);
boolean
isReadOnly
=
!
FileUtils
.
canWrite
(
file
);
if
(!
isReadOnly
)
{
if
(!
isReadOnly
)
{
fail
(
"File "
+
file
+
" is not read only. Can't test it."
);
fail
(
"File "
+
file
+
" is not read only. Can't test it."
);
}
}
...
...
h2/src/test/org/h2/test/db/TestLob.java
浏览文件 @
ab2f646c
...
@@ -440,7 +440,7 @@ public class TestLob extends TestBase {
...
@@ -440,7 +440,7 @@ public class TestLob extends TestBase {
private
void
testTempFilesDeleted
()
throws
Exception
{
private
void
testTempFilesDeleted
()
throws
Exception
{
String
[]
list
;
String
[]
list
;
FileUtils
.
deleteRecursive
(
TEMP_DIR
,
true
);
FileUtils
.
deleteRecursive
(
TEMP_DIR
,
true
);
IOUtils
.
mkdirs
(
new
File
(
TEMP_DIR
)
);
FileUtils
.
createDirectories
(
TEMP_DIR
);
list
=
FileUtils
.
listFiles
(
TEMP_DIR
);
list
=
FileUtils
.
listFiles
(
TEMP_DIR
);
if
(
list
.
length
>
0
)
{
if
(
list
.
length
>
0
)
{
fail
(
"Unexpected temp file: "
+
list
[
0
]);
fail
(
"Unexpected temp file: "
+
list
[
0
]);
...
...
h2/src/test/org/h2/test/unit/FileSystemDatabase.java
浏览文件 @
ab2f646c
...
@@ -170,10 +170,6 @@ public class FileSystemDatabase extends FileSystem {
...
@@ -170,10 +170,6 @@ public class FileSystemDatabase extends FileSystem {
return
new
RuntimeException
(
e
.
toString
(),
e
);
return
new
RuntimeException
(
e
.
toString
(),
e
);
}
}
public
boolean
canWrite
(
String
fileName
)
{
return
true
;
}
public
void
createDirectory
(
String
directoryName
)
{
public
void
createDirectory
(
String
directoryName
)
{
directoryName
=
unwrap
(
directoryName
);
directoryName
=
unwrap
(
directoryName
);
try
{
try
{
...
@@ -272,8 +268,8 @@ public class FileSystemDatabase extends FileSystem {
...
@@ -272,8 +268,8 @@ public class FileSystemDatabase extends FileSystem {
}
}
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
public
boolean
canWrite
(
String
fileName
)
{
return
fals
e
;
return
tru
e
;
}
}
public
boolean
setReadOnly
(
String
fileName
)
{
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
h2/src/test/org/h2/test/unit/TestFilePath.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
unit
;
import
java.io.EOFException
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.RandomAccessFile
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.List
;
import
java.util.Random
;
import
org.h2.dev.fs.FilePathCrypt
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FileSystemMemory
;
import
org.h2.store.fs.FileUtils2
;
import
org.h2.test.TestBase
;
import
org.h2.test.utils.DebugFilePath
;
import
org.h2.tools.Backup
;
import
org.h2.tools.DeleteDbFiles
;
/**
* Tests various file system.
*/
public
class
TestFilePath
extends
TestBase
{
/**
* Run just this test.
*
* @param a ignored
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
TestBase
test
=
TestBase
.
createCaller
().
init
();
// test.config.traceTest = true;
test
.
test
();
}
public
void
test
()
throws
Exception
{
testMemFsDir
();
testClasspath
();
FilePathCrypt
.
register
();
DebugFilePath
.
register
().
setTrace
(
true
);
testFileSystem
(
"crypt:aes:x:"
+
getBaseDir
()
+
"/fs"
);
testSimpleExpandTruncateSize
();
testSplitDatabaseInZip
();
testDatabaseInMemFileSys
();
testDatabaseInJar
();
// set default part size to 1 << 10
String
f
=
"split:10:"
+
getBaseDir
()
+
"/fs"
;
FileUtils2
.
getCanonicalPath
(
f
);
testFileSystem
(
getBaseDir
()
+
"/fs"
);
testFileSystem
(
"memFS:"
);
testFileSystem
(
"memLZF:"
);
testUserHome
();
try
{
FilePathCrypt
.
register
();
testFileSystem
(
"crypt:aes:x:"
+
getBaseDir
()
+
"/fs"
);
testFileSystem
(
"nio:"
+
getBaseDir
()
+
"/fs"
);
testFileSystem
(
"nioMapped:"
+
getBaseDir
()
+
"/fs"
);
if
(!
config
.
splitFileSystem
)
{
testFileSystem
(
"split:"
+
getBaseDir
()
+
"/fs"
);
testFileSystem
(
"split:nioMapped:"
+
getBaseDir
()
+
"/fs"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
e
;
}
catch
(
Error
e
)
{
e
.
printStackTrace
();
throw
e
;
}
finally
{
FileUtils2
.
delete
(
getBaseDir
()
+
"/fs"
);
}
}
private
void
testMemFsDir
()
throws
IOException
{
FileUtils2
.
newOutputStream
(
"memFS:data/test/a.txt"
,
false
).
close
();
String
[]
list
=
FileUtils2
.
listFiles
(
"memFS:data/test"
);
assertEquals
(
1
,
list
.
length
);
FileUtils2
.
deleteRecursive
(
"memFS:"
,
false
);
}
private
void
testClasspath
()
throws
IOException
{
String
resource
=
"org/h2/test/testSimple.in.txt"
;
InputStream
in
;
in
=
getClass
().
getResourceAsStream
(
"/"
+
resource
);
assertTrue
(
in
!=
null
);
in
.
close
();
in
=
getClass
().
getClassLoader
().
getResourceAsStream
(
resource
);
assertTrue
(
in
!=
null
);
in
.
close
();
in
=
FileUtils2
.
newInputStream
(
"classpath:"
+
resource
);
assertTrue
(
in
!=
null
);
in
.
close
();
in
=
FileUtils2
.
newInputStream
(
"classpath:/"
+
resource
);
assertTrue
(
in
!=
null
);
in
.
close
();
}
private
void
testSimpleExpandTruncateSize
()
throws
Exception
{
String
f
=
"memFS:"
+
getBaseDir
()
+
"/fs/test.data"
;
FileUtils2
.
createDirectories
(
"memFS:"
+
getBaseDir
()
+
"/fs"
);
FileObject
o
=
FileUtils2
.
openFileObject
(
f
,
"rw"
);
o
.
position
(
4000
);
o
.
write
(
new
byte
[
1
],
0
,
1
);
o
.
tryLock
();
o
.
truncate
(
0
);
o
.
releaseLock
();
o
.
close
();
}
private
void
testSplitDatabaseInZip
()
throws
SQLException
{
String
dir
=
getBaseDir
()
+
"/fs"
;
FileUtils2
.
deleteRecursive
(
dir
,
false
);
Connection
conn
;
Statement
stat
;
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:split:18:"
+
dir
+
"/test"
);
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table test(id int primary key, name varchar) "
+
"as select x, space(10000) from system_range(1, 100)"
);
stat
.
execute
(
"shutdown defrag"
);
conn
.
close
();
Backup
.
execute
(
dir
+
"/test.zip"
,
dir
,
""
,
true
);
DeleteDbFiles
.
execute
(
"split:"
+
dir
,
"test"
,
true
);
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:split:zip:"
+
dir
+
"/test.zip!/test"
);
conn
.
createStatement
().
execute
(
"select * from test where id=1"
);
conn
.
close
();
FileUtils2
.
deleteRecursive
(
dir
,
false
);
}
private
void
testDatabaseInMemFileSys
()
throws
SQLException
{
org
.
h2
.
Driver
.
load
();
deleteDb
(
"fsMem"
);
String
url
=
"jdbc:h2:"
+
getBaseDir
()
+
"/fsMem"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
"sa"
);
conn
.
createStatement
().
execute
(
"CREATE TABLE TEST AS SELECT * FROM DUAL"
);
conn
.
createStatement
().
execute
(
"BACKUP TO '"
+
getBaseDir
()
+
"/fsMem.zip'"
);
conn
.
close
();
org
.
h2
.
tools
.
Restore
.
main
(
"-file"
,
getBaseDir
()
+
"/fsMem.zip"
,
"-dir"
,
"memFS:"
);
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:memFS:fsMem"
,
"sa"
,
"sa"
);
ResultSet
rs
=
conn
.
createStatement
().
executeQuery
(
"SELECT * FROM TEST"
);
rs
.
close
();
conn
.
close
();
deleteDb
(
"fsMem"
);
FileUtils2
.
delete
(
getBaseDir
()
+
"/fsMem.zip"
);
}
private
void
testDatabaseInJar
()
throws
SQLException
{
if
(
getBaseDir
().
indexOf
(
':'
)
>
0
)
{
return
;
}
if
(
config
.
networked
)
{
return
;
}
org
.
h2
.
Driver
.
load
();
String
url
=
"jdbc:h2:"
+
getBaseDir
()
+
"/fsJar"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
"sa"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table test(id int primary key, name varchar, b blob, c clob)"
);
stat
.
execute
(
"insert into test values(1, 'Hello', SECURE_RAND(2000), space(2000))"
);
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"select * from test"
);
rs
.
next
();
byte
[]
b1
=
rs
.
getBytes
(
3
);
String
s1
=
rs
.
getString
(
4
);
conn
.
close
();
conn
=
DriverManager
.
getConnection
(
url
,
"sa"
,
"sa"
);
stat
=
conn
.
createStatement
();
stat
.
execute
(
"backup to '"
+
getBaseDir
()
+
"/fsJar.zip'"
);
conn
.
close
();
deleteDb
(
"fsJar"
);
for
(
String
f
:
FileUtils2
.
listFiles
(
"zip:"
+
getBaseDir
()
+
"/fsJar.zip"
))
{
assertTrue
(
FileUtils2
.
isAbsolute
(
f
));
assertTrue
(!
FileUtils2
.
isDirectory
(
f
));
assertTrue
(
FileUtils2
.
size
(
f
)
>
0
);
assertTrue
(
f
.
endsWith
(
FileUtils2
.
getName
(
f
)));
}
String
urlJar
=
"jdbc:h2:zip:"
+
getBaseDir
()
+
"/fsJar.zip!/fsJar"
;
conn
=
DriverManager
.
getConnection
(
urlJar
,
"sa"
,
"sa"
);
stat
=
conn
.
createStatement
();
rs
=
stat
.
executeQuery
(
"select * from test"
);
rs
.
next
();
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
"Hello"
,
rs
.
getString
(
2
));
byte
[]
b2
=
rs
.
getBytes
(
3
);
String
s2
=
rs
.
getString
(
4
);
assertEquals
(
2000
,
b2
.
length
);
assertEquals
(
2000
,
s2
.
length
());
assertEquals
(
b1
,
b2
);
assertEquals
(
s1
,
s2
);
assertFalse
(
rs
.
next
());
conn
.
close
();
FileUtils2
.
delete
(
getBaseDir
()
+
"/fsJar.zip"
);
}
private
void
testUserHome
()
{
String
fileName
=
FileUtils2
.
getCanonicalPath
(
"~/test"
);
String
userDir
=
System
.
getProperty
(
"user.home"
);
assertTrue
(
fileName
.
startsWith
(
userDir
));
}
private
void
testFileSystem
(
String
fsBase
)
throws
Exception
{
testSimple
(
fsBase
);
testTempFile
(
fsBase
);
testRandomAccess
(
fsBase
);
}
private
void
testSimple
(
final
String
fsBase
)
throws
Exception
{
long
time
=
System
.
currentTimeMillis
();
for
(
String
s
:
FileUtils2
.
listFiles
(
fsBase
))
{
FileUtils2
.
delete
(
s
);
}
FileUtils2
.
createDirectories
(
fsBase
+
"/test"
);
FileUtils2
.
delete
(
fsBase
+
"/test"
);
FileUtils2
.
delete
(
fsBase
+
"/test2"
);
assertTrue
(
FileUtils2
.
createFile
(
fsBase
+
"/test"
));
List
<
FilePath
>
p
=
FilePath
.
get
(
fsBase
).
listFiles
();
assertEquals
(
1
,
p
.
size
());
String
can
=
FilePath
.
get
(
fsBase
+
"/test"
).
getCanonicalPath
().
toString
();
assertEquals
(
can
,
p
.
get
(
0
).
toString
());
assertTrue
(
FileUtils2
.
canWrite
(
fsBase
+
"/test"
));
FileObject
fo
=
FileUtils2
.
openFileObject
(
fsBase
+
"/test"
,
"rw"
);
byte
[]
buffer
=
new
byte
[
10000
];
Random
random
=
new
Random
(
1
);
random
.
nextBytes
(
buffer
);
fo
.
write
(
buffer
,
0
,
10000
);
assertEquals
(
10000
,
fo
.
size
());
fo
.
position
(
20000
);
assertEquals
(
20000
,
fo
.
position
());
assertThrows
(
EOFException
.
class
,
fo
).
readFully
(
buffer
,
0
,
1
);
String
path
=
fsBase
+
"/test"
;
assertEquals
(
"test"
,
FileUtils2
.
getName
(
path
));
can
=
FilePath
.
get
(
fsBase
).
getCanonicalPath
().
toString
();
String
can2
=
FileUtils2
.
getCanonicalPath
(
FileUtils2
.
getParent
(
path
));
assertEquals
(
can
,
can2
);
fo
.
tryLock
();
fo
.
releaseLock
();
assertEquals
(
10000
,
fo
.
size
());
fo
.
close
();
assertEquals
(
10000
,
FileUtils2
.
size
(
fsBase
+
"/test"
));
fo
=
FileUtils2
.
openFileObject
(
fsBase
+
"/test"
,
"r"
);
byte
[]
test
=
new
byte
[
10000
];
fo
.
readFully
(
test
,
0
,
10000
);
assertEquals
(
buffer
,
test
);
assertThrows
(
IOException
.
class
,
fo
).
write
(
test
,
0
,
10
);
assertThrows
(
IOException
.
class
,
fo
).
truncate
(
10
);
fo
.
close
();
long
lastMod
=
FileUtils2
.
lastModified
(
fsBase
+
"/test"
);
if
(
lastMod
<
time
-
1999
)
{
// at most 2 seconds difference
assertEquals
(
time
,
lastMod
);
}
assertEquals
(
10000
,
FileUtils2
.
size
(
fsBase
+
"/test"
));
String
[]
list
=
FileUtils2
.
listFiles
(
fsBase
);
assertEquals
(
1
,
list
.
length
);
assertTrue
(
list
[
0
].
endsWith
(
"test"
));
FileUtils2
.
copy
(
fsBase
+
"/test"
,
fsBase
+
"/test3"
);
FileUtils2
.
moveTo
(
fsBase
+
"/test3"
,
fsBase
+
"/test2"
);
assertTrue
(!
FileUtils2
.
exists
(
fsBase
+
"/test3"
));
assertTrue
(
FileUtils2
.
exists
(
fsBase
+
"/test2"
));
assertEquals
(
10000
,
FileUtils2
.
size
(
fsBase
+
"/test2"
));
byte
[]
buffer2
=
new
byte
[
10000
];
InputStream
in
=
FileUtils2
.
newInputStream
(
fsBase
+
"/test2"
);
int
pos
=
0
;
while
(
true
)
{
int
l
=
in
.
read
(
buffer2
,
pos
,
Math
.
min
(
10000
-
pos
,
1000
));
if
(
l
<=
0
)
{
break
;
}
pos
+=
l
;
}
in
.
close
();
assertEquals
(
10000
,
pos
);
assertEquals
(
buffer
,
buffer2
);
assertTrue
(
FileUtils2
.
tryDelete
(
fsBase
+
"/test2"
));
FileUtils2
.
delete
(
fsBase
+
"/test"
);
if
(
fsBase
.
indexOf
(
FileSystemMemory
.
PREFIX
)
<
0
&&
fsBase
.
indexOf
(
FileSystemMemory
.
PREFIX_LZF
)
<
0
)
{
FileUtils2
.
createDirectories
(
fsBase
+
"/testDir"
);
assertTrue
(
FileUtils2
.
isDirectory
(
fsBase
+
"/testDir"
));
if
(!
fsBase
.
startsWith
(
"jdbc:"
))
{
FileUtils2
.
deleteRecursive
(
fsBase
+
"/testDir"
,
false
);
assertTrue
(!
FileUtils2
.
exists
(
fsBase
+
"/testDir"
));
}
}
}
private
void
testRandomAccess
(
String
fsBase
)
throws
Exception
{
testRandomAccess
(
fsBase
,
1
);
}
private
void
testRandomAccess
(
String
fsBase
,
int
seed
)
throws
Exception
{
StringBuilder
buff
=
new
StringBuilder
();
String
s
=
FileUtils2
.
createTempFile
(
fsBase
+
"/tmp"
,
".tmp"
,
false
,
false
);
File
file
=
new
File
(
TestBase
.
BASE_TEST_DIR
+
"/tmp"
);
file
.
getParentFile
().
mkdirs
();
file
.
delete
();
RandomAccessFile
ra
=
new
RandomAccessFile
(
file
,
"rw"
);
FileUtils2
.
delete
(
s
);
FileObject
f
=
FileUtils2
.
openFileObject
(
s
,
"rw"
);
assertThrows
(
EOFException
.
class
,
f
).
readFully
(
new
byte
[
1
],
0
,
1
);
f
.
sync
();
Random
random
=
new
Random
(
seed
);
int
size
=
getSize
(
100
,
500
);
try
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
trace
(
"op "
+
i
);
int
pos
=
random
.
nextInt
(
10000
);
switch
(
random
.
nextInt
(
7
))
{
case
0
:
{
pos
=
(
int
)
Math
.
min
(
pos
,
ra
.
length
());
trace
(
"seek "
+
pos
);
buff
.
append
(
"seek "
+
pos
+
"\n"
);
f
.
position
(
pos
);
ra
.
seek
(
pos
);
break
;
}
case
1
:
{
byte
[]
buffer
=
new
byte
[
random
.
nextInt
(
1000
)];
random
.
nextBytes
(
buffer
);
trace
(
"write "
+
buffer
.
length
);
buff
.
append
(
"write "
+
buffer
.
length
+
"\n"
);
f
.
write
(
buffer
,
0
,
buffer
.
length
);
ra
.
write
(
buffer
,
0
,
buffer
.
length
);
break
;
}
case
2
:
{
trace
(
"truncate "
+
pos
);
f
.
truncate
(
pos
);
if
(
pos
<
ra
.
getFilePointer
())
{
// truncate is supposed to have no effect if the
// position is larger than the current position
ra
.
setLength
(
pos
);
}
assertEquals
(
ra
.
getFilePointer
(),
f
.
position
());
buff
.
append
(
"truncate "
+
pos
+
"\n"
);
break
;
}
case
3
:
{
int
len
=
random
.
nextInt
(
1000
);
len
=
(
int
)
Math
.
min
(
len
,
ra
.
length
()
-
ra
.
getFilePointer
());
byte
[]
b1
=
new
byte
[
len
];
byte
[]
b2
=
new
byte
[
len
];
trace
(
"readFully "
+
len
);
ra
.
readFully
(
b1
,
0
,
len
);
f
.
readFully
(
b2
,
0
,
len
);
buff
.
append
(
"readFully "
+
len
+
"\n"
);
assertEquals
(
b1
,
b2
);
break
;
}
case
4
:
{
trace
(
"getFilePointer"
);
buff
.
append
(
"getFilePointer\n"
);
assertEquals
(
ra
.
getFilePointer
(),
f
.
position
());
break
;
}
case
5
:
{
trace
(
"length "
+
ra
.
length
());
buff
.
append
(
"length "
+
ra
.
length
()
+
"\n"
);
assertEquals
(
ra
.
length
(),
f
.
size
());
break
;
}
case
6
:
{
trace
(
"reopen"
);
buff
.
append
(
"reopen\n"
);
f
.
close
();
ra
.
close
();
ra
=
new
RandomAccessFile
(
file
,
"rw"
);
f
=
FileUtils2
.
openFileObject
(
s
,
"rw"
);
assertEquals
(
ra
.
length
(),
f
.
size
());
break
;
}
default
:
}
}
}
catch
(
Throwable
e
)
{
e
.
printStackTrace
();
fail
(
"Exception: "
+
e
+
"\n"
+
buff
.
toString
());
}
finally
{
f
.
close
();
ra
.
close
();
file
.
delete
();
FileUtils2
.
delete
(
s
);
}
}
private
void
testTempFile
(
String
fsBase
)
throws
Exception
{
int
len
=
10000
;
String
s
=
FileUtils2
.
createTempFile
(
fsBase
+
"/tmp"
,
".tmp"
,
false
,
false
);
OutputStream
out
=
FileUtils2
.
newOutputStream
(
s
,
false
);
byte
[]
buffer
=
new
byte
[
len
];
out
.
write
(
buffer
);
out
.
close
();
out
=
FileUtils2
.
newOutputStream
(
s
,
true
);
out
.
write
(
1
);
out
.
close
();
InputStream
in
=
FileUtils2
.
newInputStream
(
s
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
assertEquals
(
0
,
in
.
read
());
}
assertEquals
(
1
,
in
.
read
());
assertEquals
(-
1
,
in
.
read
());
in
.
close
();
out
.
close
();
FileUtils2
.
delete
(
s
);
}
}
h2/src/test/org/h2/test/utils/DebugFile.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
utils
;
import
java.io.IOException
;
import
org.h2.store.fs.FileObject
;
/**
* A debugging file that logs all operations.
*/
public
class
DebugFile
implements
FileObject
{
private
final
DebugFilePath
fs
;
private
final
FileObject
file
;
private
final
String
name
;
DebugFile
(
DebugFilePath
fs
,
FileObject
file
,
String
name
)
{
this
.
fs
=
fs
;
this
.
file
=
file
;
this
.
name
=
fs
.
getScheme
()
+
":"
+
name
;
}
public
void
close
()
throws
IOException
{
debug
(
"close"
);
file
.
close
();
}
public
long
position
()
throws
IOException
{
debug
(
"getFilePointer"
);
return
file
.
position
();
}
public
long
size
()
throws
IOException
{
debug
(
"length"
);
return
file
.
size
();
}
public
void
readFully
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
debug
(
"readFully"
,
file
.
position
(),
off
,
len
);
file
.
readFully
(
b
,
off
,
len
);
}
public
void
position
(
long
pos
)
throws
IOException
{
debug
(
"seek"
,
pos
);
file
.
position
(
pos
);
}
public
void
truncate
(
long
newLength
)
throws
IOException
{
checkPowerOff
();
debug
(
"truncate"
,
newLength
);
file
.
truncate
(
newLength
);
}
public
void
sync
()
throws
IOException
{
debug
(
"sync"
);
file
.
sync
();
}
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
checkPowerOff
();
debug
(
"write"
,
file
.
position
(),
off
,
len
);
file
.
write
(
b
,
off
,
len
);
}
private
void
debug
(
String
method
,
Object
...
params
)
{
fs
.
trace
(
name
,
method
,
params
);
}
private
void
checkPowerOff
()
throws
IOException
{
try
{
fs
.
checkPowerOff
();
}
catch
(
IOException
e
)
{
try
{
file
.
close
();
}
catch
(
IOException
e2
)
{
// ignore
}
throw
e
;
}
}
public
boolean
tryLock
()
{
debug
(
"tryLock"
);
return
file
.
tryLock
();
}
public
void
releaseLock
()
{
debug
(
"releaseLock"
);
file
.
releaseLock
();
}
}
\ No newline at end of file
h2/src/test/org/h2/test/utils/DebugFilePath.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
utils
;
import
java.io.FilterInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.List
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathWrapper
;
/**
* A debugging file system that logs all operations.
*/
public
class
DebugFilePath
extends
FilePathWrapper
{
private
static
final
DebugFilePath
INSTANCE
=
new
DebugFilePath
();
private
static
final
IOException
POWER_OFF
=
new
IOException
(
"Simulated power failure"
);
private
int
powerOffCount
;
private
boolean
trace
;
/**
* Register the file system.
*
* @return the instance
*/
public
static
DebugFilePath
register
()
{
FilePath
.
register
(
INSTANCE
);
return
INSTANCE
;
}
/**
* Check if the simulated power failure occurred.
* This call will decrement the countdown.
*
* @throws IOException if the simulated power failure occurred
*/
void
checkPowerOff
()
throws
IOException
{
if
(
powerOffCount
==
0
)
{
return
;
}
if
(
powerOffCount
>
1
)
{
powerOffCount
--;
return
;
}
powerOffCount
=
-
1
;
// throw new IOException("Simulated power failure");
throw
POWER_OFF
;
}
public
void
createDirectory
()
{
trace
(
name
,
"createDirectory"
);
super
.
createDirectory
();
}
public
boolean
createFile
()
{
trace
(
name
,
"createFile"
);
return
super
.
createFile
();
}
public
void
delete
()
{
trace
(
name
,
"fileName"
);
super
.
delete
();
}
public
boolean
exists
()
{
trace
(
name
,
"exists"
);
return
super
.
exists
();
}
// public boolean fileStartsWith(String fileName, String prefix) {
// trace(fileName, "fileStartsWith", unwrap(prefix));
// return super.fileStartsWith(fileName, prefix);
// }
public
String
getName
()
{
trace
(
name
,
"getName"
);
return
super
.
getName
();
}
public
long
lastModified
()
{
trace
(
name
,
"lastModified"
);
return
super
.
lastModified
();
}
public
FilePath
getParent
()
{
trace
(
name
,
"getParent"
);
return
super
.
getParent
();
}
public
boolean
isAbsolute
()
{
trace
(
name
,
"isAbsolute"
);
return
super
.
isAbsolute
();
}
public
boolean
isDirectory
()
{
trace
(
name
,
"isDirectory"
);
return
super
.
isDirectory
();
}
public
boolean
canWrite
()
{
trace
(
name
,
"canWrite"
);
return
super
.
canWrite
();
}
public
boolean
setReadOnly
()
{
trace
(
name
,
"setReadOnly"
);
return
super
.
setReadOnly
();
}
public
long
size
()
{
trace
(
name
,
"size"
);
return
super
.
size
();
}
public
List
<
FilePath
>
listFiles
()
{
trace
(
name
,
"listFiles"
);
return
super
.
listFiles
();
}
public
FilePath
getCanonicalPath
()
{
trace
(
name
,
"getCanonicalPath"
);
return
super
.
getCanonicalPath
();
}
public
InputStream
newInputStream
()
throws
IOException
{
trace
(
name
,
"newInputStream"
);
InputStream
in
=
super
.
newInputStream
();
if
(!
trace
)
{
return
in
;
}
final
String
fileName
=
name
;
return
new
FilterInputStream
(
in
)
{
public
int
read
(
byte
[]
b
)
throws
IOException
{
trace
(
fileName
,
"in.read(b)"
);
return
super
.
read
(
b
);
}
public
int
read
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
trace
(
fileName
,
"in.read(b)"
,
"in.read(b, "
+
off
+
", "
+
len
+
")"
);
return
super
.
read
(
b
,
off
,
len
);
}
public
long
skip
(
long
n
)
throws
IOException
{
trace
(
fileName
,
"in.read(b)"
,
"in.skip("
+
n
+
")"
);
return
super
.
skip
(
n
);
}
};
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
trace
(
name
,
"openFileObject"
,
mode
);
return
new
DebugFile
(
this
,
super
.
openFileObject
(
mode
),
name
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
trace
(
name
,
"newOutputStream"
,
append
);
return
super
.
newOutputStream
(
append
);
}
public
void
moveTo
(
FilePath
newName
)
{
trace
(
name
,
"moveTo"
,
unwrap
(((
DebugFilePath
)
newName
).
name
));
super
.
moveTo
(
newName
);
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
trace
(
name
,
"createTempFile"
,
suffix
,
deleteOnExit
,
inTempDir
);
return
super
.
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
);
}
/**
* Print a debug message.
*
* @param fileName the (wrapped) file name
* @param method the method name
* @param params parameters if any
*/
void
trace
(
String
fileName
,
String
method
,
Object
...
params
)
{
if
(
trace
)
{
StringBuilder
buff
=
new
StringBuilder
(
" "
);
buff
.
append
(
unwrap
(
fileName
)).
append
(
' '
).
append
(
method
);
for
(
Object
s
:
params
)
{
buff
.
append
(
' '
).
append
(
s
);
}
System
.
out
.
println
(
buff
);
}
}
public
void
setPowerOffCount
(
int
count
)
{
this
.
powerOffCount
=
count
;
}
public
int
getPowerOffCount
()
{
return
powerOffCount
;
}
public
boolean
isTrace
()
{
return
trace
;
}
public
void
setTrace
(
boolean
trace
)
{
this
.
trace
=
trace
;
}
public
String
getScheme
()
{
return
"debug"
;
}
}
h2/src/test/org/h2/test/utils/DebugFileSystem.java
浏览文件 @
ab2f646c
...
@@ -60,11 +60,6 @@ public class DebugFileSystem extends FileSystemWrapper {
...
@@ -60,11 +60,6 @@ public class DebugFileSystem extends FileSystemWrapper {
throw
POWER_OFF
;
throw
POWER_OFF
;
}
}
public
boolean
canWrite
(
String
fileName
)
{
trace
(
fileName
,
"canWrite"
);
return
super
.
canWrite
(
fileName
);
}
public
void
createDirectory
(
String
directoryName
)
{
public
void
createDirectory
(
String
directoryName
)
{
trace
(
directoryName
,
"createDirectory"
);
trace
(
directoryName
,
"createDirectory"
);
super
.
createDirectory
(
directoryName
);
super
.
createDirectory
(
directoryName
);
...
@@ -121,9 +116,9 @@ public class DebugFileSystem extends FileSystemWrapper {
...
@@ -121,9 +116,9 @@ public class DebugFileSystem extends FileSystemWrapper {
return
super
.
isDirectory
(
fileName
);
return
super
.
isDirectory
(
fileName
);
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
public
boolean
canWrite
(
String
fileName
)
{
trace
(
fileName
,
"
isReadOnly
"
);
trace
(
fileName
,
"
canWrite
"
);
return
super
.
isReadOnly
(
fileName
);
return
super
.
canWrite
(
fileName
);
}
}
public
boolean
setReadOnly
(
String
fileName
)
{
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
h2/src/tools/org/h2/dev/fs/FilePathCrypt.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
dev
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
org.h2.message.DbException
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FileObjectInputStream
;
import
org.h2.store.fs.FileObjectOutputStream
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathWrapper
;
import
org.h2.store.fs.FileUtils
;
/**
* A file system that encrypts the contents of the files.
*/
public
class
FilePathCrypt
extends
FilePathWrapper
{
public
static
void
register
()
{
FilePath
.
register
(
new
FilePathCrypt
());
}
protected
String
getPrefix
()
{
String
[]
parsed
=
parse
(
name
);
return
getScheme
()
+
":"
+
parsed
[
0
]
+
":"
+
parsed
[
1
]
+
":"
;
}
public
FilePath
unwrap
(
String
fileName
)
{
return
FilePath
.
get
(
parse
(
fileName
)[
2
]);
}
public
long
size
()
{
long
len
=
getBase
().
size
();
return
Math
.
max
(
0
,
len
-
FileObjectCrypt
.
HEADER_LENGTH
-
FileObjectCrypt
.
BLOCK_SIZE
);
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
String
[]
parsed
=
parse
(
name
);
FileObject
file
=
FileUtils
.
openFileObject
(
parsed
[
2
],
mode
);
return
new
FileObjectCrypt
(
name
,
parsed
[
0
],
parsed
[
1
],
file
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
FileObject
file
=
openFileObject
(
"rw"
);
return
new
FileObjectOutputStream
(
file
,
append
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
InputStream
newInputStream
()
{
try
{
FileObject
file
=
openFileObject
(
"r"
);
return
new
FileObjectInputStream
(
file
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
/**
* Split the file name into algorithm, password, and base file name.
*
* @param fileName the file name
* @return an array with algorithm, password, and base file name
*/
private
String
[]
parse
(
String
fileName
)
{
if
(!
fileName
.
startsWith
(
getScheme
()))
{
DbException
.
throwInternalError
(
fileName
+
" doesn't start with "
+
getScheme
());
}
fileName
=
fileName
.
substring
(
getScheme
().
length
()
+
1
);
int
idx
=
fileName
.
indexOf
(
':'
);
String
algorithm
,
password
;
if
(
idx
<
0
)
{
DbException
.
throwInternalError
(
fileName
+
" doesn't contain encryption algorithm and password"
);
}
algorithm
=
fileName
.
substring
(
0
,
idx
);
fileName
=
fileName
.
substring
(
idx
+
1
);
idx
=
fileName
.
indexOf
(
':'
);
if
(
idx
<
0
)
{
DbException
.
throwInternalError
(
fileName
+
" doesn't contain encryption password"
);
}
password
=
fileName
.
substring
(
0
,
idx
);
fileName
=
fileName
.
substring
(
idx
+
1
);
return
new
String
[]
{
algorithm
,
password
,
fileName
};
}
public
String
getScheme
()
{
return
"crypt"
;
}
}
h2/src/tools/org/h2/dev/fs/FilePathZip2.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
dev
.
fs
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipInputStream
;
import
org.h2.engine.Constants
;
import
org.h2.message.DbException
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FileObjectInputStream
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathDisk
;
import
org.h2.store.fs.FileSystemDisk
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.New
;
/**
* This is a read-only file system that allows to access databases stored in a
* .zip or .jar file. The problem of this file system is that data is always
* accessed as a stream. But unlike FileSystemZip, it is possible to stack file
* systems.
*/
public
class
FilePathZip2
extends
FilePath
{
/**
* Register the file system.
*
* @return the instance
*/
public
static
FilePathZip2
register
()
{
FilePathZip2
instance
=
new
FilePathZip2
();
FilePath
.
register
(
instance
);
return
instance
;
}
public
FilePathZip2
getPath
(
String
path
)
{
FilePathZip2
p
=
new
FilePathZip2
();
p
.
name
=
path
;
return
p
;
}
public
void
createDirectory
()
{
// ignore
}
public
boolean
createFile
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
if
(!
inTempDir
)
{
throw
new
IOException
(
"File system is read-only"
);
}
return
new
FilePathDisk
().
getPath
(
name
).
createTempFile
(
suffix
,
deleteOnExit
,
true
);
}
public
void
delete
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
boolean
exists
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipInputStream
file
=
openZip
();
boolean
result
=
false
;
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
if
(
entry
.
getName
().
equals
(
entryName
))
{
result
=
true
;
break
;
}
file
.
closeEntry
();
}
file
.
close
();
return
result
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
// public boolean fileStartsWith(String fileName, String prefix) {
// return fileName.startsWith(prefix);
// }
public
long
lastModified
()
{
return
0
;
}
public
FilePath
getParent
()
{
int
idx
=
name
.
lastIndexOf
(
'/'
);
return
idx
<
0
?
null
:
getPath
(
name
.
substring
(
0
,
idx
));
}
public
boolean
isAbsolute
()
{
return
true
;
}
public
boolean
isDirectory
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipInputStream
file
=
openZip
();
boolean
result
=
false
;
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
String
n
=
entry
.
getName
();
if
(
n
.
equals
(
entryName
))
{
result
=
entry
.
isDirectory
();
break
;
}
else
if
(
n
.
startsWith
(
entryName
))
{
if
(
n
.
length
()
==
entryName
.
length
()
+
1
)
{
if
(
n
.
equals
(
entryName
+
"/"
))
{
result
=
true
;
break
;
}
}
}
file
.
closeEntry
();
}
file
.
close
();
return
result
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
canWrite
()
{
return
false
;
}
public
boolean
setReadOnly
()
{
return
true
;
}
public
long
size
()
{
try
{
String
entryName
=
getEntryName
();
ZipInputStream
file
=
openZip
();
long
result
=
0
;
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
if
(
entry
.
getName
().
equals
(
entryName
))
{
result
=
entry
.
getSize
();
if
(
result
==
-
1
)
{
result
=
0
;
while
(
true
)
{
long
x
=
file
.
skip
(
16
*
Constants
.
IO_BUFFER_SIZE
);
if
(
x
==
0
)
{
break
;
}
result
+=
x
;
}
}
break
;
}
file
.
closeEntry
();
}
file
.
close
();
return
result
;
}
catch
(
IOException
e
)
{
return
0
;
}
}
public
ArrayList
<
FilePath
>
listFiles
()
{
String
path
=
name
;
try
{
if
(
path
.
indexOf
(
'!'
)
<
0
)
{
path
+=
"!"
;
}
if
(!
path
.
endsWith
(
"/"
))
{
path
+=
"/"
;
}
ZipInputStream
file
=
openZip
();
String
dirName
=
getEntryName
();
String
prefix
=
path
.
substring
(
0
,
path
.
length
()
-
dirName
.
length
());
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
String
name
=
entry
.
getName
();
if
(
name
.
startsWith
(
dirName
)
&&
name
.
length
()
>
dirName
.
length
())
{
int
idx
=
name
.
indexOf
(
'/'
,
dirName
.
length
());
if
(
idx
<
0
||
idx
>=
name
.
length
()
-
1
)
{
list
.
add
(
getPath
(
prefix
+
name
));
}
}
file
.
closeEntry
();
}
file
.
close
();
return
list
;
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
"listFiles "
+
path
);
}
}
public
FilePath
getCanonicalPath
()
{
return
this
;
}
public
InputStream
newInputStream
()
throws
IOException
{
FileObject
file
=
openFileObject
(
"r"
);
return
new
FileObjectInputStream
(
file
);
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
throw
new
FileNotFoundException
();
}
ZipInputStream
in
=
openZip
();
while
(
true
)
{
ZipEntry
entry
=
in
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
if
(
entry
.
getName
().
equals
(
entryName
))
{
return
new
FileObjectZip2
(
name
,
entryName
,
in
,
size
());
}
in
.
closeEntry
();
}
in
.
close
();
throw
new
FileNotFoundException
(
name
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
void
moveTo
(
FilePath
newName
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
// public String unwrap(String fileName) {
// if (fileName.startsWith(PREFIX)) {
// fileName = fileName.substring(PREFIX.length());
// }
// int idx = fileName.indexOf('!');
// if (idx >= 0) {
// fileName = fileName.substring(0, idx);
// }
// return FileSystemDisk.expandUserHomeDirectory(fileName);
// }
private
String
getEntryName
()
{
int
idx
=
name
.
indexOf
(
'!'
);
String
fileName
;
if
(
idx
<=
0
)
{
fileName
=
""
;
}
else
{
fileName
=
name
.
substring
(
idx
+
1
);
}
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
if
(
fileName
.
startsWith
(
"/"
))
{
fileName
=
fileName
.
substring
(
1
);
}
return
fileName
;
}
private
ZipInputStream
openZip
()
throws
IOException
{
String
fileName
=
translateFileName
(
name
);
return
new
ZipInputStream
(
FileUtils
.
newInputStream
(
fileName
));
}
private
static
String
translateFileName
(
String
fileName
)
{
if
(
fileName
.
startsWith
(
"zip2:"
))
{
fileName
=
fileName
.
substring
(
"zip2:"
.
length
());
}
int
idx
=
fileName
.
indexOf
(
'!'
);
if
(
idx
>=
0
)
{
fileName
=
fileName
.
substring
(
0
,
idx
);
}
return
FileSystemDisk
.
expandUserHomeDirectory
(
fileName
);
}
public
boolean
fileStartsWith
(
String
prefix
)
{
return
name
.
startsWith
(
prefix
);
}
public
String
getScheme
()
{
return
"zip2"
;
}
}
\ No newline at end of file
h2/src/tools/org/h2/dev/fs/FileShell.java
浏览文件 @
ab2f646c
...
@@ -215,7 +215,7 @@ public class FileShell extends Tool {
...
@@ -215,7 +215,7 @@ public class FileShell extends Tool {
for
(
String
file
:
FileUtils
.
listFiles
(
dir
))
{
for
(
String
file
:
FileUtils
.
listFiles
(
dir
))
{
StringBuilder
buff
=
new
StringBuilder
();
StringBuilder
buff
=
new
StringBuilder
();
buff
.
append
(
FileUtils
.
isDirectory
(
file
)
?
"d"
:
"-"
);
buff
.
append
(
FileUtils
.
isDirectory
(
file
)
?
"d"
:
"-"
);
buff
.
append
(
FileUtils
.
isReadOnly
(
file
)
?
"r-"
:
"rw
"
);
buff
.
append
(
FileUtils
.
canWrite
(
file
)
?
"rw"
:
"r-
"
);
buff
.
append
(
' '
);
buff
.
append
(
' '
);
buff
.
append
(
String
.
format
(
"%10d"
,
FileUtils
.
size
(
file
)));
buff
.
append
(
String
.
format
(
"%10d"
,
FileUtils
.
size
(
file
)));
buff
.
append
(
' '
);
buff
.
append
(
' '
);
...
...
h2/src/tools/org/h2/dev/fs/FileSystemZip2.java
浏览文件 @
ab2f646c
...
@@ -44,10 +44,6 @@ public class FileSystemZip2 extends FileSystem {
...
@@ -44,10 +44,6 @@ public class FileSystemZip2 extends FileSystem {
return
INSTANCE
;
return
INSTANCE
;
}
}
public
boolean
canWrite
(
String
fileName
)
{
return
false
;
}
public
void
createDirectory
(
String
directoryName
)
{
public
void
createDirectory
(
String
directoryName
)
{
// ignore
// ignore
}
}
...
@@ -159,8 +155,8 @@ public class FileSystemZip2 extends FileSystem {
...
@@ -159,8 +155,8 @@ public class FileSystemZip2 extends FileSystem {
}
}
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
public
boolean
canWrite
(
String
fileName
)
{
return
tru
e
;
return
fals
e
;
}
}
public
boolean
setReadOnly
(
String
fileName
)
{
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论