Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ab2f646c
提交
ab2f646c
authored
9月 16, 2011
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improved compatibility with the Java 7 FileSystem abstraction.
上级
6e710caa
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
33 个修改的文件
包含
3336 行增加
和
122 行删除
+3336
-122
Database.java
h2/src/main/org/h2/engine/Database.java
+2
-3
TraceSystem.java
h2/src/main/org/h2/message/TraceSystem.java
+1
-1
FileObjectDiskMapped.java
h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java
+21
-10
FileObjectRec.java
h2/src/main/org/h2/store/fs/FileObjectRec.java
+73
-0
FilePath.java
h2/src/main/org/h2/store/fs/FilePath.java
+317
-0
FilePathDisk.java
h2/src/main/org/h2/store/fs/FilePathDisk.java
+397
-0
FilePathMem.java
h2/src/main/org/h2/store/fs/FilePathMem.java
+205
-0
FilePathNio.java
h2/src/main/org/h2/store/fs/FilePathNio.java
+38
-0
FilePathNioMapped.java
h2/src/main/org/h2/store/fs/FilePathNioMapped.java
+30
-0
FilePathRec.java
h2/src/main/org/h2/store/fs/FilePathRec.java
+110
-0
FilePathSplit.java
h2/src/main/org/h2/store/fs/FilePathSplit.java
+233
-0
FilePathWrapper.java
h2/src/main/org/h2/store/fs/FilePathWrapper.java
+139
-0
FilePathZip.java
h2/src/main/org/h2/store/fs/FilePathZip.java
+247
-0
FileSystem.java
h2/src/main/org/h2/store/fs/FileSystem.java
+0
-8
FileSystemDisk.java
h2/src/main/org/h2/store/fs/FileSystemDisk.java
+1
-7
FileSystemMemory.java
h2/src/main/org/h2/store/fs/FileSystemMemory.java
+4
-8
FileSystemWrapper.java
h2/src/main/org/h2/store/fs/FileSystemWrapper.java
+2
-6
FileSystemZip.java
h2/src/main/org/h2/store/fs/FileSystemZip.java
+2
-6
FileUtils.java
h2/src/main/org/h2/store/fs/FileUtils.java
+18
-18
FileUtils2.java
h2/src/main/org/h2/store/fs/FileUtils2.java
+343
-0
IOUtils.java
h2/src/main/org/h2/util/IOUtils.java
+0
-27
SourceCompiler.java
h2/src/main/org/h2/util/SourceCompiler.java
+1
-5
TestLinkedTable.java
h2/src/test/org/h2/test/db/TestLinkedTable.java
+1
-1
TestLob.java
h2/src/test/org/h2/test/db/TestLob.java
+1
-1
FileSystemDatabase.java
h2/src/test/org/h2/test/unit/FileSystemDatabase.java
+2
-6
TestFilePath.java
h2/src/test/org/h2/test/unit/TestFilePath.java
+421
-0
DebugFile.java
h2/src/test/org/h2/test/utils/DebugFile.java
+96
-0
DebugFilePath.java
h2/src/test/org/h2/test/utils/DebugFilePath.java
+218
-0
DebugFileSystem.java
h2/src/test/org/h2/test/utils/DebugFileSystem.java
+3
-8
FilePathCrypt.java
h2/src/tools/org/h2/dev/fs/FilePathCrypt.java
+98
-0
FilePathZip2.java
h2/src/tools/org/h2/dev/fs/FilePathZip2.java
+309
-0
FileShell.java
h2/src/tools/org/h2/dev/fs/FileShell.java
+1
-1
FileSystemZip2.java
h2/src/tools/org/h2/dev/fs/FileSystemZip2.java
+2
-6
没有找到文件。
h2/src/main/org/h2/engine/Database.java
浏览文件 @
ab2f646c
...
...
@@ -506,9 +506,8 @@ public class Database implements DataHandler {
throw
DbException
.
get
(
ErrorCode
.
FILE_VERSION_ERROR_1
,
"Old database: "
+
dataFileName
+
" - please convert the database to a SQL script and re-create it."
);
}
if
(
existsPage
&&
FileUtils
.
isReadOnly
(
pageFileName
))
{
// if it is already read-only because ACCESS_MODE_DATA=r
readOnly
=
readOnly
|
FileUtils
.
isReadOnly
(
pageFileName
);
if
(
existsPage
&&
!
FileUtils
.
canWrite
(
pageFileName
))
{
readOnly
=
true
;
}
if
(
readOnly
)
{
traceSystem
=
new
TraceSystem
(
null
);
...
...
h2/src/main/org/h2/message/TraceSystem.java
浏览文件 @
ab2f646c
...
...
@@ -296,7 +296,7 @@ public class TraceSystem implements TraceWriter {
if
(
printWriter
==
null
)
{
try
{
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
// can't be opened
return
false
;
...
...
h2/src/main/org/h2/store/fs/FileObjectDiskMapped.java
浏览文件 @
ab2f646c
...
...
@@ -132,6 +132,10 @@ public class FileObjectDiskMapped implements FileObject {
return
pos
;
}
public
String
toString
()
{
return
FileSystemDiskNioMapped
.
PREFIX
+
name
;
}
public
synchronized
long
size
()
throws
IOException
{
return
file
.
length
();
}
...
...
@@ -161,9 +165,24 @@ public class FileObjectDiskMapped implements FileObject {
if
(
newLength
>=
size
())
{
return
;
}
setFileLength
(
newLength
);
}
public
synchronized
void
setFileLength
(
long
newLength
)
throws
IOException
{
checkFileSizeLimit
(
newLength
);
int
oldPos
=
pos
;
unMap
();
file
.
setLength
(
newLength
);
for
(
int
i
=
0
;;
i
++)
{
try
{
file
.
setLength
(
newLength
);
break
;
}
catch
(
IOException
e
)
{
if
(
i
>
16
||
e
.
toString
().
indexOf
(
"user-mapped section open"
)
<
0
)
{
throw
e
;
}
}
System
.
gc
();
}
reMap
();
pos
=
(
int
)
Math
.
min
(
newLength
,
oldPos
);
}
...
...
@@ -176,11 +195,7 @@ public class FileObjectDiskMapped implements FileObject {
public
synchronized
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
// check if need to expand file
if
(
mapped
.
capacity
()
<
pos
+
len
)
{
int
oldPos
=
pos
;
unMap
();
file
.
setLength
(
pos
+
len
);
reMap
();
pos
=
oldPos
;
setFileLength
(
pos
+
len
);
}
mapped
.
position
(
pos
);
mapped
.
put
(
b
,
off
,
len
);
...
...
@@ -210,8 +225,4 @@ public class FileObjectDiskMapped implements FileObject {
}
}
public
String
toString
()
{
return
name
;
}
}
h2/src/main/org/h2/store/fs/FileObjectRec.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
/**
* A file object that records all write operations and can re-play them.
*/
public
class
FileObjectRec
implements
FileObject
{
private
final
FilePathRec
fs
;
private
final
FileObject
file
;
private
final
String
name
;
FileObjectRec
(
FilePathRec
fs
,
FileObject
file
,
String
fileName
)
{
this
.
fs
=
fs
;
this
.
file
=
file
;
this
.
name
=
fileName
;
}
public
void
close
()
throws
IOException
{
file
.
close
();
}
public
long
position
()
throws
IOException
{
return
file
.
position
();
}
public
long
size
()
throws
IOException
{
return
file
.
size
();
}
public
void
readFully
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
file
.
readFully
(
b
,
off
,
len
);
}
public
void
position
(
long
pos
)
throws
IOException
{
file
.
position
(
pos
);
}
public
void
truncate
(
long
newLength
)
throws
IOException
{
fs
.
log
(
Recorder
.
TRUNCATE
,
name
,
null
,
newLength
);
file
.
truncate
(
newLength
);
}
public
void
sync
()
throws
IOException
{
file
.
sync
();
}
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
byte
[]
buff
=
b
;
if
(
off
!=
0
||
len
!=
b
.
length
)
{
buff
=
new
byte
[
len
];
System
.
arraycopy
(
b
,
off
,
buff
,
0
,
len
);
}
file
.
write
(
b
,
off
,
len
);
fs
.
log
(
Recorder
.
WRITE
,
name
,
buff
,
file
.
position
());
}
public
boolean
tryLock
()
{
return
file
.
tryLock
();
}
public
void
releaseLock
()
{
file
.
releaseLock
();
}
}
\ No newline at end of file
h2/src/main/org/h2/store/fs/FilePath.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
org.h2.util.MathUtils
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
/**
* A path to a file. It similar to the Java 7 <code>java.nio.file.Path</code>,
* but simpler, and works with older versions of Java. It also implements the
* relevant methods found in <code>java.nio.file.FileSystem</code> and
* <code>FileSystems</code>
*/
public
abstract
class
FilePath
{
private
static
final
FilePath
DEFAULT
=
new
FilePathDisk
();
private
static
Map
<
String
,
FilePath
>
providers
;
/**
* The prefix for temporary files. See also TestClearReferences.
*/
private
static
String
tempRandom
;
private
static
long
tempSequence
;
protected
String
name
;
/**
* Get the file path object for the given path.
*
* @param path the path
* @return the file path object
*/
public
static
FilePath
get
(
String
path
)
{
int
index
=
path
.
indexOf
(
':'
);
if
(
index
<
2
)
{
// use the default provider if no prefix or
// only a single character (drive name)
return
DEFAULT
.
getPath
(
path
);
}
String
scheme
=
path
.
substring
(
0
,
index
);
registerDefaultProviders
();
FilePath
p
=
providers
.
get
(
scheme
);
if
(
p
==
null
)
{
// provider not found - use the default
p
=
DEFAULT
;
}
return
p
.
getPath
(
path
);
}
private
static
void
registerDefaultProviders
()
{
if
(
providers
==
null
)
{
Map
<
String
,
FilePath
>
map
=
Collections
.
synchronizedMap
(
New
.<
String
,
FilePath
>
hashMap
());
for
(
String
c
:
new
String
[]
{
"org.h2.store.fs.FilePathMem"
,
"org.h2.store.fs.FilePathMemLZF"
,
"org.h2.store.fs.FilePathSplit"
,
"org.h2.store.fs.FilePathNio"
,
"org.h2.store.fs.FilePathNioMapped"
,
"org.h2.store.fs.FilePathZip"
})
{
try
{
FilePath
p
=
(
FilePath
)
Class
.
forName
(
c
).
newInstance
();
map
.
put
(
p
.
getScheme
(),
p
);
}
catch
(
Exception
e
)
{
// ignore - the files may be excluded in purpose
}
}
providers
=
map
;
}
}
/**
* Register a file provider.
*
* @param provider the file provider
*/
public
static
void
register
(
FilePath
provider
)
{
registerDefaultProviders
();
providers
.
put
(
provider
.
getScheme
(),
provider
);
}
/**
* Unregister a file provider.
*
* @param provider the file provider
*/
public
static
void
unregister
(
FilePath
provider
)
{
registerDefaultProviders
();
providers
.
remove
(
provider
.
getScheme
());
}
/**
* Get the size of a file in bytes
*
* @return the size in bytes
*/
public
abstract
long
size
();
/**
* Rename a file if this is allowed.
*
* @param newName the new fully qualified file name
*/
public
abstract
void
moveTo
(
FilePath
newName
);
/**
* Create a new file.
*
* @return true if creating was successful
*/
public
abstract
boolean
createFile
();
/**
* Checks if a file exists.
*
* @return true if it exists
*/
public
abstract
boolean
exists
();
/**
* Delete a file or directory if it exists.
* Directories may only be deleted if they are empty.
*/
public
abstract
void
delete
();
/**
* List the files in the given directory.
*
* @return the list of fully qualified file names
*/
public
abstract
List
<
FilePath
>
listFiles
();
/**
* Normalize a file name.
*
* @return the normalized file name
*/
public
abstract
FilePath
getCanonicalPath
();
/**
* Get the parent directory of a file or directory.
*
* @return the parent directory name
*/
public
abstract
FilePath
getParent
();
/**
* Check if it is a file or a directory.
*
* @return true if it is a directory
*/
public
abstract
boolean
isDirectory
();
/**
* Check if the file name includes a path.
*
* @return if the file name is absolute
*/
public
abstract
boolean
isAbsolute
();
/**
* Get the last modified date of a file
*
* @return the last modified date
*/
public
abstract
long
lastModified
();
/**
* Check if the file is writable.
*
* @return if the file is writable
*/
public
abstract
boolean
canWrite
();
/**
* Create a directory (all required parent directories already exist).
*/
public
abstract
void
createDirectory
();
/**
* Get the file or directory name (the last element of the path).
*
* @return the last element of the path
*/
public
String
getName
()
{
int
idx
=
Math
.
max
(
name
.
indexOf
(
':'
),
name
.
lastIndexOf
(
'/'
));
return
idx
<
0
?
name
:
name
.
substring
(
idx
+
1
);
}
/**
* Check if a file starts with a given prefix.
*
* @param prefix the prefix
* @return true if it starts with the prefix
*/
public
abstract
boolean
fileStartsWith
(
String
prefix
);
/**
* Create an output stream to write into the file.
*
* @param append if true, the file will grow, if false, the file will be
* truncated first
* @return the output stream
*/
public
abstract
OutputStream
newOutputStream
(
boolean
append
);
/**
* Open a random access file object.
*
* @param mode the access mode. Supported are r, rw, rws, rwd
* @return the file object
*/
public
abstract
FileObject
openFileObject
(
String
mode
)
throws
IOException
;
/**
* Create an input stream to read from the file.
*
* @return the input stream
*/
public
abstract
InputStream
newInputStream
()
throws
IOException
;
/**
* Disable the ability to write.
*
* @return true if the call was successful
*/
public
abstract
boolean
setReadOnly
();
/**
* Create a new temporary file.
*
* @param suffix the suffix
* @param deleteOnExit if the file should be deleted when the virtual
* machine exists
* @param inTempDir if the file should be stored in the temporary directory
* @return the name of the created file
*/
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
while
(
true
)
{
FilePath
p
=
getPath
(
name
+
getNextTempFileNamePart
(
false
)
+
suffix
);
if
(
p
.
exists
()
||
!
p
.
createFile
())
{
// in theory, the random number could collide
getNextTempFileNamePart
(
true
);
continue
;
}
p
.
openFileObject
(
"rw"
).
close
();
return
p
;
}
}
/**
* Get the next temporary file name part (the part in the middle).
*
* @param newRandom if the random part of the filename should change
* @return the file name part
*/
protected
static
synchronized
String
getNextTempFileNamePart
(
boolean
newRandom
)
{
if
(
newRandom
||
tempRandom
==
null
)
{
byte
[]
prefix
=
new
byte
[
8
];
MathUtils
.
randomBytes
(
prefix
);
tempRandom
=
StringUtils
.
convertBytesToHex
(
prefix
)
+
"."
;
}
return
tempRandom
+
tempSequence
++;
}
/**
* Get the string representation. The returned string can be used to
* construct a new object.
*
* @return the path as a string
*/
public
String
toString
()
{
return
name
;
}
/**
* Get the scheme (prefix) for this file provider.
* This is similar to <code>java.nio.file.spi.FileSystemProvider.getScheme</code>.
*
* @return the scheme
*/
public
abstract
String
getScheme
();
/**
* Convert a file to a path. This is similar to
* <code>java.nio.file.spi.FileSystemProvider.getPath</code>, but may
* return an object even if the scheme doesn't match in case of the the
* default file provider.
*
* @param path
* @return the file path
*/
public
abstract
FilePath
getPath
(
String
path
);
/**
* Get the unwrapped file name (without wrapper prefixes if wrapping /
* delegating file systems are used).
*
* @return the unwrapped path
*/
public
FilePath
unwrap
()
{
return
this
;
}
}
h2/src/main/org/h2/store/fs/FilePathDisk.java
0 → 100644
浏览文件 @
ab2f646c
差异被折叠。
点击展开。
h2/src/main/org/h2/store/fs/FilePathMem.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.TreeMap
;
import
org.h2.message.DbException
;
import
org.h2.util.New
;
/**
* This file system keeps files fully in memory. There is an option to compress
* file blocks to safe memory.
*/
public
class
FilePathMem
extends
FilePath
{
private
static
final
TreeMap
<
String
,
FileObjectMemoryData
>
MEMORY_FILES
=
new
TreeMap
<
String
,
FileObjectMemoryData
>();
public
FilePathMem
getPath
(
String
path
)
{
FilePathMem
p
=
new
FilePathMem
();
p
.
name
=
getCanonicalPath
(
path
);
return
p
;
}
public
long
size
()
{
return
getMemoryFile
().
length
();
}
public
void
moveTo
(
FilePath
newName
)
{
synchronized
(
MEMORY_FILES
)
{
FileObjectMemoryData
f
=
getMemoryFile
();
f
.
setName
(
newName
.
name
);
MEMORY_FILES
.
remove
(
name
);
MEMORY_FILES
.
put
(
newName
.
name
,
f
);
}
}
public
boolean
createFile
()
{
synchronized
(
MEMORY_FILES
)
{
if
(
exists
())
{
return
false
;
}
getMemoryFile
();
}
return
true
;
}
public
boolean
exists
()
{
if
(
isRoot
())
{
return
true
;
}
synchronized
(
MEMORY_FILES
)
{
return
MEMORY_FILES
.
get
(
name
)
!=
null
;
}
}
public
void
delete
()
{
if
(
isRoot
())
{
return
;
}
synchronized
(
MEMORY_FILES
)
{
MEMORY_FILES
.
remove
(
name
);
}
}
public
List
<
FilePath
>
listFiles
()
{
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
synchronized
(
MEMORY_FILES
)
{
for
(
String
n
:
MEMORY_FILES
.
tailMap
(
name
).
keySet
())
{
if
(
n
.
startsWith
(
name
))
{
list
.
add
(
getPath
(
n
));
}
else
{
break
;
}
}
return
list
;
}
}
public
boolean
setReadOnly
()
{
return
getMemoryFile
().
setReadOnly
();
}
public
boolean
canWrite
()
{
return
getMemoryFile
().
canWrite
();
}
public
FilePathMem
getParent
()
{
int
idx
=
name
.
lastIndexOf
(
'/'
);
return
idx
<
0
?
null
:
getPath
(
name
.
substring
(
0
,
idx
));
}
public
boolean
isDirectory
()
{
// TODO in memory file system currently
// does not really support directories
return
false
;
}
public
boolean
isAbsolute
()
{
// TODO relative files are not supported
return
true
;
}
public
FilePathMem
getCanonicalPath
()
{
return
this
;
}
public
long
lastModified
()
{
return
getMemoryFile
().
getLastModified
();
}
public
void
createDirectory
()
{
// TODO directories are not really supported
}
public
boolean
fileStartsWith
(
String
prefix
)
{
prefix
=
getCanonicalPath
(
prefix
);
return
name
.
startsWith
(
prefix
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
FileObjectMemoryData
obj
=
getMemoryFile
();
FileObjectMemory
m
=
new
FileObjectMemory
(
obj
,
false
);
return
new
FileObjectOutputStream
(
m
,
append
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
InputStream
newInputStream
()
{
FileObjectMemoryData
obj
=
getMemoryFile
();
FileObjectMemory
m
=
new
FileObjectMemory
(
obj
,
true
);
return
new
FileObjectInputStream
(
m
);
}
public
FileObject
openFileObject
(
String
mode
)
{
FileObjectMemoryData
obj
=
getMemoryFile
();
return
new
FileObjectMemory
(
obj
,
"r"
.
equals
(
mode
));
}
private
FileObjectMemoryData
getMemoryFile
()
{
synchronized
(
MEMORY_FILES
)
{
FileObjectMemoryData
m
=
MEMORY_FILES
.
get
(
name
);
if
(
m
==
null
)
{
m
=
new
FileObjectMemoryData
(
name
,
compressed
());
MEMORY_FILES
.
put
(
name
,
m
);
}
return
m
;
}
}
private
boolean
isRoot
()
{
return
name
.
equals
(
getScheme
());
}
protected
boolean
accepts
(
String
fileName
)
{
return
fileName
.
startsWith
(
getScheme
());
}
public
String
unwrap
(
String
fileName
)
{
return
fileName
;
}
private
static
String
getCanonicalPath
(
String
fileName
)
{
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
int
idx
=
fileName
.
indexOf
(
':'
)
+
1
;
if
(
fileName
.
length
()
>
idx
&&
fileName
.
charAt
(
idx
)
!=
'/'
)
{
fileName
=
fileName
.
substring
(
0
,
idx
)
+
"/"
+
fileName
.
substring
(
idx
);
}
return
fileName
;
}
public
String
getScheme
()
{
return
"memFS"
;
}
boolean
compressed
()
{
return
false
;
}
}
/**
* A memory file system that compresses blocks to conserve memory.
*/
class
FilePathMemLZF
extends
FilePathMem
{
boolean
compressed
()
{
return
true
;
}
public
String
getScheme
()
{
return
"memLZF"
;
}
}
h2/src/main/org/h2/store/fs/FilePathNio.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
/**
* This file system stores files on disk and uses java.nio to access the files.
* This class uses FileChannel.
*/
public
class
FilePathNio
extends
FilePathWrapper
{
/**
* Try to open a file with this name and mode.
*
* @param fileName the file name
* @param mode the open mode
* @return the file object
* @throws IOException if opening fails
*/
protected
FileObject
open
(
String
fileName
,
String
mode
)
throws
IOException
{
return
new
FileObjectDiskChannel
(
fileName
,
mode
);
}
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
public
String
getScheme
()
{
return
"nio"
;
}
}
h2/src/main/org/h2/store/fs/FilePathNioMapped.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
/**
* This file system stores files on disk and uses java.nio to access the files.
* This class used memory mapped files.
*/
public
class
FilePathNioMapped
extends
FilePathNio
{
protected
FileObject
open
(
String
mode
)
throws
IOException
{
return
new
FileObjectDiskMapped
(
name
,
mode
);
}
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
public
String
getScheme
()
{
return
"nioMapped"
;
}
}
h2/src/main/org/h2/store/fs/FilePathRec.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.OutputStream
;
/**
* A file system that records all write operations and can re-play them.
*/
public
class
FilePathRec
extends
FilePathWrapper
{
private
static
final
FilePathRec
INSTANCE
=
new
FilePathRec
();
private
static
Recorder
recorder
;
private
boolean
trace
;
/**
* Register the file system.
*/
public
static
void
register
()
{
FilePath
.
register
(
INSTANCE
);
}
/**
* Set the recorder class.
*
* @param recorder the recorder
*/
public
static
void
setRecorder
(
Recorder
recorder
)
{
FilePathRec
.
recorder
=
recorder
;
}
public
boolean
createFile
()
{
log
(
Recorder
.
CREATE_NEW_FILE
,
name
);
return
super
.
createFile
();
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
log
(
Recorder
.
CREATE_TEMP_FILE
,
unwrap
(
name
)
+
":"
+
suffix
+
":"
+
deleteOnExit
+
":"
+
inTempDir
);
return
super
.
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
);
}
public
void
delete
()
{
log
(
Recorder
.
DELETE
,
name
);
super
.
delete
();
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
return
new
FileObjectRec
(
this
,
super
.
openFileObject
(
mode
),
name
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
log
(
Recorder
.
OPEN_OUTPUT_STREAM
,
name
);
return
super
.
newOutputStream
(
append
);
}
public
void
moveTo
(
FilePath
newPath
)
{
log
(
Recorder
.
RENAME
,
unwrap
(
name
)
+
":"
+
unwrap
(
newPath
.
name
));
super
.
moveTo
(
newPath
);
}
public
boolean
isTrace
()
{
return
trace
;
}
public
void
setTrace
(
boolean
trace
)
{
this
.
trace
=
trace
;
}
/**
* Log the operation.
*
* @param op the operation
* @param fileName the file name(s)
*/
void
log
(
int
op
,
String
fileName
)
{
log
(
op
,
fileName
,
null
,
0
);
}
/**
* Log the operation.
*
* @param op the operation
* @param fileName the file name
* @param data the data or null
* @param x the value or 0
*/
void
log
(
int
op
,
String
fileName
,
byte
[]
data
,
long
x
)
{
if
(
recorder
!=
null
)
{
recorder
.
log
(
op
,
fileName
,
data
,
x
);
}
}
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
public
String
getScheme
()
{
return
"rec"
;
}
}
h2/src/main/org/h2/store/fs/FilePathSplit.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.SequenceInputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.h2.constant.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.util.New
;
/**
* A file system that may split files into multiple smaller files.
* (required for a FAT32 because it only support files up to 2 GB).
*/
public
class
FilePathSplit
extends
FilePathWrapper
{
private
static
final
String
PART_SUFFIX
=
".part"
;
protected
String
getPrefix
()
{
return
getScheme
()
+
":"
+
parse
(
name
)[
0
]
+
":"
;
}
public
FilePath
unwrap
(
String
fileName
)
{
return
FilePath
.
get
(
parse
(
fileName
)[
1
]);
}
public
boolean
setReadOnly
()
{
boolean
result
=
false
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
result
=
f
.
setReadOnly
();
}
else
{
break
;
}
}
return
result
;
}
public
void
delete
()
{
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
f
.
delete
();
}
else
{
break
;
}
}
}
public
long
lastModified
()
{
long
lastModified
=
0
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
long
l
=
f
.
lastModified
();
lastModified
=
Math
.
max
(
lastModified
,
l
);
}
else
{
break
;
}
}
return
lastModified
;
}
public
long
size
()
{
long
length
=
0
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
length
+=
f
.
size
();
}
else
{
break
;
}
}
return
length
;
}
public
ArrayList
<
FilePath
>
listFiles
()
{
List
<
FilePath
>
list
=
getBase
().
listFiles
();
ArrayList
<
FilePath
>
newList
=
New
.
arrayList
();
for
(
int
i
=
0
,
size
=
list
.
size
();
i
<
size
;
i
++)
{
FilePath
f
=
list
.
get
(
i
);
if
(!
f
.
getName
().
endsWith
(
PART_SUFFIX
))
{
newList
.
add
(
wrap
(
f
));
}
}
return
newList
;
}
public
InputStream
newInputStream
()
throws
IOException
{
InputStream
input
=
getBase
().
newInputStream
();
for
(
int
i
=
1
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
InputStream
i2
=
f
.
newInputStream
();
input
=
new
SequenceInputStream
(
input
,
i2
);
}
else
{
break
;
}
}
return
input
;
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
ArrayList
<
FileObject
>
list
=
New
.
arrayList
();
FileObject
o
=
getBase
().
openFileObject
(
mode
);
list
.
add
(
o
);
for
(
int
i
=
1
;;
i
++)
{
FilePath
f
=
getBase
(
i
);
if
(
f
.
exists
())
{
o
=
f
.
openFileObject
(
mode
);
list
.
add
(
o
);
}
else
{
break
;
}
}
FileObject
[]
array
=
new
FileObject
[
list
.
size
()];
list
.
toArray
(
array
);
long
maxLength
=
array
[
0
].
size
();
long
length
=
maxLength
;
if
(
array
.
length
==
1
)
{
long
defaultMaxLength
=
getDefaultMaxLength
();
if
(
maxLength
<
defaultMaxLength
)
{
maxLength
=
defaultMaxLength
;
}
}
else
{
if
(
maxLength
==
0
)
{
closeAndThrow
(
0
,
array
,
array
[
0
],
maxLength
);
}
for
(
int
i
=
1
;
i
<
array
.
length
-
1
;
i
++)
{
o
=
array
[
i
];
long
l
=
o
.
size
();
length
+=
l
;
if
(
l
!=
maxLength
)
{
closeAndThrow
(
i
,
array
,
o
,
maxLength
);
}
}
o
=
array
[
array
.
length
-
1
];
long
l
=
o
.
size
();
length
+=
l
;
if
(
l
>
maxLength
)
{
closeAndThrow
(
array
.
length
-
1
,
array
,
o
,
maxLength
);
}
}
FileObjectSplit
fo
=
new
FileObjectSplit
(
name
,
mode
,
array
,
length
,
maxLength
);
return
fo
;
}
private
long
getDefaultMaxLength
()
{
return
1L
<<
Integer
.
decode
(
parse
(
name
)[
0
]).
intValue
();
}
private
void
closeAndThrow
(
int
id
,
FileObject
[]
array
,
FileObject
o
,
long
maxLength
)
throws
IOException
{
String
message
=
"Expected file length: "
+
maxLength
+
" got: "
+
o
.
size
()
+
" for "
+
getName
(
id
);
for
(
FileObject
f
:
array
)
{
f
.
close
();
}
throw
new
IOException
(
message
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
return
new
FileObjectOutputStream
(
openFileObject
(
"rw"
),
append
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
void
moveTo
(
FilePath
path
)
{
FilePathSplit
newName
=
(
FilePathSplit
)
path
;
for
(
int
i
=
0
;;
i
++)
{
FilePath
o
=
getBase
(
i
);
if
(
o
.
exists
())
{
o
.
moveTo
(
newName
.
getBase
(
i
));
}
else
{
break
;
}
}
}
/**
* Split the file name into size and base file name.
*
* @param fileName the file name
* @return an array with size and file name
*/
private
String
[]
parse
(
String
fileName
)
{
if
(!
fileName
.
startsWith
(
getScheme
()))
{
DbException
.
throwInternalError
(
fileName
+
" doesn't start with "
+
getScheme
());
}
fileName
=
fileName
.
substring
(
getScheme
().
length
()
+
1
);
String
size
;
if
(
fileName
.
length
()
>
0
&&
Character
.
isDigit
(
fileName
.
charAt
(
0
)))
{
int
idx
=
fileName
.
indexOf
(
':'
);
size
=
fileName
.
substring
(
0
,
idx
);
try
{
fileName
=
fileName
.
substring
(
idx
+
1
);
}
catch
(
NumberFormatException
e
)
{
// ignore
}
}
else
{
size
=
Long
.
toString
(
SysProperties
.
SPLIT_FILE_SIZE_SHIFT
);
}
return
new
String
[]
{
size
,
fileName
};
}
/**
* Get the file name of a part file.
*
* @param id the part id
* @return the file name including the part id
*/
private
FilePath
getBase
(
int
id
)
{
return
FilePath
.
get
(
getName
(
id
));
}
private
String
getName
(
int
id
)
{
return
id
>
0
?
getBase
().
name
+
"."
+
id
+
PART_SUFFIX
:
getBase
().
name
;
}
public
String
getScheme
()
{
return
"split"
;
}
}
\ No newline at end of file
h2/src/main/org/h2/store/fs/FilePathWrapper.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.List
;
import
org.h2.message.DbException
;
/**
* The base class for wrapping / delegating file systems such as
* the split file system.
*/
public
abstract
class
FilePathWrapper
extends
FilePath
{
private
FilePath
base
;
public
FilePathWrapper
getPath
(
String
path
)
{
return
create
(
path
,
unwrap
(
path
));
}
public
FilePathWrapper
wrap
(
FilePath
base
)
{
return
create
(
getPrefix
()
+
base
.
name
,
base
);
}
public
FilePath
unwrap
()
{
return
unwrap
(
name
);
}
private
FilePathWrapper
create
(
String
path
,
FilePath
base
)
{
try
{
FilePathWrapper
p
=
getClass
().
newInstance
();
p
.
name
=
path
;
p
.
base
=
base
;
return
p
;
}
catch
(
Exception
e
)
{
throw
DbException
.
convert
(
e
);
}
}
protected
String
getPrefix
()
{
return
getScheme
()
+
":"
;
}
protected
FilePath
unwrap
(
String
path
)
{
return
FilePath
.
get
(
path
.
substring
(
getScheme
().
length
()
+
1
));
}
protected
FilePath
getBase
()
{
return
base
;
}
public
boolean
canWrite
()
{
return
base
.
canWrite
();
}
public
void
createDirectory
()
{
base
.
createDirectory
();
}
public
boolean
createFile
()
{
return
base
.
createFile
();
}
public
void
delete
()
{
base
.
delete
();
}
public
boolean
exists
()
{
return
base
.
exists
();
}
public
boolean
fileStartsWith
(
String
prefix
)
{
return
name
.
startsWith
(
prefix
);
}
public
FilePath
getParent
()
{
return
wrap
(
base
.
getParent
());
}
public
boolean
isAbsolute
()
{
return
base
.
isAbsolute
();
}
public
boolean
isDirectory
()
{
return
base
.
isDirectory
();
}
public
long
lastModified
()
{
return
base
.
lastModified
();
}
public
FilePath
getCanonicalPath
()
{
return
wrap
(
base
.
getCanonicalPath
());
}
public
List
<
FilePath
>
listFiles
()
{
List
<
FilePath
>
list
=
base
.
listFiles
();
for
(
int
i
=
0
,
len
=
list
.
size
();
i
<
len
;
i
++)
{
list
.
set
(
i
,
wrap
(
list
.
get
(
i
)));
}
return
list
;
}
public
void
moveTo
(
FilePath
newName
)
{
base
.
moveTo
(((
FilePathWrapper
)
newName
).
base
);
}
public
InputStream
newInputStream
()
throws
IOException
{
return
base
.
newInputStream
();
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
return
base
.
newOutputStream
(
append
);
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
return
base
.
openFileObject
(
mode
);
}
public
boolean
setReadOnly
()
{
return
base
.
setReadOnly
();
}
public
long
size
()
{
return
base
.
size
();
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
return
wrap
(
base
.
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
));
}
}
h2/src/main/org/h2/store/fs/FilePathZip.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
store
.
fs
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
org.h2.message.DbException
;
import
org.h2.util.New
;
/**
* This is a read-only file system that allows
* to access databases stored in a .zip or .jar file.
*/
public
class
FilePathZip
extends
FilePath
{
public
FilePathZip
getPath
(
String
path
)
{
FilePathZip
p
=
new
FilePathZip
();
p
.
name
=
path
;
return
p
;
}
public
void
createDirectory
()
{
// ignore
}
public
boolean
createFile
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
String
createTempFile
(
String
prefix
,
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
if
(!
inTempDir
)
{
throw
new
IOException
(
"File system is read-only"
);
}
return
FileSystemDisk
.
getInstance
().
createTempFile
(
prefix
,
suffix
,
deleteOnExit
,
true
);
}
public
void
delete
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
boolean
exists
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipFile
file
=
openZipFile
();
return
file
.
getEntry
(
entryName
)
!=
null
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
fileStartsWith
(
String
fileName
,
String
prefix
)
{
return
fileName
.
startsWith
(
prefix
);
}
// public String _getName(String name) {
// name = getEntryName(name);
// if (name.endsWith("/")) {
// name = name.substring(0, name.length() - 1);
// }
// int idx = name.lastIndexOf('/');
// if (idx >= 0) {
// name = name.substring(idx + 1);
// }
// return name;
// }
public
long
lastModified
()
{
return
0
;
}
public
FilePath
getParent
()
{
int
idx
=
name
.
lastIndexOf
(
'/'
);
return
idx
<
0
?
null
:
getPath
(
name
.
substring
(
0
,
idx
));
}
public
boolean
isAbsolute
()
{
return
true
;
}
public
boolean
isDirectory
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipFile
file
=
openZipFile
();
Enumeration
<?
extends
ZipEntry
>
en
=
file
.
entries
();
while
(
en
.
hasMoreElements
())
{
ZipEntry
entry
=
en
.
nextElement
();
String
n
=
entry
.
getName
();
if
(
n
.
equals
(
entryName
))
{
return
entry
.
isDirectory
();
}
else
if
(
n
.
startsWith
(
entryName
))
{
if
(
n
.
length
()
==
entryName
.
length
()
+
1
)
{
if
(
n
.
equals
(
entryName
+
"/"
))
{
return
true
;
}
}
}
}
return
false
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
canWrite
()
{
return
false
;
}
public
boolean
setReadOnly
()
{
return
true
;
}
public
long
size
()
{
try
{
ZipFile
file
=
openZipFile
();
ZipEntry
entry
=
file
.
getEntry
(
getEntryName
());
return
entry
==
null
?
0
:
entry
.
getSize
();
}
catch
(
IOException
e
)
{
return
0
;
}
}
public
ArrayList
<
FilePath
>
listFiles
()
{
String
path
=
name
;
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
try
{
if
(
path
.
indexOf
(
'!'
)
<
0
)
{
path
+=
"!"
;
}
if
(!
path
.
endsWith
(
"/"
))
{
path
+=
"/"
;
}
ZipFile
file
=
openZipFile
();
String
dirName
=
getEntryName
();
String
prefix
=
path
.
substring
(
0
,
path
.
length
()
-
dirName
.
length
());
Enumeration
<?
extends
ZipEntry
>
en
=
file
.
entries
();
while
(
en
.
hasMoreElements
())
{
ZipEntry
entry
=
en
.
nextElement
();
String
name
=
entry
.
getName
();
if
(!
name
.
startsWith
(
dirName
))
{
continue
;
}
if
(
name
.
length
()
<=
dirName
.
length
())
{
continue
;
}
int
idx
=
name
.
indexOf
(
'/'
,
dirName
.
length
());
if
(
idx
<
0
||
idx
>=
name
.
length
()
-
1
)
{
list
.
add
(
getPath
(
prefix
+
name
));
}
}
return
list
;
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
"listFiles "
+
path
);
}
}
public
InputStream
newInputStream
()
throws
IOException
{
return
new
FileObjectInputStream
(
openFileObject
(
"r"
));
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
ZipFile
file
=
openZipFile
();
ZipEntry
entry
=
file
.
getEntry
(
getEntryName
());
if
(
entry
==
null
)
{
throw
new
FileNotFoundException
(
name
);
}
return
new
FileObjectZip
(
file
,
entry
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
void
moveTo
(
FilePath
newName
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
private
static
String
translateFileName
(
String
fileName
)
{
if
(
fileName
.
startsWith
(
"zip:"
))
{
fileName
=
fileName
.
substring
(
"zip:"
.
length
());
}
int
idx
=
fileName
.
indexOf
(
'!'
);
if
(
idx
>=
0
)
{
fileName
=
fileName
.
substring
(
0
,
idx
);
}
return
FileSystemDisk
.
expandUserHomeDirectory
(
fileName
);
}
public
FilePath
getCanonicalPath
()
{
return
this
;
}
private
String
getEntryName
()
{
int
idx
=
name
.
indexOf
(
'!'
);
String
fileName
;
if
(
idx
<=
0
)
{
fileName
=
""
;
}
else
{
fileName
=
name
.
substring
(
idx
+
1
);
}
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
if
(
fileName
.
startsWith
(
"/"
))
{
fileName
=
fileName
.
substring
(
1
);
}
return
fileName
;
}
private
ZipFile
openZipFile
()
throws
IOException
{
String
fileName
=
translateFileName
(
name
);
return
new
ZipFile
(
fileName
);
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
if
(!
inTempDir
)
{
throw
new
IOException
(
"File system is read-only"
);
}
return
new
FilePathDisk
().
getPath
(
name
).
createTempFile
(
suffix
,
deleteOnExit
,
true
);
}
// protected boolean accepts(String fileName) {
// return fileName.startsWith(PREFIX);
// }
public
boolean
fileStartsWith
(
String
prefix
)
{
return
name
.
startsWith
(
prefix
);
}
public
String
getScheme
()
{
return
"zip"
;
}
}
h2/src/main/org/h2/store/fs/FileSystem.java
浏览文件 @
ab2f646c
...
...
@@ -143,14 +143,6 @@ public abstract class FileSystem {
*/
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.
*
...
...
h2/src/main/org/h2/store/fs/FileSystemDisk.java
浏览文件 @
ab2f646c
...
...
@@ -162,7 +162,7 @@ public class FileSystemDisk extends FileSystem {
dir
=
new
File
(
Utils
.
getProperty
(
"java.io.tmpdir"
,
"."
));
}
else
{
dir
=
new
File
(
name
).
getAbsoluteFile
().
getParentFile
();
IOUtils
.
mkdirs
(
dir
);
FileUtils
.
createDirectories
(
dir
.
getAbsolutePath
()
);
}
File
f
;
while
(
true
)
{
...
...
@@ -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
)
{
fileName
=
translateFileName
(
fileName
);
return
canWriteInternal
(
new
File
(
fileName
));
...
...
h2/src/main/org/h2/store/fs/FileSystemMemory.java
浏览文件 @
ab2f646c
...
...
@@ -103,14 +103,14 @@ public class FileSystemMemory extends FileSystem {
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
return
!
getMemoryFile
(
fileName
).
canWrite
();
}
public
boolean
setReadOnly
(
String
fileName
)
{
return
getMemoryFile
(
fileName
).
setReadOnly
();
}
public
boolean
canWrite
(
String
fileName
)
{
return
getMemoryFile
(
fileName
).
canWrite
();
}
public
String
getCanonicalPath
(
String
fileName
)
{
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
int
idx
=
fileName
.
indexOf
(
':'
)
+
1
;
...
...
@@ -144,10 +144,6 @@ public class FileSystemMemory extends FileSystem {
return
getMemoryFile
(
fileName
).
getLastModified
();
}
public
boolean
canWrite
(
String
fileName
)
{
return
true
;
}
public
void
createDirectory
(
String
directoryName
)
{
// TODO directories are not really supported
}
...
...
h2/src/main/org/h2/store/fs/FileSystemWrapper.java
浏览文件 @
ab2f646c
...
...
@@ -24,10 +24,6 @@ public abstract class FileSystemWrapper extends FileSystem {
*/
protected
abstract
String
getPrefix
();
public
boolean
canWrite
(
String
fileName
)
{
return
FileUtils
.
canWrite
(
unwrap
(
fileName
));
}
public
boolean
setReadOnly
(
String
fileName
)
{
return
FileUtils
.
setReadOnly
(
unwrap
(
fileName
));
}
...
...
@@ -77,8 +73,8 @@ public abstract class FileSystemWrapper extends FileSystem {
return
FileUtils
.
isDirectory
(
unwrap
(
fileName
));
}
public
boolean
isReadOnly
(
String
fileName
)
{
return
FileUtils
.
isReadOnly
(
unwrap
(
fileName
));
public
boolean
canWrite
(
String
fileName
)
{
return
FileUtils
.
canWrite
(
unwrap
(
fileName
));
}
public
long
size
(
String
fileName
)
{
...
...
h2/src/main/org/h2/store/fs/FileSystemZip.java
浏览文件 @
ab2f646c
...
...
@@ -29,10 +29,6 @@ public class FileSystemZip extends FileSystem {
FileSystem
.
register
(
new
FileSystemZip
());
}
public
boolean
canWrite
(
String
fileName
)
{
return
false
;
}
public
void
createDirectory
(
String
directoryName
)
{
// ignore
}
...
...
@@ -124,8 +120,8 @@ public class FileSystemZip extends FileSystem {
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
return
tru
e
;
public
boolean
canWrite
(
String
fileName
)
{
return
fals
e
;
}
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
h2/src/main/org/h2/store/fs/FileUtils.java
浏览文件 @
ab2f646c
...
...
@@ -3,6 +3,8 @@ package org.h2.store.fs;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
org.h2.constant.ErrorCode
;
import
org.h2.message.DbException
;
import
org.h2.util.IOUtils
;
/**
...
...
@@ -191,10 +193,10 @@ public class FileUtils {
return
getFileSystem
(
fileName
).
newOutputStream
(
fileName
,
append
);
}
// special methods =======================================
/**
* 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
...
...
@@ -203,20 +205,10 @@ public class FileUtils {
return
getFileSystem
(
fileName
).
canWrite
(
fileName
);
}
/**
* 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
);
}
// special methods =======================================
/**
* Disable the ability to write.
* Disable the ability to write.
The file can still be deleted afterwards.
*
* @param fileName the file name
* @return true if the call was successful
...
...
@@ -292,10 +284,18 @@ public class FileUtils {
* @param dir the directory name
*/
public
static
void
createDirectories
(
String
dir
)
{
if
(
dir
!=
null
&&
!
FileUtils
.
exists
(
dir
))
{
String
parent
=
FileUtils
.
getParent
(
dir
);
createDirectories
(
parent
);
createDirectory
(
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
);
createDirectories
(
parent
);
createDirectory
(
dir
);
}
}
}
...
...
h2/src/main/org/h2/store/fs/FileUtils2.java
0 → 100644
浏览文件 @
ab2f646c
差异被折叠。
点击展开。
h2/src/main/org/h2/util/IOUtils.java
浏览文件 @
ab2f646c
...
...
@@ -11,7 +11,6 @@ import java.io.BufferedWriter;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.EOFException
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
...
...
@@ -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.
*
...
...
h2/src/main/org/h2/util/SourceCompiler.java
浏览文件 @
ab2f646c
...
...
@@ -139,11 +139,7 @@ public class SourceCompiler {
File
dir
=
new
File
(
compileDir
);
if
(
packageName
!=
null
)
{
dir
=
new
File
(
dir
,
packageName
.
replace
(
'.'
,
'/'
));
try
{
IOUtils
.
mkdirs
(
dir
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
compileDir
);
}
FileUtils
.
createDirectories
(
dir
.
getAbsolutePath
());
}
File
javaFile
=
new
File
(
dir
,
className
+
".java"
);
File
classFile
=
new
File
(
dir
,
className
+
".class"
);
...
...
h2/src/test/org/h2/test/db/TestLinkedTable.java
浏览文件 @
ab2f646c
...
...
@@ -637,7 +637,7 @@ public class TestLinkedTable extends TestBase {
String
name
=
FileUtils
.
getName
(
file
);
if
((
name
.
startsWith
(
"testLinkedTableInReadOnlyDb"
))
&&
(!
name
.
endsWith
(
".trace.db"
)))
{
FileUtils
.
setReadOnly
(
file
);
boolean
isReadOnly
=
FileUtils
.
isReadOnly
(
file
);
boolean
isReadOnly
=
!
FileUtils
.
canWrite
(
file
);
if
(!
isReadOnly
)
{
fail
(
"File "
+
file
+
" is not read only. Can't test it."
);
}
...
...
h2/src/test/org/h2/test/db/TestLob.java
浏览文件 @
ab2f646c
...
...
@@ -440,7 +440,7 @@ public class TestLob extends TestBase {
private
void
testTempFilesDeleted
()
throws
Exception
{
String
[]
list
;
FileUtils
.
deleteRecursive
(
TEMP_DIR
,
true
);
IOUtils
.
mkdirs
(
new
File
(
TEMP_DIR
)
);
FileUtils
.
createDirectories
(
TEMP_DIR
);
list
=
FileUtils
.
listFiles
(
TEMP_DIR
);
if
(
list
.
length
>
0
)
{
fail
(
"Unexpected temp file: "
+
list
[
0
]);
...
...
h2/src/test/org/h2/test/unit/FileSystemDatabase.java
浏览文件 @
ab2f646c
...
...
@@ -170,10 +170,6 @@ public class FileSystemDatabase extends FileSystem {
return
new
RuntimeException
(
e
.
toString
(),
e
);
}
public
boolean
canWrite
(
String
fileName
)
{
return
true
;
}
public
void
createDirectory
(
String
directoryName
)
{
directoryName
=
unwrap
(
directoryName
);
try
{
...
...
@@ -272,8 +268,8 @@ public class FileSystemDatabase extends FileSystem {
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
return
fals
e
;
public
boolean
canWrite
(
String
fileName
)
{
return
tru
e
;
}
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
h2/src/test/org/h2/test/unit/TestFilePath.java
0 → 100644
浏览文件 @
ab2f646c
差异被折叠。
点击展开。
h2/src/test/org/h2/test/utils/DebugFile.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
utils
;
import
java.io.IOException
;
import
org.h2.store.fs.FileObject
;
/**
* A debugging file that logs all operations.
*/
public
class
DebugFile
implements
FileObject
{
private
final
DebugFilePath
fs
;
private
final
FileObject
file
;
private
final
String
name
;
DebugFile
(
DebugFilePath
fs
,
FileObject
file
,
String
name
)
{
this
.
fs
=
fs
;
this
.
file
=
file
;
this
.
name
=
fs
.
getScheme
()
+
":"
+
name
;
}
public
void
close
()
throws
IOException
{
debug
(
"close"
);
file
.
close
();
}
public
long
position
()
throws
IOException
{
debug
(
"getFilePointer"
);
return
file
.
position
();
}
public
long
size
()
throws
IOException
{
debug
(
"length"
);
return
file
.
size
();
}
public
void
readFully
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
debug
(
"readFully"
,
file
.
position
(),
off
,
len
);
file
.
readFully
(
b
,
off
,
len
);
}
public
void
position
(
long
pos
)
throws
IOException
{
debug
(
"seek"
,
pos
);
file
.
position
(
pos
);
}
public
void
truncate
(
long
newLength
)
throws
IOException
{
checkPowerOff
();
debug
(
"truncate"
,
newLength
);
file
.
truncate
(
newLength
);
}
public
void
sync
()
throws
IOException
{
debug
(
"sync"
);
file
.
sync
();
}
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
checkPowerOff
();
debug
(
"write"
,
file
.
position
(),
off
,
len
);
file
.
write
(
b
,
off
,
len
);
}
private
void
debug
(
String
method
,
Object
...
params
)
{
fs
.
trace
(
name
,
method
,
params
);
}
private
void
checkPowerOff
()
throws
IOException
{
try
{
fs
.
checkPowerOff
();
}
catch
(
IOException
e
)
{
try
{
file
.
close
();
}
catch
(
IOException
e2
)
{
// ignore
}
throw
e
;
}
}
public
boolean
tryLock
()
{
debug
(
"tryLock"
);
return
file
.
tryLock
();
}
public
void
releaseLock
()
{
debug
(
"releaseLock"
);
file
.
releaseLock
();
}
}
\ No newline at end of file
h2/src/test/org/h2/test/utils/DebugFilePath.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
utils
;
import
java.io.FilterInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.List
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathWrapper
;
/**
* A debugging file system that logs all operations.
*/
public
class
DebugFilePath
extends
FilePathWrapper
{
private
static
final
DebugFilePath
INSTANCE
=
new
DebugFilePath
();
private
static
final
IOException
POWER_OFF
=
new
IOException
(
"Simulated power failure"
);
private
int
powerOffCount
;
private
boolean
trace
;
/**
* Register the file system.
*
* @return the instance
*/
public
static
DebugFilePath
register
()
{
FilePath
.
register
(
INSTANCE
);
return
INSTANCE
;
}
/**
* Check if the simulated power failure occurred.
* This call will decrement the countdown.
*
* @throws IOException if the simulated power failure occurred
*/
void
checkPowerOff
()
throws
IOException
{
if
(
powerOffCount
==
0
)
{
return
;
}
if
(
powerOffCount
>
1
)
{
powerOffCount
--;
return
;
}
powerOffCount
=
-
1
;
// throw new IOException("Simulated power failure");
throw
POWER_OFF
;
}
public
void
createDirectory
()
{
trace
(
name
,
"createDirectory"
);
super
.
createDirectory
();
}
public
boolean
createFile
()
{
trace
(
name
,
"createFile"
);
return
super
.
createFile
();
}
public
void
delete
()
{
trace
(
name
,
"fileName"
);
super
.
delete
();
}
public
boolean
exists
()
{
trace
(
name
,
"exists"
);
return
super
.
exists
();
}
// public boolean fileStartsWith(String fileName, String prefix) {
// trace(fileName, "fileStartsWith", unwrap(prefix));
// return super.fileStartsWith(fileName, prefix);
// }
public
String
getName
()
{
trace
(
name
,
"getName"
);
return
super
.
getName
();
}
public
long
lastModified
()
{
trace
(
name
,
"lastModified"
);
return
super
.
lastModified
();
}
public
FilePath
getParent
()
{
trace
(
name
,
"getParent"
);
return
super
.
getParent
();
}
public
boolean
isAbsolute
()
{
trace
(
name
,
"isAbsolute"
);
return
super
.
isAbsolute
();
}
public
boolean
isDirectory
()
{
trace
(
name
,
"isDirectory"
);
return
super
.
isDirectory
();
}
public
boolean
canWrite
()
{
trace
(
name
,
"canWrite"
);
return
super
.
canWrite
();
}
public
boolean
setReadOnly
()
{
trace
(
name
,
"setReadOnly"
);
return
super
.
setReadOnly
();
}
public
long
size
()
{
trace
(
name
,
"size"
);
return
super
.
size
();
}
public
List
<
FilePath
>
listFiles
()
{
trace
(
name
,
"listFiles"
);
return
super
.
listFiles
();
}
public
FilePath
getCanonicalPath
()
{
trace
(
name
,
"getCanonicalPath"
);
return
super
.
getCanonicalPath
();
}
public
InputStream
newInputStream
()
throws
IOException
{
trace
(
name
,
"newInputStream"
);
InputStream
in
=
super
.
newInputStream
();
if
(!
trace
)
{
return
in
;
}
final
String
fileName
=
name
;
return
new
FilterInputStream
(
in
)
{
public
int
read
(
byte
[]
b
)
throws
IOException
{
trace
(
fileName
,
"in.read(b)"
);
return
super
.
read
(
b
);
}
public
int
read
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
trace
(
fileName
,
"in.read(b)"
,
"in.read(b, "
+
off
+
", "
+
len
+
")"
);
return
super
.
read
(
b
,
off
,
len
);
}
public
long
skip
(
long
n
)
throws
IOException
{
trace
(
fileName
,
"in.read(b)"
,
"in.skip("
+
n
+
")"
);
return
super
.
skip
(
n
);
}
};
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
trace
(
name
,
"openFileObject"
,
mode
);
return
new
DebugFile
(
this
,
super
.
openFileObject
(
mode
),
name
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
trace
(
name
,
"newOutputStream"
,
append
);
return
super
.
newOutputStream
(
append
);
}
public
void
moveTo
(
FilePath
newName
)
{
trace
(
name
,
"moveTo"
,
unwrap
(((
DebugFilePath
)
newName
).
name
));
super
.
moveTo
(
newName
);
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
trace
(
name
,
"createTempFile"
,
suffix
,
deleteOnExit
,
inTempDir
);
return
super
.
createTempFile
(
suffix
,
deleteOnExit
,
inTempDir
);
}
/**
* Print a debug message.
*
* @param fileName the (wrapped) file name
* @param method the method name
* @param params parameters if any
*/
void
trace
(
String
fileName
,
String
method
,
Object
...
params
)
{
if
(
trace
)
{
StringBuilder
buff
=
new
StringBuilder
(
" "
);
buff
.
append
(
unwrap
(
fileName
)).
append
(
' '
).
append
(
method
);
for
(
Object
s
:
params
)
{
buff
.
append
(
' '
).
append
(
s
);
}
System
.
out
.
println
(
buff
);
}
}
public
void
setPowerOffCount
(
int
count
)
{
this
.
powerOffCount
=
count
;
}
public
int
getPowerOffCount
()
{
return
powerOffCount
;
}
public
boolean
isTrace
()
{
return
trace
;
}
public
void
setTrace
(
boolean
trace
)
{
this
.
trace
=
trace
;
}
public
String
getScheme
()
{
return
"debug"
;
}
}
h2/src/test/org/h2/test/utils/DebugFileSystem.java
浏览文件 @
ab2f646c
...
...
@@ -60,11 +60,6 @@ public class DebugFileSystem extends FileSystemWrapper {
throw
POWER_OFF
;
}
public
boolean
canWrite
(
String
fileName
)
{
trace
(
fileName
,
"canWrite"
);
return
super
.
canWrite
(
fileName
);
}
public
void
createDirectory
(
String
directoryName
)
{
trace
(
directoryName
,
"createDirectory"
);
super
.
createDirectory
(
directoryName
);
...
...
@@ -121,9 +116,9 @@ public class DebugFileSystem extends FileSystemWrapper {
return
super
.
isDirectory
(
fileName
);
}
public
boolean
isReadOnly
(
String
fileName
)
{
trace
(
fileName
,
"
isReadOnly
"
);
return
super
.
isReadOnly
(
fileName
);
public
boolean
canWrite
(
String
fileName
)
{
trace
(
fileName
,
"
canWrite
"
);
return
super
.
canWrite
(
fileName
);
}
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
h2/src/tools/org/h2/dev/fs/FilePathCrypt.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
dev
.
fs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
org.h2.message.DbException
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FileObjectInputStream
;
import
org.h2.store.fs.FileObjectOutputStream
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathWrapper
;
import
org.h2.store.fs.FileUtils
;
/**
* A file system that encrypts the contents of the files.
*/
public
class
FilePathCrypt
extends
FilePathWrapper
{
public
static
void
register
()
{
FilePath
.
register
(
new
FilePathCrypt
());
}
protected
String
getPrefix
()
{
String
[]
parsed
=
parse
(
name
);
return
getScheme
()
+
":"
+
parsed
[
0
]
+
":"
+
parsed
[
1
]
+
":"
;
}
public
FilePath
unwrap
(
String
fileName
)
{
return
FilePath
.
get
(
parse
(
fileName
)[
2
]);
}
public
long
size
()
{
long
len
=
getBase
().
size
();
return
Math
.
max
(
0
,
len
-
FileObjectCrypt
.
HEADER_LENGTH
-
FileObjectCrypt
.
BLOCK_SIZE
);
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
String
[]
parsed
=
parse
(
name
);
FileObject
file
=
FileUtils
.
openFileObject
(
parsed
[
2
],
mode
);
return
new
FileObjectCrypt
(
name
,
parsed
[
0
],
parsed
[
1
],
file
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
try
{
FileObject
file
=
openFileObject
(
"rw"
);
return
new
FileObjectOutputStream
(
file
,
append
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
public
InputStream
newInputStream
()
{
try
{
FileObject
file
=
openFileObject
(
"r"
);
return
new
FileObjectInputStream
(
file
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
name
);
}
}
/**
* Split the file name into algorithm, password, and base file name.
*
* @param fileName the file name
* @return an array with algorithm, password, and base file name
*/
private
String
[]
parse
(
String
fileName
)
{
if
(!
fileName
.
startsWith
(
getScheme
()))
{
DbException
.
throwInternalError
(
fileName
+
" doesn't start with "
+
getScheme
());
}
fileName
=
fileName
.
substring
(
getScheme
().
length
()
+
1
);
int
idx
=
fileName
.
indexOf
(
':'
);
String
algorithm
,
password
;
if
(
idx
<
0
)
{
DbException
.
throwInternalError
(
fileName
+
" doesn't contain encryption algorithm and password"
);
}
algorithm
=
fileName
.
substring
(
0
,
idx
);
fileName
=
fileName
.
substring
(
idx
+
1
);
idx
=
fileName
.
indexOf
(
':'
);
if
(
idx
<
0
)
{
DbException
.
throwInternalError
(
fileName
+
" doesn't contain encryption password"
);
}
password
=
fileName
.
substring
(
0
,
idx
);
fileName
=
fileName
.
substring
(
idx
+
1
);
return
new
String
[]
{
algorithm
,
password
,
fileName
};
}
public
String
getScheme
()
{
return
"crypt"
;
}
}
h2/src/tools/org/h2/dev/fs/FilePathZip2.java
0 → 100644
浏览文件 @
ab2f646c
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
dev
.
fs
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipInputStream
;
import
org.h2.engine.Constants
;
import
org.h2.message.DbException
;
import
org.h2.store.fs.FileObject
;
import
org.h2.store.fs.FileObjectInputStream
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathDisk
;
import
org.h2.store.fs.FileSystemDisk
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.New
;
/**
* This is a read-only file system that allows to access databases stored in a
* .zip or .jar file. The problem of this file system is that data is always
* accessed as a stream. But unlike FileSystemZip, it is possible to stack file
* systems.
*/
public
class
FilePathZip2
extends
FilePath
{
/**
* Register the file system.
*
* @return the instance
*/
public
static
FilePathZip2
register
()
{
FilePathZip2
instance
=
new
FilePathZip2
();
FilePath
.
register
(
instance
);
return
instance
;
}
public
FilePathZip2
getPath
(
String
path
)
{
FilePathZip2
p
=
new
FilePathZip2
();
p
.
name
=
path
;
return
p
;
}
public
void
createDirectory
()
{
// ignore
}
public
boolean
createFile
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
FilePath
createTempFile
(
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
if
(!
inTempDir
)
{
throw
new
IOException
(
"File system is read-only"
);
}
return
new
FilePathDisk
().
getPath
(
name
).
createTempFile
(
suffix
,
deleteOnExit
,
true
);
}
public
void
delete
()
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
boolean
exists
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipInputStream
file
=
openZip
();
boolean
result
=
false
;
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
if
(
entry
.
getName
().
equals
(
entryName
))
{
result
=
true
;
break
;
}
file
.
closeEntry
();
}
file
.
close
();
return
result
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
// public boolean fileStartsWith(String fileName, String prefix) {
// return fileName.startsWith(prefix);
// }
public
long
lastModified
()
{
return
0
;
}
public
FilePath
getParent
()
{
int
idx
=
name
.
lastIndexOf
(
'/'
);
return
idx
<
0
?
null
:
getPath
(
name
.
substring
(
0
,
idx
));
}
public
boolean
isAbsolute
()
{
return
true
;
}
public
boolean
isDirectory
()
{
try
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
return
true
;
}
ZipInputStream
file
=
openZip
();
boolean
result
=
false
;
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
String
n
=
entry
.
getName
();
if
(
n
.
equals
(
entryName
))
{
result
=
entry
.
isDirectory
();
break
;
}
else
if
(
n
.
startsWith
(
entryName
))
{
if
(
n
.
length
()
==
entryName
.
length
()
+
1
)
{
if
(
n
.
equals
(
entryName
+
"/"
))
{
result
=
true
;
break
;
}
}
}
file
.
closeEntry
();
}
file
.
close
();
return
result
;
}
catch
(
IOException
e
)
{
return
false
;
}
}
public
boolean
canWrite
()
{
return
false
;
}
public
boolean
setReadOnly
()
{
return
true
;
}
public
long
size
()
{
try
{
String
entryName
=
getEntryName
();
ZipInputStream
file
=
openZip
();
long
result
=
0
;
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
if
(
entry
.
getName
().
equals
(
entryName
))
{
result
=
entry
.
getSize
();
if
(
result
==
-
1
)
{
result
=
0
;
while
(
true
)
{
long
x
=
file
.
skip
(
16
*
Constants
.
IO_BUFFER_SIZE
);
if
(
x
==
0
)
{
break
;
}
result
+=
x
;
}
}
break
;
}
file
.
closeEntry
();
}
file
.
close
();
return
result
;
}
catch
(
IOException
e
)
{
return
0
;
}
}
public
ArrayList
<
FilePath
>
listFiles
()
{
String
path
=
name
;
try
{
if
(
path
.
indexOf
(
'!'
)
<
0
)
{
path
+=
"!"
;
}
if
(!
path
.
endsWith
(
"/"
))
{
path
+=
"/"
;
}
ZipInputStream
file
=
openZip
();
String
dirName
=
getEntryName
();
String
prefix
=
path
.
substring
(
0
,
path
.
length
()
-
dirName
.
length
());
ArrayList
<
FilePath
>
list
=
New
.
arrayList
();
while
(
true
)
{
ZipEntry
entry
=
file
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
String
name
=
entry
.
getName
();
if
(
name
.
startsWith
(
dirName
)
&&
name
.
length
()
>
dirName
.
length
())
{
int
idx
=
name
.
indexOf
(
'/'
,
dirName
.
length
());
if
(
idx
<
0
||
idx
>=
name
.
length
()
-
1
)
{
list
.
add
(
getPath
(
prefix
+
name
));
}
}
file
.
closeEntry
();
}
file
.
close
();
return
list
;
}
catch
(
IOException
e
)
{
throw
DbException
.
convertIOException
(
e
,
"listFiles "
+
path
);
}
}
public
FilePath
getCanonicalPath
()
{
return
this
;
}
public
InputStream
newInputStream
()
throws
IOException
{
FileObject
file
=
openFileObject
(
"r"
);
return
new
FileObjectInputStream
(
file
);
}
public
FileObject
openFileObject
(
String
mode
)
throws
IOException
{
String
entryName
=
getEntryName
();
if
(
entryName
.
length
()
==
0
)
{
throw
new
FileNotFoundException
();
}
ZipInputStream
in
=
openZip
();
while
(
true
)
{
ZipEntry
entry
=
in
.
getNextEntry
();
if
(
entry
==
null
)
{
break
;
}
if
(
entry
.
getName
().
equals
(
entryName
))
{
return
new
FileObjectZip2
(
name
,
entryName
,
in
,
size
());
}
in
.
closeEntry
();
}
in
.
close
();
throw
new
FileNotFoundException
(
name
);
}
public
OutputStream
newOutputStream
(
boolean
append
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
public
void
moveTo
(
FilePath
newName
)
{
throw
DbException
.
getUnsupportedException
(
"write"
);
}
// public String unwrap(String fileName) {
// if (fileName.startsWith(PREFIX)) {
// fileName = fileName.substring(PREFIX.length());
// }
// int idx = fileName.indexOf('!');
// if (idx >= 0) {
// fileName = fileName.substring(0, idx);
// }
// return FileSystemDisk.expandUserHomeDirectory(fileName);
// }
private
String
getEntryName
()
{
int
idx
=
name
.
indexOf
(
'!'
);
String
fileName
;
if
(
idx
<=
0
)
{
fileName
=
""
;
}
else
{
fileName
=
name
.
substring
(
idx
+
1
);
}
fileName
=
fileName
.
replace
(
'\\'
,
'/'
);
if
(
fileName
.
startsWith
(
"/"
))
{
fileName
=
fileName
.
substring
(
1
);
}
return
fileName
;
}
private
ZipInputStream
openZip
()
throws
IOException
{
String
fileName
=
translateFileName
(
name
);
return
new
ZipInputStream
(
FileUtils
.
newInputStream
(
fileName
));
}
private
static
String
translateFileName
(
String
fileName
)
{
if
(
fileName
.
startsWith
(
"zip2:"
))
{
fileName
=
fileName
.
substring
(
"zip2:"
.
length
());
}
int
idx
=
fileName
.
indexOf
(
'!'
);
if
(
idx
>=
0
)
{
fileName
=
fileName
.
substring
(
0
,
idx
);
}
return
FileSystemDisk
.
expandUserHomeDirectory
(
fileName
);
}
public
boolean
fileStartsWith
(
String
prefix
)
{
return
name
.
startsWith
(
prefix
);
}
public
String
getScheme
()
{
return
"zip2"
;
}
}
\ No newline at end of file
h2/src/tools/org/h2/dev/fs/FileShell.java
浏览文件 @
ab2f646c
...
...
@@ -215,7 +215,7 @@ public class FileShell extends Tool {
for
(
String
file
:
FileUtils
.
listFiles
(
dir
))
{
StringBuilder
buff
=
new
StringBuilder
();
buff
.
append
(
FileUtils
.
isDirectory
(
file
)
?
"d"
:
"-"
);
buff
.
append
(
FileUtils
.
isReadOnly
(
file
)
?
"r-"
:
"rw
"
);
buff
.
append
(
FileUtils
.
canWrite
(
file
)
?
"rw"
:
"r-
"
);
buff
.
append
(
' '
);
buff
.
append
(
String
.
format
(
"%10d"
,
FileUtils
.
size
(
file
)));
buff
.
append
(
' '
);
...
...
h2/src/tools/org/h2/dev/fs/FileSystemZip2.java
浏览文件 @
ab2f646c
...
...
@@ -44,10 +44,6 @@ public class FileSystemZip2 extends FileSystem {
return
INSTANCE
;
}
public
boolean
canWrite
(
String
fileName
)
{
return
false
;
}
public
void
createDirectory
(
String
directoryName
)
{
// ignore
}
...
...
@@ -159,8 +155,8 @@ public class FileSystemZip2 extends FileSystem {
}
}
public
boolean
isReadOnly
(
String
fileName
)
{
return
tru
e
;
public
boolean
canWrite
(
String
fileName
)
{
return
fals
e
;
}
public
boolean
setReadOnly
(
String
fileName
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论