我正在寻找一种逐行读取文件中十六进制字符串的方法,并将它们作为转换后的字节附加到某些ByteBuffer。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<div class="ui-widget">
<label for="tags">Tags:</label>
<input id="tags" />
<div id="tagsname"></div>
</div>
<button type="button" id="getValue">Get value</button>
已经回答了一百万次。但我想知道是否有使用ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
Files.lines(filePath).foreach( l ->
byteBuffer.put(
// first of all strip newlines and normalize string
l.replaceAll("/\n|\r/g", "").toUpperCase()
// but what to do here?
// is there something like
// take next 2 characters (-> Consumer)
// and replace them with the converted byte?
// E.g. "C8" -> 0xC8
// until the end of the string is reached
)
);
返回的流的解决方案。
一般来说,我喜欢this回答。任何人都可以帮我翻译成基于java-8流的解决方案或从上面完成我的例子吗?
谢谢!
答案 0 :(得分:1)
您可以使用实用程序方法将行解析为字符串数组的十六进制字符串:
public static byte[] hexStringToByteArray(String str) {
if(str.startsWith("0x")) { // Get rid of potential prefix
str = str.substring(2);
}
if(str.length() % 2 != 0) { // If string is not of even length
str = '0' + str; // Assume leading zeroes were left out
}
byte[] result = new byte[str.length() / 2];
for(int i = 0; i < str.length(); i += 2) {
String nextByte = str.charAt(i) + "" + str.charAt(i + 1);
// To avoid overflow, parse as int and truncate:
result[i / 2] = (byte) Integer.parseInt(nextByte, 16);
}
return result;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
Files.lines(filePath).forEach( l ->
byteBuffer.put(
hexStringToByteArray(l.replaceAll("/\n|\r/g", "").toUpperCase())
)
);
答案 1 :(得分:1)
这看起来有点像xy problem,因为读取文件“逐行”已经是您尝试的解决方案的一部分,而实际任务不包括任何阅读文件“逐行”。
实际上,您希望处理源的所有十六进制数,而不管行终结符,这是java.util.Scanner
的作业。它还允许使用Stream API处理项目,但与循环相比,此特定任务不会从中受益:
ByteBuffer bb = ByteBuffer.allocate(1024);
try(Scanner s = new Scanner(yourFile)) {
s.findAll("[0-9A-Fa-f]{2}")
.mapToInt(m -> Integer.parseInt(m.group(), 16))
.forEachOrdered(i -> { if(bb.hasRemaining()) bb.put((byte)i); });
}
try(Scanner s = new Scanner(yourFile)) {
Pattern p = Pattern.compile("[0-9A-Fa-f]{2}");
for(;;) {
String next = s.findWithinHorizon(p, 0);
if(next == null) break;
if(!bb.hasRemaining()) // the thing hard to do with Stream API
bb = ByteBuffer.allocate(bb.capacity()*2).put(bb.flip());
bb.put((byte)Integer.parseInt(next, 16));
}
}
请注意,这些示例使用Java 9.在Java 8中,Buffer
返回的Buffer.flip()
需要将类型强制转换回ByteBuffer
并且Scanner.findAll
不可用但是被this answer中的后端口替换。