Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java命令或子程序,相当于bash strings命令_Java_Bash_Binaries - Fatal编程技术网

Java命令或子程序,相当于bash strings命令

Java命令或子程序,相当于bash strings命令,java,bash,binaries,Java,Bash,Binaries,在bash中我能做什么 strings someBinaryfile.exe 对于.exe(或.dll,或.so),它将只打印二进制文件的可读部分 java中是否有类似的库。我知道如何打开文件并打印它,但我只需要可读的部分。我不知道任何预先存在的Java库完全复制了字符串的功能。如果你想考虑自己实现它,那么我们可以阅读它来更好地了解需求: 对于给定的每个文件,GNU字符串打印可打印字符 长度至少为4个字符(或给定数字)的序列 和后接不可打印字符 因此,如果您想用纯Java代码实现您自己的解决方

bash中
我能做什么

strings someBinaryfile.exe
对于
.exe
(或
.dll
,或
.so
),它将只打印二进制文件的可读部分


java
中是否有类似的库。我知道如何打开文件并打印它,但我只需要可读的部分。

我不知道任何预先存在的Java库完全复制了
字符串的功能。如果你想考虑自己实现它,那么我们可以阅读它来更好地了解需求:

对于给定的每个文件,GNU字符串打印可打印字符 长度至少为4个字符(或给定数字)的序列 和后接不可打印字符

因此,如果您想用纯Java代码实现您自己的解决方案,那么您可以读取文件的每个字节,检查该字节是否可打印,并将这些字节的序列存储在缓冲区中。然后,一旦遇到不可打印的字符,如果缓冲区至少包含4个字节,则打印缓冲区的内容。例如:

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.File;
import java.io.IOException;

class Strings {

    private static final int MIN_STRING_LENGTH = 4;

    public static void main(String[] args) throws IOException {
        for (String arg : args) {
            File f = new File(arg);
            if (!f.exists()) {
                System.err.printf("error: no such file or directory: %s%n", arg);
                continue;
            }
            if (!f.canRead()) {
                System.err.printf("error: permission denied: %s%n", arg);
                continue;
            }
            if (f.isDirectory()) {
                System.err.printf("error: path is directory: %s%n", arg);
                continue;
            }
            try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(f));
                        ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                for (int b = is.read(); b != -1; b = is.read()) {
                    if (b >= 0x20 && b < 0x7F) {
                        os.write(b);
                    } else {
                        if (os.size() >= MIN_STRING_LENGTH) {
                            System.out.println(new String(os.toByteArray(), "US-ASCII"));
                        }
                        os.reset();
                    }
                }
                if (os.size() >= MIN_STRING_LENGTH) {
                    System.out.println(new String(os.toByteArray(), "US-ASCII"));
                }
            }
        }
    }
}
import java.io.BufferedInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.FileInputStream;
导入java.io.File;
导入java.io.IOException;
类字符串{
私有静态最终整数最小字符串长度=4;
公共静态void main(字符串[]args)引发IOException{
for(字符串arg:args){
文件f=新文件(arg);
如果(!f.exists()){
System.err.printf(“错误:没有这样的文件或目录:%s%n”,arg);
持续
}
如果(!f.canRead()){
System.err.printf(“错误:权限被拒绝:%s%n”,arg);
持续
}
if(f.isDirectory()){
System.err.printf(“错误:路径是目录:%s%n”,arg);
持续
}
try(BufferedInputStream is=new BufferedInputStream(new FileInputStream(f));
ByteArrayOutputStream os=新建ByteArrayOutputStream()){
for(int b=is.read();b!=-1;b=is.read()){
如果(b>=0x20&&b<0x7F){
os.write(b);
}否则{
如果(os.size()>=最小字符串长度){
System.out.println(新字符串(os.toByteArray(),“US-ASCII”);
}
os.reset();
}
}
如果(os.size()>=最小字符串长度){
System.out.println(新字符串(os.toByteArray(),“US-ASCII”);
}
}
}
}
}
这将涵盖
字符串
功能的基本近似值,但还有更多细节需要考虑:

默认情况下,它仅打印初始化和加载的 对象文件的部分;对于其他类型的文件,它会打印 整个文件中的字符串

实现这一部分会变得更加复杂,因为您需要解析和理解二进制文件格式的不同部分,例如或

另一个复杂问题是字符编码:

-e编码 --encoding=encoding选择要查找的字符串的字符编码。编码的可能值为:s= 单7位字节字符(ASCII、ISO 8859等,默认值),S= 单8位字节字符,b=16位双字节,l=16位 littleendian,B=32位bigendian,L=32位littleendian。有用的 用于查找宽字符串。(l和b适用于,例如, Unicode UTF-16/UCS-2编码)

我上面描述的更简单的逻辑假设为单字节字符。如果需要在多字节字符编码中识别字符串,那么逻辑将需要在管理缓冲区、检查可打印性和检查字符串长度方面更加小心

您可以将许多其他参数传递到
字符串
,所有这些参数都在手册页中描述。如果您需要完全复制所有这些功能,那么它将使逻辑更加复杂


如果您不想实现这一点,那么可以直接通过类fork和执行
字符串
,并解析输出。取舍是,它引入了一个外部依赖项,您的代码必须在安装了
字符串的平台上运行,并且会产生一些开销来分叉和执行外部进程。根据具体情况,您的应用程序可能会或可能不会接受这种权衡。

感谢您将问题格式化@Inian
strings
不是
bash
命令;它是一个独立的程序,可以从Java程序运行,也可以从
bash
脚本运行。我理解@chepner——除此之外,Java中是否有类似用途的库?例如ApacheCommons(尽管我在ApacheCommons库中找不到类似的函数)太棒了!与gnu strings命令非常接近。谢谢@chris nauroth