如何读取Windows NTFS';使用Java';木卫一?
我试图让Java应用程序读取给定路径中的所有数据。文件、目录、元数据等等。这还包括NTFS称之为备用数据流(ADS)的一个奇怪的东西 显然,它就像目录或文件中的第二层数据。您可以打开命令提示符并使用“:”在ADS中创建文件,例如:如何读取Windows NTFS';使用Java';木卫一?,java,io,java-io,ntfs,alternate-data-stream,Java,Io,Java Io,Ntfs,Alternate Data Stream,我试图让Java应用程序读取给定路径中的所有数据。文件、目录、元数据等等。这还包括NTFS称之为备用数据流(ADS)的一个奇怪的东西 显然,它就像目录或文件中的第二层数据。您可以打开命令提示符并使用“:”在ADS中创建文件,例如: C:\ADSTest> echo test>:ads.txt 所以 应该打开一个包含字符串“test”的记事本。但是,如果您这样做了: C:\ADSTest> dir 您将无法看到ads.txt。但是,如果您使用显示ADS数据的dir选项,您将能
C:\ADSTest> echo test>:ads.txt
所以
应该打开一个包含字符串“test”的记事本。但是,如果您这样做了:
C:\ADSTest> dir
您将无法看到ads.txt。但是,如果您使用显示ADS数据的dir选项,您将能够看到它:
C:\ADSTest> dir /r
MM/dd/yyyy hh:mm .:ads.txt
现在,我知道JavaIO有阅读广告的能力。我怎么知道的?嗯,:
如果文件系统实现支持文件属性
如果不能满足您的需要,您可以使用
UserDefinedAttributeView可创建和跟踪您自己的文件属性
有些实现将此概念映射到NTFS等功能
文件系统上的替代数据流和扩展属性,如
与ext3和ZFS一样
而且
数据存储在NTFS备用数据流(ADS)中,这些数据流是
通过JavaIO可读(我已经测试过了)
问题是,我找不到任何可以解析广告的预写文件属性查看器,我也不知道如何编写自己的广告解析器。我是一个初学者程序员,所以我觉得这是我的头。有人能帮我吗?或者给我指出正确的方向
解决方案
编辑:在@knosrtum的帮助下,我发明了一种方法,将给定路径中的所有解析广告信息作为字符串数组列表返回(也可以轻松编辑为文件数组列表)。以下是可能需要它的任何人的代码:
public class ADSReader {
public static ArrayList<String> start(Path toParse) {
String path = toParse.toString();
ArrayList<String> parsedADS = new ArrayList<>();
final String command = "cmd.exe /c dir " + path + " /r"; // listing of given Path.
final Pattern pattern = Pattern.compile(
"\\s*" // any amount of whitespace
+ "[0123456789,]+\\s*" // digits (with possible comma), whitespace
+ "([^:]+:" // group 1 = file name, then colon,
+ "[^:]+:" // then ADS, then colon,
+ ".+)"); // then everything else.
try {
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = br.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
parsedADS.add((matcher.group(1)));
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int z = 0; z<parsedADS.size(); z++)
System.out.println(parsedADS.get(z));
return parsedADS;
}
}
公共类ADSReader{
公共静态ArrayList开始(路径toParse){
字符串路径=toParse.toString();
ArrayList parsedADS=新的ArrayList();
final String command=“cmd.exe/c dir”+path+“/r”;//给定路径的列表。
最终模式=Pattern.compile(
“\\s*”//任意数量的空白
+[0123456789,]+\\s*“//数字(可能带有逗号),空格
+([^:::+:“//组1=文件名,然后是冒号,
+“[^::::+:”//然后是广告,然后是冒号,
+“+);//然后是其他一切。
试一试{
Process Process=Runtime.getRuntime().exec(命令);
process.waitFor();
try(BufferedReader br=新的BufferedReader(
新的InputStreamReader(process.getInputStream())){
弦线;
而((line=br.readLine())!=null){
匹配器匹配器=模式匹配器(线);
if(matcher.matches()){
add((matcher.group(1));
}
}
}
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}
对于(intz=0;z我可以通过打开文件的语法“file_name:stream_name”来读取文件的广告。如果您已经这样做了:
C:>echo Hidden text > test.txt:hidden
那么您应该能够做到这一点:
package net.snortum.play;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class AdsPlay {
public static void main(String[] args) {
new AdsPlay().start();
}
private void start() {
File file = new File("test.txt:hidden");
try (BufferedReader bf = new BufferedReader( new FileReader(file))) {
String hidden = bf.readLine();
System.out.println(hidden);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果您想从dir/r
命令获取ADS数据,我认为您只需要执行一个shell并捕获输出:
package net.snortum.play;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExecPlay {
public static void main(String[] args) {
new ExecPlay().start();
}
private void start() {
String fileName = "not found";
String ads = "not found";
final String command = "cmd.exe /c dir /r"; // listing of current directory
final Pattern pattern = Pattern.compile(
"\\s*" // any amount of whitespace
+ "[0123456789,]+\\s*" // digits (with possible comma), whitespace
+ "([^:]+):" // group 1 = file name, then colon
+ "([^:]+):" // group 2 = ADS, then colon
+ ".+"); // everything else
try {
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = br.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
fileName = matcher.group(1);
ads = matcher.group(2);
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(fileName + ", " + ads);
}
}
现在,您可以使用第一个代码列表来打印ADS数据。Cool!但是,正如我在原始帖子中所述,我需要此功能来读取给定路径中的所有数据。如果您运行DIR/r
,请将其想象为Windows DIR命令。通常,我会使用DirectoryStream=Files.newDirectoryStream(localDir)
,但这不会读取ADS。因此,我需要能够检测文件流中的ADS数据,并将其放入路径的ArrayList中。我必须如何修改此代码以适应此情况?感谢您的编辑,但有没有办法将其转换为返回特定ADS路径或路径类对象的ArrayList的方法一个ADS路径(理想情况下仅使用Java IO实现),这样我就可以将它插入我的应用程序的ArrayList中,该ArrayList已经包含了所有正常解析的路径,将传递给我的筛选和排序方法。如果你确切知道ADS名称,你可以使用NIO编写代码来读取或测试它。在上面的示例中,ADS名称将是“隐藏”的.但是如果你不知道确切的名称,我不知道Java IO如何判断文件上是否有广告信息。我想你必须使用我上面写的dir/r
解析器。我通过稍微调整你的代码,成功地编造了一个符合我需要的方法。非常感谢,我学到了很多新东西!
package net.snortum.play;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExecPlay {
public static void main(String[] args) {
new ExecPlay().start();
}
private void start() {
String fileName = "not found";
String ads = "not found";
final String command = "cmd.exe /c dir /r"; // listing of current directory
final Pattern pattern = Pattern.compile(
"\\s*" // any amount of whitespace
+ "[0123456789,]+\\s*" // digits (with possible comma), whitespace
+ "([^:]+):" // group 1 = file name, then colon
+ "([^:]+):" // group 2 = ADS, then colon
+ ".+"); // everything else
try {
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = br.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
fileName = matcher.group(1);
ads = matcher.group(2);
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(fileName + ", " + ads);
}
}