我正在使用通过谷歌找到的类来解压缩.zip文件.. .zip包含文件和文件夹。问题是FileOutputStream
throws
FileNotFoundException
..但该文件应该从.zip文件中获取,那么它以前是如何存在的呢?
这是我在AsyncTask
中使用的代码:
@Override
protected Boolean doInBackground(String... params) {
try {
String zipFile = Path + FileName;
FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(Path
+ ze.getName()); // <-- crashes here
while ((length = zin.read(buffer)) > 0) {
fout.write(buffer, 0, length);
publishProgress(length);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch (Exception e) {
mProgressDialog.dismiss();
return false;
}
return true;
}
下载.zip的另一个AsyncTask
:
@Override
protected Boolean doInBackground(String... params) {
try {
URL url = new URL(params[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
File f = new File(Path+FileName);
if(!f.exists())
{
f.mkdirs();
if(!f.createNewFile())
{
f.delete();
f.createNewFile();
}
}
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(Path+FileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
return true;
} catch (Exception e)
{
e.printStackTrace();
e.getCause();
return false;
}
我再次使用(是目录)消息错误获取FileNotFoundExcpetion
!
答案 0 :(得分:14)
FileOutputStream
将抛出FileNotFoundException
。我在这里看不到任何目录创建代码,甚至没有任何代码可以检查Path
是否存在,所以这可能是正在发生的事情。
答案 1 :(得分:8)
我再次使用(是目录)消息错误获取FileNotFoundException。
File f = new File(Path+FileName);
f.mkdirs();
尝试使用
File directory = new File(Path);
directory.mkdirs();
然后
File file = new File(directory, FileName);
而不是你的代码。
答案 2 :(得分:2)
您的第一个版本依赖于dirChecker(
)您尚未发布,但它无法正常工作,或者您的ZIP文件根本不包含目录条目,这是完全合法的,所以你不管怎样,他们不应该依赖他们。
你的第二个版本更好,但你不需要这一切:
File f = new File(Path+FileName);
if(!f.exists())
{
f.mkdirs();
if(!f.createNewFile())
{
f.delete();
f.createNewFile();
}
}
你只需要这个:
File f = new File(Path, FileName);
f.getParentFile().mkdirs();
其余的事情无论如何都会发生。
答案 3 :(得分:0)
来自FileOutputStream构造函数的javadoc
抛出:
FileNotFoundException - 如果文件存在但是是目录 而不是常规文件,不存在但无法创建,或 由于任何其他原因无法打开
通常,如果您没有创建文件的权限或者文件系统的一部分是只读的,则会发生FileNotFoundException(虽然我不确定这在Android中适用的程度)
答案 4 :(得分:0)
此处的问题是由于嵌套在给定zip中的zip文件或目录引起的。如果给定的ZipEntry是一个目录,则需要创建目录并使用FileOutputStream跳过写入。
使用Support Library
检查给定的zipEntry是否是目录并使用zipEnrty.isDirectory()
创建目录,然后继续使用下一个zipEntry而不使用fileOutputStream编写它。
以下是解压缩zip文件的完整代码:
zipEntry.mkDirs()
答案 5 :(得分:-1)
我曾经使用以下代码从app小部件写入内部和外部Android内存:
URL adr = new URL(cleanUrl);
HttpURLConnection urlConnection = (HttpURLConnection) adr.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setReadTimeout(5000);
urlConnection.connect();
File file = new File(path, name);
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.flush();
fileOutput.close();
路径都是:
path = mContext.getFilesDir();
或
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
和
path.mkdirs();
在这两种情况下,我都有一个 FileNotFoundException 和一个零长度的创建文件。
我已经设法为两种类型的Android内存写并具有以下功能:
protected InputStream get(String url) throws ClientProtocolException, IOException {
final HttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
HttpResponse response = client.execute(getRequest);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
try {
return entity.getContent();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
以下用法:
File file = new File(path, name);
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = get(cleanUrl);
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.flush();
fileOutput.close();
答案 6 :(得分:-2)
从Manifest中删除“android:maxSdkVersion =”18“”
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
您在Manifest文件中声明。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>