首页 > 编程知识 正文

java file获取文件大小,java读取zip文件

时间:2023-05-04 15:16:55 阅读:119058 作者:300

原始标题:像操作File一样操作资产资源

昨天,美团发表了2018年中期报告。 上半年营收263亿元,净亏损288亿元,调整后亏损42亿元。 其中,外卖收入160亿,毛利率12.2%; 来店,酒店业务68亿,毛利率89.4%,新业务收入35.7亿。

作者简介

今天已经是星期五了,再过两天我会努力的。

本篇是猴子来的救兵_的帖子,希望分享自己不错的开源库,通过封装简化操作assets目录的api,对大家有帮助。

猴子来的救援队_的博客地址:

https://blog.csdn.net/aa464971

前言

在平时的开发中经常使用Assets。 虽然可以将一些资源合并到APP应用程序中,但是使用它们很麻烦。 例如,要使用Assets中的一个文件,必须:

try{

finalinputstreamstream=get assets ().open ) ' test.jpg );

}catch(ioexceptione ) {

e .打印堆栈跟踪(;

}

得到的是InputStream,如果需要复制到手机的外部存储器中,必须用FileOutputStream输出到文件中。 如果需要获取文件夹下的文件:

try{

finalString[] list=getAssets ().list ) ' test );

}catch(ioexceptione ) {

e .打印堆栈跟踪(;

}

这样获取的只是文件夹下的文件名,将整个文件夹复制到手机目录至少需要三个步骤。

横移;

连接完整路径;

调用open将其输出到文件。

说强迫症很难受,没有Java File的API那么方便。 那只能抓住一个车轮像File一样。

下图是用AssetFile创建的Assets文件管理器

使用场景

首先列举一下我遭遇的场景。 在线过滤器和内置过滤器。 在线过滤器必须首先将配置文件下载到手机目录中。 内置过滤器被放入Assets中。 为了便于管理,将两个滤镜放在一个统一的目录中,AssetFile首先解决了复制文件夹问题。

在试图获取下图中的过滤器1.json时,实际上是这样的资产管理器. open (过滤器/组/过滤器1/过滤器1.json ),文件名和文件数实际上由开发决定

资产文件只是封装它们以方便使用,而不是省略它们的过程

基本实现

让我们先实现基本功能。 Java的称为File,称为AssetFile。 首先临时保存基本信息、路径和文件名

publicclassAssetFile{

私有资产路径;

隐私名称;

}

我们使用File时传递文件路径。 资产文件也一样。 假设在Assets根目录中有一个test.jpg文件

publicclassAssetFile{

私有资产路径;

隐私名称;

公共安全(stringassetpath ) {

this.assetPath=assetPath==null? ' ' :资产路径;

//有则去除/

intindex=asset path.lastindexof (file.separator char );

this.name=asset path.substring (索引1,assetPath.length () );

}

}

newassetfile(test.jpg ) ) )。

文件API

因为基本的信息也被分配了值,所以可以说已经有雏形了。 现在添加常见的API,如exists ()。

调用assetmanager.list(assetpath )时,如果找不到此文件,则会抛出IOException,因此catch到达后此文件将不存在。

