下面列出了java.nio.MappedByteBuffer#slice ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@DataProvider(name = "badBuffers")
static Object[][] createBadBuffers() throws Exception {
FileChannel fc = FileChannel.open(bob);
closeables.add(fc);
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10);
return new Object[][] {
{ ByteBuffer.allocate(0) },
{ ByteBuffer.allocate(10) },
{ ByteBuffer.allocate(10).duplicate() },
{ ByteBuffer.allocate(10).slice() },
{ ByteBuffer.allocateDirect(10).duplicate() },
{ ByteBuffer.allocateDirect(10).slice() },
{ ByteBuffer.allocateDirect(0).duplicate() },
{ ByteBuffer.allocateDirect(0).slice() },
{ mbb.duplicate() },
{ mbb.slice() }
};
}
private synchronized void grow() {
try {
long start = this.units.size() * Unit.SIZE;
MappedByteBuffer mmf = this.ch.map(MapMode.READ_WRITE, start, Unit.SIZE * 100);
this.mmfs.add(mmf);
mmf.order(ByteOrder.nativeOrder());
for (int i=0; i<100; i++) {
Unit ii = new Unit();
mmf.position(i * Unit.SIZE);
mmf.limit(mmf.position() + Unit.SIZE);
ii.buf = mmf.slice();
ii.addr = UberUtil.getAddress(ii.buf);
this.units.add(ii);
}
}
catch (Exception ignored) {
// if it fails then nothing is logged
}
}
public static void readLine() throws Exception {
File file = new File("E:\\demo");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024 * 10);
int offset = 0;
byte[] body = ("这里是上海" + System.lineSeparator()).getBytes();
while (true) {
if (offset + body.length <= 10240) {
ByteBuffer slice = buffer.slice();
slice.position(offset);
slice.put(body);
offset += body.length;
buffer.force();
}
else {
break;
}
}
channel.close();
System.out.println(file.getPath() + ".dat");
file.renameTo(new File(file.getPath() + ".dat"));
}
public ByteBuffer[] sliceTerms()
{
final ByteBuffer[] terms = new ByteBuffer[PARTITION_COUNT];
if (termLength < ONE_GIG)
{
final MappedByteBuffer buffer = mappedBuffers[0];
for (int i = 0; i < PARTITION_COUNT; i++)
{
buffer.limit((termLength * i) + termLength).position(termLength * i);
terms[i] = buffer.slice();
}
}
else
{
for (int i = 0; i < PARTITION_COUNT; i++)
{
terms[i] = mappedBuffers[i].duplicate();
}
}
return terms;
}
private void open(boolean write) throws IOException {
if (this.raf != null) {
return;
}
// rename the existing file so we dont accidently lose previous crash scene
if (write && file.exists()) {
String filename = file.getName();
filename = System.currentTimeMillis() + "-" + filename;
File backup = new File(file.getParentFile(), filename);
file.renameTo(backup);
}
// open it
this.raf = new RandomAccessFile(file, write ? "rw" : "r");
this.ch = this.raf.getChannel();
// map units if this is read only
if (!write) {
int nbuffers = (int)(this.file.length() / Unit.SIZE);
MappedByteBuffer mmf = raf.getChannel().map(MapMode.READ_ONLY, 0, Unit.SIZE * nbuffers);
this.mmfs.add(mmf);
mmf.order(ByteOrder.nativeOrder());
for (int i=0; i<nbuffers; i++) {
Unit ii = new Unit();
mmf.position(i * Unit.SIZE);
mmf.limit(mmf.position() + Unit.SIZE);
ii.buf = mmf.slice();
ii.addr = UberUtil.getAddress(ii.buf);
this.units.add(ii);
}
this.ch.close();
this.raf.close();
}
}
MappedJournalSegmentWriter(
MappedByteBuffer buffer,
JournalSegment<E> segment,
int maxEntrySize,
JournalIndex index,
Namespace namespace) {
this.mappedBuffer = buffer;
this.buffer = buffer.slice();
this.segment = segment;
this.maxEntrySize = maxEntrySize;
this.index = index;
this.namespace = namespace;
this.firstIndex = segment.index();
reset(0);
}
private static void resetSymbolAddressesInExportInfo(
MappedByteBuffer machoBuffer, MachoDyldInfoCommand dyldInfoCommand) {
machoBuffer.position(dyldInfoCommand.getExportInfoOffset());
machoBuffer.limit(dyldInfoCommand.getExportInfoOffset() + dyldInfoCommand.getExportInfoSize());
ByteBuffer exportInfoBuffer = machoBuffer.slice();
Optional<MachoExportTrieNode> tree = MachoExportTrieReader.read(exportInfoBuffer);
if (tree.isPresent()) {
resetSymbolAddressesInTree(tree.get());
// We want to reset all addresses to zero and write out a new tree rather than just setting
// all existing addresses to zero: that's because symbol offset sizes depends on the offsets
// themselves, so we want to make the scrubbed dylib stub be independent from those addresses.
// Otherwise, it's possible that the dylib stub will be logically the same (i.e., all
// addresses zero) but different on disk due to zero being expressed using different number
// of ULEB128 bytes.
exportInfoBuffer.rewind();
MachoExportTrieWriter.write(tree.get(), exportInfoBuffer);
// As we set all addresses to 0x0, that means the total size of the trie will _never_ be
// larger than the initial trie. Consequently, we do not need to adjust segment sizes and
// just need to zero out any remaining parts in the export section.
while (exportInfoBuffer.position() < exportInfoBuffer.limit()) {
exportInfoBuffer.put((byte) 0x00);
}
}
}
private Optional<MachoExportTrieNode> readExportTrieFromBuffer(MappedByteBuffer dylibBuffer) {
Optional<MachoDyldInfoCommand> maybeDyldInfoCommand =
MachoDyldInfoCommandReader.read(dylibBuffer);
assertTrue(maybeDyldInfoCommand.isPresent());
MachoDyldInfoCommand dyldInfoCommand = maybeDyldInfoCommand.get();
dylibBuffer.position(dyldInfoCommand.getExportInfoOffset());
ByteBuffer exportTrieByteBuffer = dylibBuffer.slice();
exportTrieByteBuffer.limit(dyldInfoCommand.getExportInfoSize());
return MachoExportTrieReader.read(exportTrieByteBuffer);
}
@Test
public void testScrubber() throws IOException, FileScrubber.ScrubException, InterruptedException {
assumeTrue(Platform.detect() == Platform.MACOS);
assumeTrue(AppleNativeIntegrationTestUtils.isApplePlatformAvailable(ApplePlatform.MACOSX));
// Copy the source dylib, so we can scrub the temporary copy
Path srcDylibPath = getHelloLibDylibPath();
Path destFolder = tmp.newFolder();
Path destDylibPath = destFolder.resolve(srcDylibPath.getFileName());
Files.copy(srcDylibPath, destDylibPath);
FileChannel dylibChannel =
FileChannel.open(destDylibPath, StandardOpenOption.READ, StandardOpenOption.WRITE);
DylibStubContentsScrubber scrubber = new DylibStubContentsScrubber();
scrubber.scrubFile(dylibChannel);
// Read the DYLD info, so we can get the offset to the export trie + read it
MappedByteBuffer dylibByteBuffer =
dylibChannel.map(FileChannel.MapMode.READ_ONLY, 0, dylibChannel.size());
Optional<MachoDyldInfoCommand> maybeDyldInfo = MachoDyldInfoCommandReader.read(dylibByteBuffer);
assertTrue(maybeDyldInfo.isPresent());
dylibByteBuffer.position(maybeDyldInfo.get().getExportInfoOffset());
ByteBuffer exportInfoBuffer = dylibByteBuffer.slice();
exportInfoBuffer.limit(maybeDyldInfo.get().getExportInfoSize());
Optional<MachoExportTrieNode> maybeRoot = MachoExportTrieReader.read(exportInfoBuffer);
assertTrue(maybeRoot.isPresent());
List<MachoExportTrieNode> exportedSymbols = maybeRoot.get().collectNodesWithExportInfo();
assertThat(exportedSymbols.size(), equalTo(2));
for (MachoExportTrieNode node : exportedSymbols) {
assertTrue(node.getExportInfo().isPresent());
assertThat(node.getExportInfo().get().address, equalTo(0L));
}
String nmOutput = workspace.runCommand("nm", destDylibPath.toString()).getStdout().get();
assertFalse(nmOutput.isEmpty());
assertThat(nmOutput, containsString("0000000000000000 T _goodbye"));
assertThat(nmOutput, containsString("0000000000000000 T _hello"));
}