FileNotFoundException when using FileOutputStream - java

I need to extract tar file by this code.
But it' this error when I use FileOutputStream(outputFile);
" java.io.FileNotFoundException: D:\TestFile\1.png (Access is denied)"
Input is 1.tar file from Drive D:/testFile
and extract to same folder
I try check path of outputfile by outputFile.getCanonicalFile but it's ok!!
what wrong?
public class DecompressTarFile {
public ArrayList<File> getTarFileExtracted() {
return tarFileExtracted;
}
public ArrayList<File> tarFileExtracted = new ArrayList<File>();
public DecompressTarFile(File inputFile, File outputDir) throws FileNotFoundException, ArchiveException, IOException {
System.out.println("Untaring " + inputFile.getAbsolutePath() + " to dir " + outputDir.getAbsolutePath() + ".");
InputStream inputStream = new FileInputStream(inputFile);
TarArchiveInputStream tarStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", inputStream);
TarArchiveEntry tarEntry = null;
while ((tarEntry = (TarArchiveEntry) tarStream.getNextEntry()) != null) {
File outputFile = new File(outputDir, tarEntry.getName());
System.out.println("Attempting to write output directory " + outputFile.getAbsolutePath());
if (!outputFile.exists()) {
System.out.println("Attempting to create output directory " + outputFile.getAbsolutePath());
if (!outputFile.mkdirs()) {
throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
}
} else {
System.out.println("Create output file " + outputFile.getAbsolutePath());
OutputStream outputFileStream = new FileOutputStream(outputFile);
IOUtils.copy(tarStream, outputFileStream);
outputFileStream.close();
}
tarFileExtracted.add(outputFile);
}
tarStream.close();
}
}
and called by main class
static File tarFileInput = new File("D:/TestFile/haha.tar");
static File tarPathFileOutput = new File("D:/TestFile");
public static void main(String[] args) throws ArchiveException, IOException {
decomp = new DecompressTarFile(tarFileInput, tarPathFileOutput);
//listOutput = decomp.getTarFileExtracted();
}
And this result from this code
run:
Untaring D:\TestFile\haha.tar to dir D:\TestFile.
Attempting to write output directory D:\TestFile\1.png
Create output file D:\TestFile\1.png
Exception in thread "main" java.io.FileNotFoundException: D:\TestFile\1.png (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at com.service..TarFile.DecompressTarFile.<init>(DecompressTarFile.java:53)
at com.service..TarFile.MainForTest.main(MainForTest.java:28)
Java Result: 1

This is the problem:
Attempting to write output directory D:\TestFile\1.png
You've created the target filename as a directory. You need to separate out "the directory I need to exist" and "the file I want to write to". For example:
File outputFile = new File(outputDir, tarEntry.getName());
File outputDirectory = outputFile.getParent();
if (!outputDirectory.exists()) {
// Try to create the directory
}
Oh, and also you've got a loop condition of:
while (tarEntry != null)
... but you're not changing the value of tarEntry in the loop...

Related

Zip file is created with windows path separator

I create a zip file using below code. Zip is created properly, then later in my program I try to get a zip entry from this file. And if I print a zip entry name I get windows path separators(Eg \a\b\c). But I need this like a/b/c. I have not posted reading zip entry code.
public static void zipFolder(File subdirs, String ZipName) throws FileNotFoundException, IOException {
try (FileOutputStream fileWriter = new FileOutputStream(location+File.seperator+ ZipName);
ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
addFolderToZip(subdirs, subdirs, zip);
}
}
private static void addFileToZip(File rootPath, File srcFile, ZipOutputStream zip) throws FileNotFoundException, IOException {
if (srcFile.isDirectory()) {
addFolderToZip(rootPath, srcFile, zip);
} else {
byte[] buf = new byte[1024];
int len;
try (FileInputStream in = new FileInputStream(srcFile)) {
String name = srcFile.getPath();
name = name.replace(rootPath.getPath() + File.separator, "");
zip.putNextEntry(new ZipEntry(name));
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
}
}
}
private static void addFolderToZip(File rootPath, File srcFolder, ZipOutputStream zip) throws FileNotFoundException, IOException {
for (File fileName : srcFolder.listFiles()) {
addFileToZip(rootPath, fileName, zip);
}
}
The root cause of your problem in the following snippet:
String name = srcFile.getPath();
name = name.replace(rootPath.getPath() + File.separator, "");
zip.putNextEntry(new ZipEntry(name));
The File.getPath() method returns the path with the system-dependent default name-separator.
So, according to this
Within a ZIP file, pathnames use the forward slash / as separator, as required by the ZIP spec (4.4.17.1). This requires a conversion from or to the local file.separator on systems like Windows. The API (ZipEntry) does not take care of the transformation, and the need for the programmer to deal with it is not documented.
you should rewrite this snippet in the following way:
String name = srcFile.getPath();
name = name.replace(rootPath.getPath() + File.separator, "");
if (File.separatorChar != '/') {
name = name.replace('\\', '/');
}
zip.putNextEntry(new ZipEntry(name));

Why do I get a java.io.FileNotFoundException error and a java.lang.NullPointerException in this code?

Here is my code snippet:
public class Compress {
List<String> filesinDir= new ArrayList<String>();
public static void main(String[] args){
Compress c= new Compress();
c.gzipFile();
String OUTPUT_DIR= "C:\\Users\\Surya's\\Documents\\tmp.zip";
File dir= new File(" C:\\Users\\Surya's\\Documents\\tmp ");
c.zipDirectory(dir, OUTPUT_DIR);
}
public void gzipFile(){
String OUTPUT_GZIP_FILE= " C:\\Users\\Surya's\\Documents\\file1.gz ";
String SOURCE_FILE= " C:\\Users\\Surya's\\Documents\\file1.txt ";
byte[] b= new byte[1024];
int len;
try{
FileOutputStream fos= new FileOutputStream(OUTPUT_GZIP_FILE);
GZIPOutputStream gz= new GZIPOutputStream(fos);
FileInputStream in= new FileInputStream(SOURCE_FILE);
while((len= in.read(b))!= -1){
gz.write(b, 0, len);
}
fos.close();
in.close();
gz.finish();
gz.close();
}
catch(IOException e){
e.printStackTrace();
}
}
public void zipDirectory(File dir, String OUTPUT_DIR){
try{
ListofFiles(dir);
FileOutputStream of= new FileOutputStream(OUTPUT_DIR);
ZipOutputStream gzdir= new ZipOutputStream(of);
for(String filepath : filesinDir){
ZipEntry ze= new ZipEntry(filepath.substring(dir.getAbsolutePath().length()+1, filepath.length()));
gzdir.putNextEntry(ze);
byte[] b= new byte[1024];
int len;
FileInputStream fi= new FileInputStream(filepath);
while((len=fi.read(b))!=-1){
of.write(b, 0, len);
}
gzdir.closeEntry();
fi.close();
}
gzdir.close();
of.close();
}
catch(IOException e){
e.printStackTrace();
}
}
public void ListofFiles(File dir) throws IOException{
File[] files= dir.listFiles();
for(File file : files){
if(file.isFile()) filesinDir.add(file.getAbsolutePath());
else ListofFiles(file);
}
}
}
I am trying to zip a single file as well as well as a directory with files in it. gzipFile() handles the compression of the single file while zipDirectory() calls a function ListofFiles() for arranging the abstract pathnames in an array. zipDirectory uses ZipEntry to begin writing from the start of the file and positions the start of the
The error message is
java.io.FileNotFoundException: C:\Users\Surya's\Documents\file1.gz (The filename, directory name, or volume label syntax is incorrect)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:110)
at com.assignment.java.Compress.gzipFile(Compress.java:29)
at com.assignment.java.Compress.main(Compress.java:15)
Exception in thread "main" java.lang.NullPointerException
at com.assignment.java.Compress.ListofFiles(Compress.java:73)
at com.assignment.java.Compress.zipDirectory(Compress.java:48)
at com.assignment.java.Compress.main(Compress.java:18)
Why is a FileNotFound exception being shown since the program is supposed to create a file file1.gz in the Documents folder.
You shouldn't put extra spaces to the path.
Try using
String OUTPUT_DIR= "C:\\Users\\Surya's\\Documents\\tmp.zip";
File dir= new File("C:\\Users\\Surya's\\Documents\\tmp");
String OUTPUT_GZIP_FILE= "C:\\Users\\Surya's\\Documents\\file1.gz";
String SOURCE_FILE= "C:\\Users\\Surya's\\Documents\\file1.txt";
instead of
String OUTPUT_DIR= "C:\\Users\\Surya's\\Documents\\tmp.zip";
File dir= new File(" C:\\Users\\Surya's\\Documents\\tmp ");
String OUTPUT_GZIP_FILE= " C:\\Users\\Surya's\\Documents\\file1.gz ";
String SOURCE_FILE= " C:\\Users\\Surya's\\Documents\\file1.txt ";

java writing file error: java.io.FileNotFoundException: Invalid file path

I have a question about writing csv file on the current project in eclipse
public static void Write_Result(String Amount_Time_Dalta) throws IOException{
File file;
FileOutputStream fop = null;
String content = "";
String All_Result[] = Amount_Time_Dalta.split("-");
String path ="/Users/Myname/Documents/workspace/ProjectHelper/"+All_Result[1] + ".csv";
System.out.println(path);
content = All_Result[3]+ "," + All_Result[5] + "\n";
System.out.println(content);
file = new File(path);
fop = new FileOutputStream(file);
file.getParentFile();
if (!file.exists()) {
file.createNewFile();
}
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
}
and I am getting error which is
Exception in thread "main" java.io.FileNotFoundException: Invalid file path
at java.io.FileOutputStream.<init>(FileOutputStream.java:215)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at FileDistributor.Write_Result(FileDistributor.java:59)
at FileDistributor.main(FileDistributor.java:29)
I used
String path ="/Users/Myname/Documents/workspace/ProjectHelper/";
path to read a files. I was working fine.
However, when I am using same path to write result to file ( can be exist or not. I create or overwrite a file.) it returns Invalid file path.... I am not really sure why..
updated
just found interesting thing. when i just use File newTextFile = new File("1000".csv); then it is working. however, when i replace to File newTextFile = new File(filename +".csv"); it doesn't work.
What you have here is a valid path from which a File object can be created:
/Users/Myname/Documents/workspace/ProjectHelper/
But if you look at it a second time, you'll see that it refers to a directory, not a writable file. What's your file name?
What does your System.out.println say is the value of All_Result[1]?
Sample Code:
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
public class Test
{
public static void main(String[] args)
{
String[] array = {"1000.csv", "800.csv", "700.csv"};
File file;
FileOutputStream fop;
// Uncomment these two lines
//String path = "c:\\" + array[0];
//file = new File(path);
// And comment these next two lines, and the code still works
String path = "c:\\";
file = new File (path + array[0]);
// Sanity check
System.out.println(path);
try
{
fop = new FileOutputStream(file);
}
catch(IOException e)
{
System.out.println("IOException opening output stream");
e.printStackTrace();
}
if (!file.exists())
{
try
{
file.createNewFile();
}
catch(IOException e)
{
System.out.println("IOException opening creating new file");
e.printStackTrace();
}
}
}
}
In order to get this code to break, instead of passing array[0] as a file name, just pass in an empty string "" and you can reproduce your error.
I have encountered the same problem and was looking for answer. I tried using string.trim() and put it into the outputstream and it worked. I am guessing there are some trailing characters or bits surrounding the file path

How to download entire folder in java?

I want to download entire folder/directory from server.
The folder contain files. I tried it with zip functionality but for that i need to give path till the files and not the folder path.
like -
BufferedInputStream in = new BufferedInputStream(new FileInputStream("d:\\StoreFiles\\Temp\\profile.txt"));
I want something like ("d:\StoreFiles") which will download all the folders in Storefiles folder and the files inside the folder.
How can i implement this?
How about this? It recursively going in the directory and downloading:
public static void main(String[] args) {
directoryDownloader(new File("/Users/eugene/Desktop"));
}
private static void directoryDownloader(File input){
if(input.isDirectory()){
for(File file : input.listFiles()){
directoryDownloader(file);
}
} else {
downloadFile(input);
}
}
private static void downloadFile(File someFile){
System.out.println("Downloading file : " + someFile.getPath());
}
P.S. Implement the downloadFile how you want.
I would suggest looking at Apache Commons IO FileUtils to copy directories. It's pretty easy to use. Have a look at the javadoc
Some of the useful methods that might come in handy (note that there are several ones available):
copyDirectory(File srcDir, File destDir)
copyDirectory(File srcDir, File destDir, FileFilter filter)
I think this example useful for u
public class CopyDirectoryExample
{
public static void main(String[] args)
{
File srcFolder = new File("c:\\mkyong");
File destFolder = new File("c:\\mkyong-new");
//make sure source exists
if(!srcFolder.exists()){
System.out.println("Directory does not exist.");
//just exit
System.exit(0);
}else{
try{
copyFolder(srcFolder,destFolder);
}catch(IOException e){
e.printStackTrace();
//error, just exit
System.exit(0);
}
}
System.out.println("Done");
}
public static void copyFolder(File src, File dest)
throws IOException{
if(src.isDirectory()){
//if directory not exists, create it
if(!dest.exists()){
dest.mkdir();
System.out.println("Directory copied from "
+ src + " to " + dest);
}
//list all the directory contents
String files[] = src.list();
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
//recursive copy
copyFolder(srcFile,destFile);
}
}else{
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
System.out.println("File copied from " + src + " to " + dest);
}
}
}