publicbooleanexists (辅助管理器) {

try{

资产管理器. list (资产路径;

返回真;

}catch(exceptione ) {

e .打印堆栈跟踪(;

返回假;

}

}

AssetFile file = newAssetFile( "test.jpg")

booleanexists = file.exists(context.getAssets())

加入文件夹支持

文件的API比较简单,要考虑文件夹就会有一些逻辑了

isDirectory()

现在我们加入一个isDirectory (),用来判断这个路径是否是文件夹,可以获取该路径下的子文件数组,来判断这个路径是不是一个文件夹,如果数组长度大于0说明是一个文件夹。

当然这个方法也有不准确的情况,比如你放了一个空文件夹在Assets里,但是为什么要放一个空文件夹在Assets里呢,所以这个方法还是可行的。

这里还有一个处理,assetManager.list()是把子文件的路径都添加到数组里了,所以不能每次都这样取一次子文件数组,可以用一个变量来缓存它,当它有值的时候,就直接用变量的值了。

publicclassAssetFile{

privateBoolean directory;

publicbooleanisDirectory(AssetManager assetManager){

if(directory == null) {

try{

directory = assetManager.list(assetPath).length > 0;

} catch(Exception e) {

e.printStackTrace();

directory = false;

}

}

returndirectory;

}

}

getParent()

还有一个常用的方法就是获取父文件夹,这个比较简单,通过分割路径字符串就可以实现。

比如A文件夹里放了B文件夹,B文件夹放了C文件,那路径其实就是A/B/C.jpg,通过substring从0开始截取到最后的/,截取后的A/B就是父文件夹的路径了。

publicString getParent(){

intindex = assetPath.lastIndexOf(File.separatorChar);

returnassetPath.substring( 0, index);

}

publicAssetFile getParentFile(){

returnnewAssetFile(getParent());

}

listFiles()

既然有文件夹,就肯定会需要用到listFiles(),assetManager.list()提供的只是子文件的文件名称,所以需要把它拼接成完整的路径传给AssetFile。

还可以添加一个AssetFileFilter,return false的就不添加到集合;了。当根目录的时候调用assetManager.list会把系统自带的一些文件列出来,所以这里还实现了一个SystemAssetFileFilter,用来过滤这些文件。

publicList listFiles(AssetManager assetManager){

returnlistFiles(assetManager, newSystemAssetFileFilter());

}

publicList listFiles(AssetManager assetManager, AssetFileFilter filter){

try{

String newAssetPath = TextUtils.isEmpty(assetPath) ? "": assetPath;

//先获取子文件数组

String[] list = assetManager.list(newAssetPath);

List fileList = newArrayList<>();

for( inti = 0; i < list.length; i++) {

AssetFile file = newAssetFile(newAssetPath, list[i]);

if(filter != null) {

//如果有过滤器,返回true的才添加到AssetFile集合

if(filter.accept(file)) {

fileList.add(file);

}

} else{

//否则直接添加

fileList.add(file);

}

}

returnfileList;

} catch(IOException e) {

e.printStackTrace();

}

returnnewArrayList<>();

}

AssetsManager

为了更方便的使用,可以再扩展一个AssetsManager,提供一些辅助性的方法,比如从Assets复制资源到手机目录,复制文件很简单,拿到流之后直接输出到文件,复制文件夹需要递归来达到复制多层文件夹的效果。

/**

* 复制Asset文件夹和里面的文件到手机目录

*

* @paramassetSource

* @paramoutputDir

*/

publicstaticbooleancopyAsset(AssetManager assetManager, AssetFile assetSource, File outputDir){

try{

File outputFile = newFile(outputDir, assetSource.getName());

String assetPath = assetSource.getAssetPath();

finalString[] list = assetManager.list(assetPath);

if(list.length <= 0) {

//文件

copyAssetFile(assetManager, assetPath, outputFile);

} else{

//目录

if(!outputFile.exists()) {

outputFile.mkdirs();

}

for(String child : list) {

copyAsset(assetManager, newAssetFile(assetPath, child), outputFile);

}

}

returntrue;

} catch(IOException e) {

e.printStackTrace();

}

returnfalse;

}

/**

* 复制Asset文件到手机目录

*

* @paramassetPath

* @paramoutputFile

* @return

*/

publicstaticbooleancopyAssetFile(AssetManager assetManager, String assetPath, File outputFile){

try{

InputStream is = assetManager.open(assetPath);

intbyteRead = 0;

FileOutputStream fs = newFileOutputStream(outputFile);

byte[] buffer = newbyte[ 1024];

while((byteRead = is.read(buffer)) != - 1) {

fs.write(buffer, 0, byteRead);

}

fs.close();

is.close();

returntrue;

} catch(Exception e) {

e.printStackTrace();

}

returnfalse;

}

文档

Gradle引入

implementation 'com.dyhdyh.io:asset-file:1.0.2'

AssetFile

//根目录

AssetFile root = newAssetFile();

//根目录下的test.jpg

AssetFile testFile = newAssetFile( "test.jpg");

//test文件夹下的test.jpg - test/test.jpg

AssetFile testFile = newAssetFile( "test/test.jpg");

AssetFile testFile = newAssetFile( "test", "test.jpg");

//获取完整路径

assetFile.getAssetPath();

//获取文件名称或目录名称

assetFile.getName();

//获取父级目录

assetFile.getParentFile();

//转换Uri

assetFile.getUri();

//是否文件夹

assetFile.isDirectory(getAssets());

//是否根目录

assetFile.isRootDir();

//文件是否存在

assetFile.exists(getAssets());

//获取目录下的文件数组

assetFile.listFiles(getAssets());

AssetsManager

//复制Assets里的test.jpg到手机根目录

AssetFile assetFile = newAssetFile( "test.jpg");

File outputFile = newFile(Environment.getExternalStorageDirectory(), assetFile.getName());

AssetsManager.copyAssetFile(getAssets(), assetFile.getAssetPath(), outputFile);

//复制Assets里的test文件夹到手机根目录

AssetsManager.copyAssetFile(getAssets(), "test", Environment.getExternalStorageDirectory());

项目地址:

https://github.com/dengyuhan/AssetFile返回搜狐,查看更多

责任编辑:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。