我试图让我的 Java 应用程序读取给定路径中的所有数据。所以文件、目录、元数据等。这还包括 NTFS 称为备用数据流 (ADS) 的一件奇怪的事情。

显然它就像目录或文件中的第二层数据。您可以打开命令提示符并使用“:”在 ADS 中创建一个文件,例如:

C:\ADSTest> echo test>:ads.txt

所以,
C:\ADSTest> notepad :ads.txt

应该打开一个包含字符串“test”的记事本。但是,如果您这样做:
C:\ADSTest> dir

您将无法看到 ads.txt。但是,如果您使用显示 ADS 数据的 dir 选项,您将能够看到它:
C:\ADSTest> dir /r
MM/dd/yyyy hh:mm            .:ads.txt

现在,我知道 Java IO 具有读取 ADS 的能力。我怎么知道?好吧, Oracle's documentations clearly states so :



另外,a random post on a random forum :D



问题是,我找不到任何可以解析 ADS 的预先编写的文件属性查看器,而且我不明白如何编写自己的 ADS 解析器。我是一名初级程序员,所以我觉得这超出了我的范围。有人可以帮助我或指出我正确的方向吗?

解决方案

编辑: 在@knosrtum 的帮助下,我能够设计一种方法,该方法将从给定路径返回所有解析的 ADS 信息作为字符串的 ArrayList(它也可以轻松编辑为文件的 ArrayList)。这是任何可能需要它的人的代码:
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;

    }
}

最佳答案

我能够通过使用语法“file_name:stream_name”打开文件来读取文件的 ADS。所以如果你这样做了:

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);

    }
}

现在您可以使用第一个代码 list 来打印 ADS 数据。

关于java - 如何使用 Java 的 IO 读取 Windows NTFS 的备用数据流?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33085253/

10-12 01:45