HADOOP-15170. Add symlink support to FileUtil#unTarUsingJava. Contributed by Ajay Kumar
This commit is contained in:
parent
4aef8bd2ef
commit
460d77bd64
@ -34,6 +34,8 @@
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.file.AccessDeniedException;
|
import java.nio.file.AccessDeniedException;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -894,7 +896,7 @@ private static void unTarUsingTar(File inFile, File untarDir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void unTarUsingJava(File inFile, File untarDir,
|
static void unTarUsingJava(File inFile, File untarDir,
|
||||||
boolean gzipped) throws IOException {
|
boolean gzipped) throws IOException {
|
||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
TarArchiveInputStream tis = null;
|
TarArchiveInputStream tis = null;
|
||||||
@ -956,6 +958,14 @@ private static void unpackEntries(TarArchiveInputStream tis,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entry.isSymbolicLink()) {
|
||||||
|
// Create symbolic link relative to tar parent dir
|
||||||
|
Files.createSymbolicLink(FileSystems.getDefault()
|
||||||
|
.getPath(outputDir.getPath(), entry.getName()),
|
||||||
|
FileSystems.getDefault().getPath(entry.getLinkName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
File outputFile = new File(outputDir, entry.getName());
|
File outputFile = new File(outputDir, entry.getName());
|
||||||
if (!outputFile.getParentFile().exists()) {
|
if (!outputFile.getParentFile().exists()) {
|
||||||
if (!outputFile.getParentFile().mkdirs()) {
|
if (!outputFile.getParentFile().mkdirs()) {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -37,6 +38,8 @@
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -47,6 +50,9 @@
|
|||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.test.GenericTestUtils;
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
@ -1173,4 +1179,84 @@ public void testCompareFsDirectories() throws Exception {
|
|||||||
assertEquals(FileUtil.compareFs(fs3,fs4),true);
|
assertEquals(FileUtil.compareFs(fs3,fs4),true);
|
||||||
assertEquals(FileUtil.compareFs(fs1,fs6),false);
|
assertEquals(FileUtil.compareFs(fs1,fs6),false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 8000)
|
||||||
|
public void testCreateSymbolicLinkUsingJava() throws IOException {
|
||||||
|
setupDirs();
|
||||||
|
final File simpleTar = new File(del, FILE);
|
||||||
|
OutputStream os = new FileOutputStream(simpleTar);
|
||||||
|
TarArchiveOutputStream tos = new TarArchiveOutputStream(os);
|
||||||
|
File untarFile = null;
|
||||||
|
try {
|
||||||
|
// Files to tar
|
||||||
|
final String tmpDir = "tmp/test";
|
||||||
|
File tmpDir1 = new File(tmpDir, "dir1/");
|
||||||
|
File tmpDir2 = new File(tmpDir, "dir2/");
|
||||||
|
// Delete the directories if they already exist
|
||||||
|
tmpDir1.mkdirs();
|
||||||
|
tmpDir2.mkdirs();
|
||||||
|
|
||||||
|
java.nio.file.Path symLink = FileSystems
|
||||||
|
.getDefault().getPath(tmpDir1.getPath() + "/sl");
|
||||||
|
|
||||||
|
// Create Symbolic Link
|
||||||
|
Files.createSymbolicLink(symLink,
|
||||||
|
FileSystems.getDefault().getPath(tmpDir2.getPath())).toString();
|
||||||
|
assertTrue(Files.isSymbolicLink(symLink.toAbsolutePath()));
|
||||||
|
// put entries in tar file
|
||||||
|
putEntriesInTar(tos, tmpDir1.getParentFile());
|
||||||
|
tos.close();
|
||||||
|
|
||||||
|
untarFile = new File(tmpDir, "2");
|
||||||
|
// Untar using java
|
||||||
|
FileUtil.unTarUsingJava(simpleTar, untarFile, false);
|
||||||
|
|
||||||
|
// Check symbolic link and other directories are there in untar file
|
||||||
|
assertTrue(Files.exists(untarFile.toPath()));
|
||||||
|
assertTrue(Files.exists(FileSystems.getDefault().getPath(untarFile
|
||||||
|
.getPath(), tmpDir)));
|
||||||
|
assertTrue(Files.isSymbolicLink(FileSystems.getDefault().getPath(untarFile
|
||||||
|
.getPath().toString(), symLink.toString())));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteDirectory(new File("tmp"));
|
||||||
|
tos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putEntriesInTar(TarArchiveOutputStream tos, File f)
|
||||||
|
throws IOException {
|
||||||
|
if (Files.isSymbolicLink(f.toPath())) {
|
||||||
|
TarArchiveEntry tarEntry = new TarArchiveEntry(f.getPath(),
|
||||||
|
TarArchiveEntry.LF_SYMLINK);
|
||||||
|
tarEntry.setLinkName(Files.readSymbolicLink(f.toPath()).toString());
|
||||||
|
tos.putArchiveEntry(tarEntry);
|
||||||
|
tos.closeArchiveEntry();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
tos.putArchiveEntry(new TarArchiveEntry(f));
|
||||||
|
tos.closeArchiveEntry();
|
||||||
|
for (File child : f.listFiles()) {
|
||||||
|
putEntriesInTar(tos, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.isFile()) {
|
||||||
|
tos.putArchiveEntry(new TarArchiveEntry(f));
|
||||||
|
BufferedInputStream origin = new BufferedInputStream(
|
||||||
|
new FileInputStream(f));
|
||||||
|
int count;
|
||||||
|
byte[] data = new byte[2048];
|
||||||
|
while ((count = origin.read(data)) != -1) {
|
||||||
|
tos.write(data, 0, count);
|
||||||
|
}
|
||||||
|
tos.flush();
|
||||||
|
tos.closeArchiveEntry();
|
||||||
|
origin.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user