Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ab2f646c
提交
ab2f646c
authored
13 年前
作者:
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
);
...
...
This diff is collapsed.
Click to expand it.
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
;
...
...
This diff is collapsed.
Click to expand it.
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
();
for
(
int
i
=
0
;;
i
++)
{
try
{
file
.
setLength
(
newLength
);
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
;
}
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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
());
}
}
}
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
));
}
}
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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.
*
*
...
...
This diff is collapsed.
Click to expand it.
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
));
...
...
This diff is collapsed.
Click to expand it.
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
}
}
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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,12 +284,20 @@ public class FileUtils {
...
@@ -292,12 +284,20 @@ 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
)
{
if
(
FileUtils
.
exists
(
dir
))
{
if
(!
FileUtils
.
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
=
FileUtils
.
getParent
(
dir
);
String
parent
=
FileUtils
.
getParent
(
dir
);
createDirectories
(
parent
);
createDirectories
(
parent
);
createDirectory
(
dir
);
createDirectory
(
dir
);
}
}
}
}
}
/**
/**
* Copy a file from one directory to another, or to another file.
* Copy a file from one directory to another, or to another file.
...
...
This diff is collapsed.
Click to expand it.
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
();
}
}
This diff is collapsed.
Click to expand it.
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.
*
*
...
...
This diff is collapsed.
Click to expand it.
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"
);
...
...
This diff is collapsed.
Click to expand it.
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."
);
}
}
...
...
This diff is collapsed.
Click to expand 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
]);
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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
);
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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"
;
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
(
' '
);
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论