Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
24fbe952
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
3
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
24fbe952
编写于
8月 20, 2009
作者:
A
alanb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6595866: File does work with symbolic links (win,vista)
Reviewed-by: sherman
上级
b345613e
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
594 addition
and
25 deletion
+594
-25
src/windows/native/java/io/WinNTFileSystem_md.c
src/windows/native/java/io/WinNTFileSystem_md.c
+214
-25
test/java/io/File/SymLinks.java
test/java/io/File/SymLinks.java
+380
-0
未找到文件。
src/windows/native/java/io/WinNTFileSystem_md.c
浏览文件 @
24fbe952
...
...
@@ -51,13 +51,25 @@ static struct {
jfieldID
path
;
}
ids
;
/**
* GetFinalPathNameByHandle is available on Windows Vista and newer
*/
typedef
BOOL
(
WINAPI
*
GetFinalPathNameByHandleProc
)
(
HANDLE
,
LPWSTR
,
DWORD
,
DWORD
);
static
GetFinalPathNameByHandleProc
GetFinalPathNameByHandle_func
;
JNIEXPORT
void
JNICALL
Java_java_io_WinNTFileSystem_initIDs
(
JNIEnv
*
env
,
jclass
cls
)
{
HANDLE
handle
;
jclass
fileClass
=
(
*
env
)
->
FindClass
(
env
,
"java/io/File"
);
if
(
!
fileClass
)
return
;
ids
.
path
=
(
*
env
)
->
GetFieldID
(
env
,
fileClass
,
"path"
,
"Ljava/lang/String;"
);
handle
=
LoadLibrary
(
"kernel32"
);
if
(
handle
!=
NULL
)
{
GetFinalPathNameByHandle_func
=
(
GetFinalPathNameByHandleProc
)
GetProcAddress
(
handle
,
"GetFinalPathNameByHandleW"
);
}
}
/* -- Path operations -- */
...
...
@@ -65,6 +77,138 @@ Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls)
extern
int
wcanonicalize
(
const
WCHAR
*
path
,
WCHAR
*
out
,
int
len
);
extern
int
wcanonicalizeWithPrefix
(
const
WCHAR
*
canonicalPrefix
,
const
WCHAR
*
pathWithCanonicalPrefix
,
WCHAR
*
out
,
int
len
);
/**
* Retrieves the fully resolved (final) path for the given path or NULL
* if the function fails.
*/
static
WCHAR
*
getFinalPath
(
const
WCHAR
*
path
)
{
HANDLE
h
;
WCHAR
*
result
;
DWORD
error
;
/* Need Windows Vista or newer to get the final path */
if
(
GetFinalPathNameByHandle_func
==
NULL
)
return
NULL
;
h
=
CreateFileW
(
path
,
FILE_READ_ATTRIBUTES
,
FILE_SHARE_DELETE
|
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
FILE_FLAG_BACKUP_SEMANTICS
,
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
return
NULL
;
/**
* Allocate a buffer for the resolved path. For a long path we may need
* to allocate a larger buffer.
*/
result
=
(
WCHAR
*
)
malloc
(
MAX_PATH
*
sizeof
(
WCHAR
));
if
(
result
!=
NULL
)
{
DWORD
len
=
(
*
GetFinalPathNameByHandle_func
)(
h
,
result
,
MAX_PATH
,
0
);
if
(
len
>=
MAX_PATH
)
{
/* retry with a buffer of the right size */
result
=
(
WCHAR
*
)
realloc
(
result
,
(
len
+
1
)
*
sizeof
(
WCHAR
));
if
(
result
!=
NULL
)
{
len
=
(
*
GetFinalPathNameByHandle_func
)(
h
,
result
,
len
,
0
);
}
else
{
len
=
0
;
}
}
if
(
len
>
0
)
{
/**
* Strip prefix (should be \\?\ or \\?\UNC)
*/
if
(
result
[
0
]
==
L'\\'
&&
result
[
1
]
==
L'\\'
&&
result
[
2
]
==
L'?'
&&
result
[
3
]
==
L'\\'
)
{
int
isUnc
=
(
result
[
4
]
==
L'U'
&&
result
[
5
]
==
L'N'
&&
result
[
6
]
==
L'C'
);
int
prefixLen
=
(
isUnc
)
?
7
:
4
;
/* actual result length (includes terminator) */
int
resultLen
=
len
-
prefixLen
+
(
isUnc
?
1
:
0
)
+
1
;
/* copy result without prefix into new buffer */
WCHAR
*
tmp
=
(
WCHAR
*
)
malloc
(
resultLen
*
sizeof
(
WCHAR
));
if
(
tmp
==
NULL
)
{
len
=
0
;
}
else
{
WCHAR
*
p
=
result
;
p
+=
prefixLen
;
if
(
isUnc
)
{
WCHAR
*
p2
=
tmp
;
p2
[
0
]
=
L'\\'
;
p2
++
;
wcscpy
(
p2
,
p
);
}
else
{
wcscpy
(
tmp
,
p
);
}
free
(
result
);
result
=
tmp
;
}
}
}
/* unable to get final path */
if
(
len
==
0
&&
result
!=
NULL
)
{
free
(
result
);
result
=
NULL
;
}
}
error
=
GetLastError
();
if
(
CloseHandle
(
h
))
SetLastError
(
error
);
return
result
;
}
/**
* Retrieves file information for the specified file. If the file is
* symbolic link then the information on fully resolved target is
* returned.
*/
static
BOOL
getFileInformation
(
const
WCHAR
*
path
,
BY_HANDLE_FILE_INFORMATION
*
finfo
)
{
BOOL
result
;
DWORD
error
;
HANDLE
h
=
CreateFileW
(
path
,
FILE_READ_ATTRIBUTES
,
FILE_SHARE_DELETE
|
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
FILE_FLAG_BACKUP_SEMANTICS
,
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
return
FALSE
;
result
=
GetFileInformationByHandle
(
h
,
finfo
);
error
=
GetLastError
();
if
(
CloseHandle
(
h
))
SetLastError
(
error
);
return
result
;
}
/**
* If the given attributes are the attributes of a reparse point, then
* read and return the attributes of the final target.
*/
DWORD
getFinalAttributesIfReparsePoint
(
WCHAR
*
path
,
DWORD
a
)
{
if
((
a
!=
INVALID_FILE_ATTRIBUTES
)
&&
((
a
&
FILE_ATTRIBUTE_REPARSE_POINT
)
!=
0
))
{
BY_HANDLE_FILE_INFORMATION
finfo
;
BOOL
res
=
getFileInformation
(
path
,
&
finfo
);
a
=
(
res
)
?
finfo
.
dwFileAttributes
:
INVALID_FILE_ATTRIBUTES
;
}
return
a
;
}
JNIEXPORT
jstring
JNICALL
Java_java_io_WinNTFileSystem_canonicalize0
(
JNIEnv
*
env
,
jobject
this
,
jstring
pathname
)
...
...
@@ -202,12 +346,15 @@ Java_java_io_WinNTFileSystem_getBooleanAttributes(JNIEnv *env, jobject this,
return
rv
;
if
(
!
isReservedDeviceNameW
(
pathbuf
))
{
if
(
GetFileAttributesExW
(
pathbuf
,
GetFileExInfoStandard
,
&
wfad
))
{
DWORD
a
=
getFinalAttributesIfReparsePoint
(
pathbuf
,
wfad
.
dwFileAttributes
);
if
(
a
!=
INVALID_FILE_ATTRIBUTES
)
{
rv
=
(
java_io_FileSystem_BA_EXISTS
|
((
wfad
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
|
((
a
&
FILE_ATTRIBUTE_DIRECTORY
)
?
java_io_FileSystem_BA_DIRECTORY
:
java_io_FileSystem_BA_REGULAR
)
|
((
wfad
.
dwFileAttributes
&
FILE_ATTRIBUTE_HIDDEN
)
|
((
a
&
FILE_ATTRIBUTE_HIDDEN
)
?
java_io_FileSystem_BA_HIDDEN
:
0
));
}
}
else
{
/* pagefile.sys is a special case */
if
(
GetLastError
()
==
ERROR_SHARING_VIOLATION
)
{
rv
=
java_io_FileSystem_BA_EXISTS
;
...
...
@@ -234,6 +381,7 @@ JNICALL Java_java_io_WinNTFileSystem_checkAccess(JNIEnv *env, jobject this,
if
(
pathbuf
==
NULL
)
return
JNI_FALSE
;
attr
=
GetFileAttributesW
(
pathbuf
);
attr
=
getFinalAttributesIfReparsePoint
(
pathbuf
,
attr
);
free
(
pathbuf
);
if
(
attr
==
INVALID_FILE_ATTRIBUTES
)
return
JNI_FALSE
;
...
...
@@ -272,6 +420,20 @@ Java_java_io_WinNTFileSystem_setPermission(JNIEnv *env, jobject this,
if
(
pathbuf
==
NULL
)
return
JNI_FALSE
;
a
=
GetFileAttributesW
(
pathbuf
);
/* if reparse point, get final target */
if
((
a
!=
INVALID_FILE_ATTRIBUTES
)
&&
((
a
&
FILE_ATTRIBUTE_REPARSE_POINT
)
!=
0
))
{
WCHAR
*
fp
=
getFinalPath
(
pathbuf
);
if
(
fp
==
NULL
)
{
a
=
INVALID_FILE_ATTRIBUTES
;
}
else
{
free
(
pathbuf
);
pathbuf
=
fp
;
a
=
GetFileAttributesW
(
pathbuf
);
}
}
if
(
a
!=
INVALID_FILE_ATTRIBUTES
)
{
if
(
enable
)
a
=
a
&
~
FILE_ATTRIBUTE_READONLY
;
...
...
@@ -305,7 +467,7 @@ Java_java_io_WinNTFileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
/* Open existing or fail */
OPEN_EXISTING
,
/* Backup semantics for directories */
FILE_
ATTRIBUTE_NORMAL
|
FILE_
FLAG_BACKUP_SEMANTICS
,
FILE_FLAG_BACKUP_SEMANTICS
,
/* No template file */
NULL
);
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
...
...
@@ -332,7 +494,16 @@ Java_java_io_WinNTFileSystem_getLength(JNIEnv *env, jobject this, jobject file)
if
(
GetFileAttributesExW
(
pathbuf
,
GetFileExInfoStandard
,
&
wfad
))
{
if
((
wfad
.
dwFileAttributes
&
FILE_ATTRIBUTE_REPARSE_POINT
)
==
0
)
{
rv
=
wfad
.
nFileSizeHigh
*
((
jlong
)
MAXDWORD
+
1
)
+
wfad
.
nFileSizeLow
;
}
else
{
/* file is a reparse point so read attributes of final target */
BY_HANDLE_FILE_INFORMATION
finfo
;
if
(
getFileInformation
(
pathbuf
,
&
finfo
))
{
rv
=
finfo
.
nFileSizeHigh
*
((
jlong
)
MAXDWORD
+
1
)
+
finfo
.
nFileSizeLow
;
}
}
}
else
{
if
(
GetLastError
()
==
ERROR_SHARING_VIOLATION
)
{
/* The error is "share violation", which means the file/dir
...
...
@@ -365,19 +536,17 @@ Java_java_io_WinNTFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
/* File sharing flags */
NULL
,
/* Security attributes */
CREATE_NEW
,
/* creation disposition */
FILE_ATTRIBUTE_NORMAL
,
/* flags and attributes */
FILE_ATTRIBUTE_NORMAL
|
FILE_FLAG_OPEN_REPARSE_POINT
,
/* flags and attributes */
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
{
DWORD
error
=
GetLastError
();
if
((
error
!=
ERROR_FILE_EXISTS
)
&&
(
error
!=
ERROR_ALREADY_EXISTS
))
{
// If a directory by the named path already exists,
// return false (behavior of solaris and linux) instead of
// throwing an exception
DWORD
fattr
=
GetFileAttributesW
(
pathbuf
);
if
((
fattr
==
INVALID_FILE_ATTRIBUTES
)
||
(
fattr
&
~
FILE_ATTRIBUTE_DIRECTORY
))
{
// return false rather than throwing an exception when there is
// an existing file.
DWORD
a
=
GetFileAttributesW
(
pathbuf
);
if
(
a
==
INVALID_FILE_ATTRIBUTES
)
{
SetLastError
(
error
);
JNU_ThrowIOExceptionWithLastError
(
env
,
"Could not open file"
);
}
...
...
@@ -396,9 +565,9 @@ removeFileOrDirectory(const jchar *path)
/* Returns 0 on success */
DWORD
a
;
SetFileAttributesW
(
path
,
0
);
SetFileAttributesW
(
path
,
FILE_ATTRIBUTE_NORMAL
);
a
=
GetFileAttributesW
(
path
);
if
(
a
==
((
DWORD
)
-
1
)
)
{
if
(
a
==
INVALID_FILE_ATTRIBUTES
)
{
return
1
;
}
else
if
(
a
&
FILE_ATTRIBUTE_DIRECTORY
)
{
return
!
RemoveDirectoryW
(
path
);
...
...
@@ -578,8 +747,13 @@ Java_java_io_WinNTFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
HANDLE
h
;
if
(
pathbuf
==
NULL
)
return
JNI_FALSE
;
h
=
CreateFileW
(
pathbuf
,
GENERIC_WRITE
,
0
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
|
FILE_FLAG_BACKUP_SEMANTICS
,
0
);
h
=
CreateFileW
(
pathbuf
,
FILE_WRITE_ATTRIBUTES
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
FILE_FLAG_BACKUP_SEMANTICS
,
0
);
if
(
h
!=
INVALID_HANDLE_VALUE
)
{
LARGE_INTEGER
modTime
;
FILETIME
t
;
...
...
@@ -607,6 +781,21 @@ Java_java_io_WinNTFileSystem_setReadOnly(JNIEnv *env, jobject this,
if
(
pathbuf
==
NULL
)
return
JNI_FALSE
;
a
=
GetFileAttributesW
(
pathbuf
);
/* if reparse point, get final target */
if
((
a
!=
INVALID_FILE_ATTRIBUTES
)
&&
((
a
&
FILE_ATTRIBUTE_REPARSE_POINT
)
!=
0
))
{
WCHAR
*
fp
=
getFinalPath
(
pathbuf
);
if
(
fp
==
NULL
)
{
a
=
INVALID_FILE_ATTRIBUTES
;
}
else
{
free
(
pathbuf
);
pathbuf
=
fp
;
a
=
GetFileAttributesW
(
pathbuf
);
}
}
if
(
a
!=
INVALID_FILE_ATTRIBUTES
)
{
if
(
SetFileAttributesW
(
pathbuf
,
a
|
FILE_ATTRIBUTE_READONLY
))
rv
=
JNI_TRUE
;
...
...
test/java/io/File/SymLinks.java
0 → 100644
浏览文件 @
24fbe952
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @bug 6595866
* @summary Test java.io.File operations with sym links
*/
import
java.io.*
;
import
java.nio.file.Path
;
import
java.nio.file.attribute.*
;
import
static
java
.
nio
.
file
.
LinkOption
.*;
public
class
SymLinks
{
final
static
PrintStream
out
=
System
.
out
;
final
static
File
top
=
new
File
(
System
.
getProperty
(
"test.dir"
,
"."
));
// files used by the test
final
static
File
file
=
new
File
(
top
,
"foofile"
);
final
static
File
link2file
=
new
File
(
top
,
"link2file"
);
final
static
File
link2link2file
=
new
File
(
top
,
"link2link2file"
);
final
static
File
dir
=
new
File
(
top
,
"foodir"
);
final
static
File
link2dir
=
new
File
(
top
,
"link2dir"
);
final
static
File
link2link2dir
=
new
File
(
top
,
"link2link2dir"
);
final
static
File
link2nobody
=
new
File
(
top
,
"link2nobody"
);
final
static
File
link2link2nobody
=
new
File
(
top
,
"link2link2nobody"
);
/**
* Setup files, directories, and sym links used by test.
*/
static
void
setup
()
throws
IOException
{
// link2link2file -> link2file -> foofile
FileOutputStream
fos
=
new
FileOutputStream
(
file
);
try
{
fos
.
write
(
new
byte
[
16
*
1024
]);
}
finally
{
fos
.
close
();
}
mklink
(
link2file
,
file
);
mklink
(
link2link2file
,
link2file
);
// link2link2dir -> link2dir -> dir
assertTrue
(
dir
.
mkdir
());
mklink
(
link2dir
,
dir
);
mklink
(
link2link2dir
,
link2dir
);
// link2link2nobody -> link2nobody -> <does-not-exist>
mklink
(
link2nobody
,
new
File
(
top
,
"DoesNotExist"
));
mklink
(
link2link2nobody
,
link2nobody
);
}
/**
* Remove files, directories, and sym links used by test.
*/
static
void
cleanup
()
throws
IOException
{
if
(
file
!=
null
)
file
.
delete
();
if
(
link2file
!=
null
)
link2file
.
toPath
().
deleteIfExists
();
if
(
link2link2file
!=
null
)
link2link2file
.
toPath
().
deleteIfExists
();
if
(
dir
!=
null
)
dir
.
delete
();
if
(
link2dir
!=
null
)
link2dir
.
toPath
().
deleteIfExists
();
if
(
link2link2dir
!=
null
)
link2link2dir
.
toPath
().
deleteIfExists
();
if
(
link2nobody
!=
null
)
link2nobody
.
toPath
().
deleteIfExists
();
if
(
link2link2nobody
!=
null
)
link2link2nobody
.
toPath
().
deleteIfExists
();
}
/**
* Creates a sym link source->target
*/
static
void
mklink
(
File
source
,
File
target
)
throws
IOException
{
source
.
toPath
().
createSymbolicLink
(
target
.
toPath
());
}
/**
* Returns true if the "link" exists and is a sym link.
*/
static
boolean
isSymLink
(
File
link
)
{
try
{
BasicFileAttributes
attrs
=
Attributes
.
readBasicFileAttributes
(
link
.
toPath
(),
NOFOLLOW_LINKS
);
return
attrs
.
isSymbolicLink
();
}
catch
(
IOException
x
)
{
return
false
;
}
}
/**
* Returns the last modified time of a sym link.
*/
static
long
lastModifiedOfSymLink
(
File
link
)
throws
IOException
{
BasicFileAttributes
attrs
=
Attributes
.
readBasicFileAttributes
(
link
.
toPath
(),
NOFOLLOW_LINKS
);
assertTrue
(
attrs
.
isSymbolicLink
());
return
attrs
.
lastModifiedTime
().
toMillis
();
}
/**
* Returns true if sym links are supported on the file system where
* "dir" exists.
*/
static
boolean
supportsSymLinks
(
File
dir
)
{
Path
link
=
dir
.
toPath
().
resolve
(
"link"
);
Path
target
=
dir
.
toPath
().
resolve
(
"target"
);
try
{
link
.
createSymbolicLink
(
target
);
link
.
delete
();
return
true
;
}
catch
(
UnsupportedOperationException
x
)
{
return
false
;
}
catch
(
IOException
x
)
{
return
false
;
}
}
static
void
assertTrue
(
boolean
v
)
{
if
(!
v
)
throw
new
RuntimeException
(
"Test failed"
);
}
static
void
assertFalse
(
boolean
v
)
{
assertTrue
(!
v
);
}
static
void
header
(
String
h
)
{
out
.
println
();
out
.
println
();
out
.
println
(
"-- "
+
h
+
" --"
);
}
/**
* Tests go here.
*/
static
void
go
()
throws
IOException
{
// check setup
assertTrue
(
file
.
isFile
());
assertTrue
(
isSymLink
(
link2file
));
assertTrue
(
isSymLink
(
link2link2file
));
assertTrue
(
dir
.
isDirectory
());
assertTrue
(
isSymLink
(
link2dir
));
assertTrue
(
isSymLink
(
link2link2dir
));
assertTrue
(
isSymLink
(
link2nobody
));
assertTrue
(
isSymLink
(
link2link2nobody
));
header
(
"createNewFile"
);
assertFalse
(
file
.
createNewFile
());
assertFalse
(
link2file
.
createNewFile
());
assertFalse
(
link2link2file
.
createNewFile
());
assertFalse
(
dir
.
createNewFile
());
assertFalse
(
link2dir
.
createNewFile
());
assertFalse
(
link2link2dir
.
createNewFile
());
assertFalse
(
link2nobody
.
createNewFile
());
assertFalse
(
link2link2nobody
.
createNewFile
());
header
(
"mkdir"
);
assertFalse
(
file
.
mkdir
());
assertFalse
(
link2file
.
mkdir
());
assertFalse
(
link2link2file
.
mkdir
());
assertFalse
(
dir
.
mkdir
());
assertFalse
(
link2dir
.
mkdir
());
assertFalse
(
link2link2dir
.
mkdir
());
assertFalse
(
link2nobody
.
mkdir
());
assertFalse
(
link2link2nobody
.
mkdir
());
header
(
"delete"
);
File
link
=
new
File
(
top
,
"mylink"
);
try
{
mklink
(
link
,
file
);
assertTrue
(
link
.
delete
());
assertTrue
(!
isSymLink
(
link
));
assertTrue
(
file
.
exists
());
mklink
(
link
,
link2file
);
assertTrue
(
link
.
delete
());
assertTrue
(!
isSymLink
(
link
));
assertTrue
(
link2file
.
exists
());
mklink
(
link
,
dir
);
assertTrue
(
link
.
delete
());
assertTrue
(!
isSymLink
(
link
));
assertTrue
(
dir
.
exists
());
mklink
(
link
,
link2dir
);
assertTrue
(
link
.
delete
());
assertTrue
(!
isSymLink
(
link
));
assertTrue
(
link2dir
.
exists
());
mklink
(
link
,
link2nobody
);
assertTrue
(
link
.
delete
());
assertTrue
(!
isSymLink
(
link
));
assertTrue
(
isSymLink
(
link2nobody
));
}
finally
{
link
.
toPath
().
deleteIfExists
();
}
header
(
"renameTo"
);
File
newlink
=
new
File
(
top
,
"newlink"
);
assertTrue
(
link2file
.
renameTo
(
newlink
));
try
{
assertTrue
(
file
.
exists
());
assertTrue
(
isSymLink
(
newlink
));
assertTrue
(!
isSymLink
(
link2file
));
}
finally
{
newlink
.
renameTo
(
link2file
);
// restore link
}
assertTrue
(
link2dir
.
renameTo
(
newlink
));
try
{
assertTrue
(
dir
.
exists
());
assertTrue
(
isSymLink
(
newlink
));
assertTrue
(!
isSymLink
(
link2dir
));
}
finally
{
newlink
.
renameTo
(
link2dir
);
// restore link
}
header
(
"list"
);
final
String
name
=
"entry"
;
File
entry
=
new
File
(
dir
,
name
);
try
{
assertTrue
(
dir
.
list
().
length
==
0
);
// directory should be empty
assertTrue
(
link2dir
.
list
().
length
==
0
);
assertTrue
(
link2link2dir
.
list
().
length
==
0
);
assertTrue
(
entry
.
createNewFile
());
assertTrue
(
dir
.
list
().
length
==
1
);
assertTrue
(
dir
.
list
()[
0
].
equals
(
name
));
// access directory by following links
assertTrue
(
link2dir
.
list
().
length
==
1
);
assertTrue
(
link2dir
.
list
()[
0
].
equals
(
name
));
assertTrue
(
link2link2dir
.
list
().
length
==
1
);
assertTrue
(
link2link2dir
.
list
()[
0
].
equals
(
name
));
// files that are not directories
assertTrue
(
link2file
.
list
()
==
null
);
assertTrue
(
link2nobody
.
list
()
==
null
);
}
finally
{
entry
.
delete
();
}
header
(
"isXXX"
);
assertTrue
(
file
.
isFile
());
assertTrue
(
link2file
.
isFile
());
assertTrue
(
link2link2file
.
isFile
());
assertTrue
(
dir
.
isDirectory
());
assertTrue
(
link2dir
.
isDirectory
());
assertTrue
(
link2link2dir
.
isDirectory
());
// on Windows we test with the DOS hidden attribute set
if
(
System
.
getProperty
(
"os.name"
).
startsWith
(
"Windows"
))
{
DosFileAttributeView
view
=
file
.
toPath
()
.
getFileAttributeView
(
DosFileAttributeView
.
class
);
view
.
setHidden
(
true
);
try
{
assertTrue
(
file
.
isHidden
());
assertTrue
(
link2file
.
isHidden
());
assertTrue
(
link2link2file
.
isHidden
());
}
finally
{
view
.
setHidden
(
false
);
}
assertFalse
(
file
.
isHidden
());
assertFalse
(
link2file
.
isHidden
());
assertFalse
(
link2link2file
.
isHidden
());
}
header
(
"length"
);
long
len
=
file
.
length
();
assertTrue
(
len
>
0L
);
// these tests should follow links
assertTrue
(
link2file
.
length
()
==
len
);
assertTrue
(
link2link2file
.
length
()
==
len
);
assertTrue
(
link2nobody
.
length
()
==
0L
);
header
(
"lastModified / setLastModified"
);
// need time to diff between link and file
long
origLastModified
=
file
.
lastModified
();
assertTrue
(
origLastModified
!=
0L
);
try
{
Thread
.
sleep
(
2000
);
}
catch
(
InterruptedException
x
)
{
}
file
.
setLastModified
(
System
.
currentTimeMillis
());
long
lastModified
=
file
.
lastModified
();
assertTrue
(
lastModified
!=
origLastModified
);
assertTrue
(
lastModifiedOfSymLink
(
link2file
)
!=
lastModified
);
assertTrue
(
lastModifiedOfSymLink
(
link2link2file
)
!=
lastModified
);
assertTrue
(
link2file
.
lastModified
()
==
lastModified
);
assertTrue
(
link2link2file
.
lastModified
()
==
lastModified
);
assertTrue
(
link2nobody
.
lastModified
()
==
0L
);
origLastModified
=
dir
.
lastModified
();
assertTrue
(
origLastModified
!=
0L
);
dir
.
setLastModified
(
0L
);
assertTrue
(
dir
.
lastModified
()
==
0L
);
assertTrue
(
link2dir
.
lastModified
()
==
0L
);
assertTrue
(
link2link2dir
.
lastModified
()
==
0L
);
dir
.
setLastModified
(
origLastModified
);
header
(
"setXXX / canXXX"
);
assertTrue
(
file
.
canRead
());
assertTrue
(
file
.
canWrite
());
assertTrue
(
link2file
.
canRead
());
assertTrue
(
link2file
.
canWrite
());
assertTrue
(
link2link2file
.
canRead
());
assertTrue
(
link2link2file
.
canWrite
());
if
(
file
.
setReadOnly
())
{
assertFalse
(
file
.
canWrite
());
assertFalse
(
link2file
.
canWrite
());
assertFalse
(
link2link2file
.
canWrite
());
assertTrue
(
file
.
setWritable
(
true
));
// make writable
assertTrue
(
file
.
canWrite
());
assertTrue
(
link2file
.
canWrite
());
assertTrue
(
link2link2file
.
canWrite
());
assertTrue
(
link2file
.
setReadOnly
());
// make read only
assertFalse
(
file
.
canWrite
());
assertFalse
(
link2file
.
canWrite
());
assertFalse
(
link2link2file
.
canWrite
());
assertTrue
(
link2link2file
.
setWritable
(
true
));
// make writable
assertTrue
(
file
.
canWrite
());
assertTrue
(
link2file
.
canWrite
());
assertTrue
(
link2link2file
.
canWrite
());
}
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
if
(
supportsSymLinks
(
top
))
{
try
{
setup
();
go
();
}
finally
{
cleanup
();
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录