Java: Maintaining zipped files Modified Date

A proprietary program that I'm working with zips up and extracts certain files without changing the modified date of the files when unzipping. I'm also creating my own zip and extraction tool based off the source code in our program but when I'm unzipping the files the modified date of all zipped files is showing with the unzip time & date. Here's the code for my extraction:
public static int unzipFiles(File zipFile, File extractDir) throws Exception
{
int totalFileCount = 0;
String zipFilePath = zipFile.getPath();
System.out.println("Zip File Path: " + zipFilePath);
ZipFile zfile = new ZipFile(zipFile);
System.out.println("Size of ZipFile: "+zfile.size());
Enumeration<? extends ZipEntry> entries = zfile.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
System.out.println("ZipEntry File: " + entry.getName());
File file = new File(extractDir, entry.getName());
if (entry.isDirectory())
{
System.out.println("Creating Directory");
file.mkdirs();
}
else
{
file.getParentFile().mkdirs();
InputStream in = zfile.getInputStream(entry);
try
{
copy(in, file);
}
finally
{
in.close();
}
}
totalFileCount++;
}
return totalFileCount;
}
private static void copy(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
System.out.println("InputStream/OutputStram copy");
while (true)
{
int readCount = in.read(buffer);
if (readCount < 0)
{
break;
}
out.write(buffer, 0, readCount);
}
}
I'm sure there is a better way to do this other than doing the inputstream/outputstream copy. I'm sure this is the culprit as doing an extraction with winRAR does not change the date with the files I zipped.
Use ZipEntry.getTime to get the last-modified time and File.setLastModified to set it on the file after you are done copying it.

Categories

Resources