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 {
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
);
...
...
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 {
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
;
...
...
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 {
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
();
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
;
}
}
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
差异被折叠。
点击展开。
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 {
*/
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.
*
...
...
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 {
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
));
...
...
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 {
}
}
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
}
...
...
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 {
*/
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
)
{
...
...
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 {
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
)
{
...
...
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;
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,12 +284,20 @@ public class FileUtils {
* @param dir the directory name
*/
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
);
createDirectories
(
parent
);
createDirectory
(
dir
);
}
}
}
/**
* 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
差异被折叠。
点击展开。
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.
*
...
...
This diff is collapsed.
Click to expand it.
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"
);
...
...
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 {
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."
);
}
...
...
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 {
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
]);
...
...
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 {
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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
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 {
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
)
{
...
...
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 {
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
(
' '
);
...
...
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 {
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
)
{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论