2828import java .nio .file .Files ;
2929import java .nio .file .Path ;
3030import java .nio .file .Paths ;
31+ import java .nio .file .attribute .BasicFileAttributes ;
3132import java .util .stream .Stream ;
3233import org .apache .commons .compress .archivers .ArchiveEntry ;
3334import org .apache .commons .compress .archivers .ArchiveInputStream ;
3435import org .apache .commons .compress .archivers .ArchiveOutputStream ;
3536import org .apache .commons .compress .archivers .tar .TarArchiveEntry ;
3637import org .apache .commons .compress .archivers .tar .TarArchiveInputStream ;
3738import org .apache .commons .compress .archivers .tar .TarArchiveOutputStream ;
39+ import org .apache .commons .compress .archivers .tar .TarConstants ;
3840import org .apache .commons .io .IOUtils ;
3941import org .apache .hadoop .hdds .HddsUtils ;
4042import org .apache .hadoop .ozone .OzoneConsts ;
@@ -79,12 +81,42 @@ public static byte[] readEntry(InputStream input, final long size)
7981 return output .toByteArray ();
8082 }
8183
84+ private static TarArchiveEntry createBasicTarArchiveEntry (File file , String entryName )
85+ throws IOException {
86+ final Path path = file .toPath ();
87+
88+ final TarArchiveEntry entry ;
89+ if (Files .isDirectory (path )) {
90+ final int nameLength = entryName .length ();
91+ final String dirName = nameLength == 0 || entryName .charAt (nameLength - 1 ) != '/'
92+ ? entryName + "/"
93+ : entryName ;
94+ entry = new TarArchiveEntry (dirName , TarConstants .LF_DIR );
95+ entry .setMode (TarArchiveEntry .DEFAULT_DIR_MODE );
96+ } else {
97+ entry = new TarArchiveEntry (entryName );
98+ entry .setMode (TarArchiveEntry .DEFAULT_FILE_MODE );
99+ entry .setSize (Files .size (path ));
100+ }
101+
102+ try {
103+ BasicFileAttributes attrs = Files .readAttributes (
104+ file .toPath (), BasicFileAttributes .class );
105+ entry .setLastModifiedTime (attrs .lastModifiedTime ());
106+ entry .setLastAccessTime (attrs .lastAccessTime ());
107+ entry .setCreationTime (attrs .creationTime ());
108+ } catch (IOException e ) {
109+ entry .setModTime (file .lastModified ()); // fallback
110+ }
111+ return entry ;
112+ }
113+
82114 public static void includePath (Path dir , String subdir ,
83115 ArchiveOutputStream <TarArchiveEntry > archiveOutput ) throws IOException {
84116
85117 // Add a directory entry before adding files, in case the directory is
86118 // empty.
87- TarArchiveEntry entry = archiveOutput . createArchiveEntry (dir .toFile (), subdir );
119+ TarArchiveEntry entry = createBasicTarArchiveEntry (dir .toFile (), subdir );
88120 archiveOutput .putArchiveEntry (entry );
89121 archiveOutput .closeArchiveEntry ();
90122
@@ -105,7 +137,7 @@ public static void includePath(Path dir, String subdir,
105137 public static long includeFile (File file , String entryName ,
106138 ArchiveOutputStream <TarArchiveEntry > archiveOutput ) throws IOException {
107139 final long bytes ;
108- TarArchiveEntry entry = archiveOutput . createArchiveEntry (file , entryName );
140+ TarArchiveEntry entry = createBasicTarArchiveEntry (file , entryName );
109141 archiveOutput .putArchiveEntry (entry );
110142 try (InputStream input = Files .newInputStream (file .toPath ())) {
111143 bytes = IOUtils .copy (input , archiveOutput , getBufferSize (file .length ()));
@@ -138,7 +170,7 @@ public static long linkAndIncludeFile(File file, String entryName,
138170 long bytes = 0 ;
139171 try {
140172 Files .createLink (link .toPath (), file .toPath ());
141- TarArchiveEntry entry = archiveOutput . createArchiveEntry (link , entryName );
173+ TarArchiveEntry entry = createBasicTarArchiveEntry (link , entryName );
142174 archiveOutput .putArchiveEntry (entry );
143175 try (InputStream input = Files .newInputStream (link .toPath ())) {
144176 bytes = IOUtils .copyLarge (input , archiveOutput );
0 commit comments