I was toying with the idea of rewriting some existing bash scripts in kotlin script.
One of the scripts has a section that unzips all the files in a directory. In bash:
unzip *.zip
Is there a nice way to unzip a file(s) in kotlin script?
The easiest way is to just use exec unzip (assuming that the name of your zip file is stored in zipFileName variable):
ProcessBuilder()
.command("unzip", zipFileName)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
.start()
.waitFor()
The different approach, that is more portable (it will run on any OS and does not require unzip executable to be present), but somewhat less feature-full (it will not restore Unix permissions), is to do unzipping in code:
import java.io.File
import java.util.zip.ZipFile
ZipFile(zipFileName).use { zip ->
zip.entries().asSequence().forEach { entry ->
zip.getInputStream(entry).use { input ->
File(entry.name).outputStream().use { output ->
input.copyTo(output)
}
}
}
}
If you need to scan all *.zip file, then you can do it like this:
File(".").list { _, name -> name.endsWith(".zip") }?.forEach { zipFileName ->
// any of the above approaches
}
or like this:
import java.nio.file.*
Files.newDirectoryStream(Paths.get("."), "*.zip").forEach { path ->
val zipFileName = path.toString()
// any of the above approaches
}
this code is for unziping from Assets
1.for unzping first u need InputStream
2.put it in ZipInputStream
3.if directory is not exist u have to make by .mkdirs()
private val BUFFER_SIZE = 8192//2048;
private val SDPath = Environment.getExternalStorageDirectory().absolutePath
private val unzipPath = "$SDPath/temp/zipunzipFile/unzip/"
var count: Int
val buffer = ByteArray(BUFFER_SIZE)
val context: Context = this
val am = context.getAssets()
val stream = context.getAssets().open("raw.zip")
try {
ZipInputStream(stream).use { zis ->
var ze: ZipEntry
while (zis.nextEntry.also { ze = it } != null) {
var fileName = ze.name
fileName = fileName.substring(fileName.indexOf("/") + 1)
val file = File(unzipPath, fileName)
val dir = if (ze.isDirectory) file else file.getParentFile()
if (!dir.isDirectory() && !dir.mkdirs())
throw FileNotFoundException("Invalid path: " + dir.getAbsolutePath())
if (ze.isDirectory) continue
val fout = FileOutputStream(file)
try {
while ( zis.read(buffer).also { count = it } != -1)
fout.write(buffer, 0, count)
} finally {
val fout : FileOutputStream =openFileOutput(fileName, Context.MODE_PRIVATE)
fout.close()
}
}
for unziping from externalStorage:
private val sourceFile= "$SDPath/unzipFile/data/"
ZipInputStream zis = null;
try {
zis = new ZipInputStream(new BufferedInputStream(new
FileInputStream(sourceFile)));
ZipEntry ze;
int count;
byte[] buffer = new byte[BUFFER_SIZE];
while ((ze = zis.getNextEntry()) != null) {
String fileName = ze.getName();
fileName = fileName.substring(fileName.indexOf("/") + 1);
File file = new File(destinationFolder, fileName);
File dir = ze.isDirectory() ? file : file.getParentFile();
if (!dir.isDirectory() && !dir.mkdirs())
throw new FileNotFoundException("Invalid path: " +
dir.getAbsolutePath());
if (ze.isDirectory()) continue;
FileOutputStream fout = new FileOutputStream(file);
try {
while ((count = zis.read(buffer)) != -1)
fout.write(buffer, 0, count);
} finally {
fout.close();
}
}
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage());
return false;
} finally {
if (zis != null)
try {
zis.close();
} catch (IOException e) {
}
}
return true;
Related
I am trying to copy an image that is stored in my application folder to a predefined folder in my gallery.
I started from an image sharing code..
This is my code :
val extension = when (requireNotNull(pictureResult).format) {
PictureFormat.JPEG -> "jpg"
PictureFormat.DNG -> "dng"
else -> throw RuntimeException("Unknown format.")
}
val timestamp = System.currentTimeMillis()
val namePhoto = "picture_"+timestamp+"."+extension;
val destFile = File(filesDir, namePhoto)
val folder = "/CustomFolder"
CameraUtils.writeToFile(requireNotNull(pictureResult?.data), destFile) { file ->
if (file != null) {
// Code to share - it works
/*
val context = this#PicturePreviewActivity
val intent = Intent(Intent.ACTION_SEND)
intent.type = "image/*"
val uri = FileProvider.getUriForFile(context, context.packageName + ".provider", file)
intent.putExtra(Intent.EXTRA_STREAM, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
*/
*/
// Code to save image to gallery - doesn't work :(
val photoDirectory = File(Environment.DIRECTORY_PICTURES+folder, namePhoto)
val sourcePath = Paths.get(file.toURI())
Log.i("LOG","sourcePath : "+sourcePath.toString()) // /data/user/0/com.app.demo/files/picture_1663772068143.jpg
val targetPath = Paths.get(photoDirectory.toURI())
Log.i("LOG","targetPath : "+targetPath.toString()) // /Pictures/CustomFolder/picture_1663772068143.jpg
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING)
// Error here but I don't know why
} else {
Toast.makeText(this#PicturePreviewActivity, "Error while writing file.", Toast.LENGTH_SHORT).show()
}
}
How do I copy the image to a predefined folder?
Ok, I did it !
Solution :
val folder = "/CustomFolder/" // name of your folder
val timestamp = System.currentTimeMillis()
val namePicture = "picture_"+timestamp+"."+extension;
try {
val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+folder);
if (!path.exists()) {
path.mkdir();
}
val pathImage = File(path,namePicture)
val stream = FileOutputStream(pathImage)
stream.write(imageByteArray).run {
stream.flush()
stream.close()
}
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
public List<string> Upload(HttpPostedFileBase[] files)
{
//string size = fc["size"];
int sizeResize = AppSettings.Company.ChieuRongToiDaCuaHinhUpload ?? 1500;
//if (!string.IsNullOrEmpty(size))
//{
// int.TryParse(size, out sizeResize);
//}
List<string> fileNames = new List<string>();
try
{
// Duyệt qua các file được gởi lên phía client
foreach (HttpPostedFileBase file in files)
{
//Lấy ra file trong list các file gởi lên
//HttpPostedFileBase file = Request.Files[fileName];
//Save file content goes here
if (file != null && file.ContentLength > 0)
{
//Định nghĩa đường dẫn lưu file trên server
//ở đây mình lưu tại đường dẫn yourdomain.com/Uploads/
var originalDirectory = new DirectoryInfo(string.Format("{0}Uploads\\{1}\\", Server.MapPath(#"\"),"files"));
//Lưu trữ hình ảnh theo từng tháng trong năm
string pathString = System.IO.Path.Combine(originalDirectory.ToString(), DateTime.Now.ToString("yyyy-MM"));
bool isExists = System.IO.Directory.Exists(pathString);
if (!isExists) System.IO.Directory.CreateDirectory(pathString);
var path = string.Format("{0}\\{1}", pathString, Common.Tools.StringTools.ConvertToUnSignNoneDotSign(file.FileName));
string newFileName = file.FileName;
//lấy đường dẫn lưu file sau khi kiểm tra tên file trên server có tồn tại hay không
//thư mục files nằm trong CKFinder để quản lý file
var newPath = GetNewPathForDupes(path, ref newFileName);
string serverPath = string.Format("/{0}/{1}/{2}/{3}", "Uploads","files", DateTime.Now.ToString("yyyy-MM"), newFileName);
//nếu là loại file hình thì resize, còn lại khỏi
if(file.ContentType.Contains("image"))
{
//Lưu hình ảnh Resize từ file sử dụng file.InputStream
SaveResizeImage(Image.FromStream(file.InputStream), sizeResize, newPath);
//Tạo hình Thumbnail
StringTools.CreateThumbnail(newFileName, pathString, withThumbnailImage, withThumbnailImage, true);
}
else
{
file.SaveAs(newPath);
}
fileNames.Add(serverPath);
//fileNames.Add("LocalPath: " + newPath + "<br/>ServerPath: " + serverPath);
}
}
}
catch (Exception ex)
{
TempData["e"] = ex.Message;
logger.Error(ex.Message);
}
TempData["file"] = fileNames;
return fileNames;
//return RedirectToAction("Index", "Home");
//return RedirectToAction("Edit", "VL_TinTuyenDung");
}
here I streaming the data from streaming directory and the write it to a output location. I am also trying to implement the process of moving hdfs files from a input folder to the streaming directory. This move happens one time before the streaming context starts. But I want this move to get executed every time for each Batch of Dstream. is that even possible?
val streamed_rdd = ssc.fileStream[LongWritable, Text, TextInputFormat](streaming_directory, (t:Path)=> true , true).map { case (x, y) => (y.toString) }
streamed_rdd.foreachRDD( rdd => {
rdd.map(x =>x.split("\t")).map(x => x(3)).foreachPartition { partitionOfRecords =>
val connection: Connection = connectionFactory.createConnection()
connection.setClientID("Email_send_module_client_id")
println("connection started with active mq")
val session: Session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
println("created session")
val dest = session.createQueue("dwEmailsQueue2")
println("destination queue name = dwEmailsQueue2")
val prod_queue = session.createProducer(dest)
connection.start()
partitionOfRecords.foreach { record =>
val rec_to_send: TextMessage = session.createTextMessage(record)
println("started creating a text message")
prod_queue.send(rec_to_send)
println("sent the record")
}
connection.close()
}
}
)
**val LIST = scala.collection.mutable.MutableList[String]()
val files_to_move = scala.collection.mutable.MutableList[String]()
val cmd = "hdfs dfs -ls -d "+load_directory+"/*"
println(cmd)
val system_time = System.currentTimeMillis
println(system_time)
val output = cmd.!!
output.split("\n").foreach(x => x.split(" ").foreach(x => if (x.startsWith("/user/hdpprod/")) LIST += x))
LIST.foreach(x => if (x.toString.split("/").last.split("_").last.toLong < system_time) files_to_move += x)
println("files to move" +files_to_move)
var mv_cmd :String = "hdfs dfs -mv "
for (file <- files_to_move){
mv_cmd += file+" "
}
mv_cmd += streaming_directory
println(mv_cmd)
val mv_output = mv_cmd.!!
println("moved the data to the folder")**
if (streamed_rdd.count().toString == "0") {
println("no data in the streamed list")
} else {
println("saving the Dstream at "+System.currentTimeMillis())
streamed_rdd.transform(rdd => {rdd.map(x => (check_time_to_send+"\t"+check_time_to_send_utc+"\t"+x))}).saveAsTextFiles("/user/hdpprod/temp/spark_streaming_output_sent/sent")
}
ssc.start()
ssc.awaitTermination()
}
}
I tried doing same stuff in java implementation as below. you can call this method from foreachPartion on rdd
public static void moveFiles(final String moveFilePath,
final JavaRDD rdd) {
for (final Partition partition : rdd.partitions()) {
final UnionPartition unionPartition = (UnionPartition) partition;
final NewHadoopPartition newHadoopPartition = (NewHadoopPartition)
unionPartition.parentPartition();
final String fPath = newHadoopPartition.serializableHadoopSplit()
.value().toString();
final String[] filespaths = fPath.split(":");
if ((filespaths != null) && (filespaths.length > 0)) {
for (final String filepath : filespaths) {
if ((filepath != null) && filepath.contains("/")) {
final File file = new File(filepath);
if (file.exists() && file.isFile()) {
try {
File destFile = new File(moveFilePath + "/" +
file.getName());
if (destFile.exists()) {
destFile = new File(moveFilePath + "/" +
file.getName() + "_");
}
java.nio.file.Files.move((file
.toPath()), destFile.toPath(),
StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
logger.error(
"Exception while moving file",
e);
}
}
}
}
}
}
}
I wanna to know how to add a folder in the apk.don't give me a solution about using the compress software directly. The apk was recompiled by the 'apktool.jar'. I need some code to achieve this problem. Hope one can solve my question as soon as possible.Thank you~
public static int zipMetaInfFolderToApk(String apkName, String folderName) throws IOException {
if(!new File(apkName).exists()){
return ConstantValue.ISQUESTION;
}
String zipName = apkName.substring(0, apkName.lastIndexOf(".")) + "."
+ "zip";
String bak_zipName = apkName.substring(0, apkName.lastIndexOf("."))
+ "_bak." + "zip";
FileUtils.renameFile(apkName, zipName);
ZipFile war = new ZipFile(zipName);
ZipOutputStream append = new ZipOutputStream(new FileOutputStream(
bak_zipName));
Enumeration<? extends ZipEntry> entries = war.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
System.out.println("copy: " + e.getName());
append.putNextEntry(e);
if (!e.isDirectory()) {
copy(war.getInputStream(e), append);
}
append.closeEntry();
}
String name = "";
if(folderName.equals("")){
name = "META-INF/" + folderName;
}else{
name = "META-INF/" + folderName + "/";
}
ZipEntry e = new ZipEntry(name);
try{
append.putNextEntry(e);
}catch(ZipException e1){
append.closeEntry();
war.close();
append.close();
FileUtils.renameFile(zipName,apkName);
FileUtils.deleteFolder(bak_zipName);
e1.printStackTrace();
return ConstantValue.ISQUESTION;
}
append.closeEntry();
war.close();
append.close();
FileUtils.deleteFolder(zipName);
FileUtils.renameFile(bak_zipName, apkName);
return ConstantValue.ISNORMAL;
}
I could get the handle to the google text doc i needed. I am now stuck at how to read the contents.
My code looks like:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(Constants.CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(Constants.CONSUMER_SECRET);
oauthParameters.setOAuthToken(Constants.ACCESS_TOKEN);
oauthParameters.setOAuthTokenSecret(Constants.ACCESS_TOKEN_SECRET);
DocsService client = new DocsService("sakshum-YourAppName-v1");
client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full/");
DocumentQuery dquery = new DocumentQuery(feedUrl);
dquery.setTitleQuery("blood_donor_verification_template_dev");
dquery.setTitleExact(true);
dquery.setMaxResults(10);
DocumentListFeed resultFeed = client.getFeed(dquery, DocumentListFeed.class);
System.out.println("feed size:" + resultFeed.getEntries().size());
String emailBody = "";
for (DocumentListEntry entry : resultFeed.getEntries()) {
System.out.println(entry.getPlainTextContent());
emailBody = entry.getPlainTextContent();
}
Plz note that entry.getPlainTextContent() does not work and throws object not TextContent type exception
finally i solved it as:
for (DocumentListEntry entry : resultFeed.getEntries()) {
String docId = entry.getDocId();
String docType = entry.getType();
URL exportUrl =
new URL("https://docs.google.com/feeds/download/" + docType
+ "s/Export?docID=" + docId + "&exportFormat=html");
MediaContent mc = new MediaContent();
mc.setUri(exportUrl.toString());
MediaSource ms = client.getMedia(mc);
InputStream inStream = null;
try {
inStream = ms.getInputStream();
int c;
while ((c = inStream.read()) != -1) {
emailBody.append((char)c);
}
} finally {
if (inStream != null) {
inStream.close();
}
}
}