Java Android:如何读取以字节为单位的文件?
我正在尝试在Android应用程序中获取以字节为单位的文件内容。我已在SD卡中获取文件,现在希望以字节获取所选文件。我在谷歌上搜索过,但没有这样的成功。请帮忙 下面是获取扩展名为的文件的代码。通过这个,我得到文件并显示在微调器中。在选择文件时,我希望获得以字节为单位的文件Java Android:如何读取以字节为单位的文件?,java,android,file,Java,Android,File,我正在尝试在Android应用程序中获取以字节为单位的文件内容。我已在SD卡中获取文件,现在希望以字节获取所选文件。我在谷歌上搜索过,但没有这样的成功。请帮忙 下面是获取扩展名为的文件的代码。通过这个,我得到文件并显示在微调器中。在选择文件时,我希望获得以字节为单位的文件 private List<String> getListOfFiles(String path) { File files = new File(path); FileFilter filter =
private List<String> getListOfFiles(String path) {
File files = new File(path);
FileFilter filter = new FileFilter() {
private final List<String> exts = Arrays.asList("jpeg", "jpg", "png", "bmp", "gif","mp3");
public boolean accept(File pathname) {
String ext;
String path = pathname.getPath();
ext = path.substring(path.lastIndexOf(".") + 1);
return exts.contains(ext);
}
};
final File [] filesFound = files.listFiles(filter);
List<String> list = new ArrayList<String>();
if (filesFound != null && filesFound.length > 0) {
for (File file : filesFound) {
list.add(file.getName());
}
}
return list;
}
私有列表getListOfFiles(字符串路径){
文件=新文件(路径);
FileFilter=newfilefilter(){
私有最终列表exts=Arrays.asList(“jpeg”、“jpg”、“png”、“bmp”、“gif”、“mp3”);
公共布尔接受(文件路径名){
字符串扩展;
String path=pathname.getPath();
ext=路径子字符串(路径lastIndexOf(“.”+1);
返回exts.contains(ext);
}
};
最终文件[]filesFound=files.listFiles(过滤器);
列表=新的ArrayList();
如果(filesFound!=null&&filesFound.length>0){
for(文件:filesFound){
list.add(file.getName());
}
}
退货清单;
}
这里是一个简单的例子:
File file = new File(path);
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
在manifest.xml中添加权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
这里有一个解决方案,可以保证读取整个文件,不需要库,而且效率很高:
byte[] fullyReadFileToBytes(File f) throws IOException {
int size = (int) f.length();
byte bytes[] = new byte[size];
byte tmpBuff[] = new byte[size];
FileInputStream fis= new FileInputStream(f);;
try {
int read = fis.read(bytes, 0, size);
if (read < size) {
int remain = size - read;
while (remain > 0) {
read = fis.read(tmpBuff, 0, remain);
System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
remain -= read;
}
}
} catch (IOException e){
throw e;
} finally {
fis.close();
}
return bytes;
}
byte[]fullyReadFileToBytes(文件f)引发IOException{
int size=(int)f.length();
字节字节[]=新字节[大小];
字节tmpBuff[]=新字节[大小];
FileInputStream fis=新的FileInputStream(f);;
试一试{
int read=fis.read(字节,0,大小);
如果(读取<大小){
int剩余=大小-读取;
而(保持>0){
read=fis.read(tmpBuff,0,剩余);
数组复制(tmpBuff,0,字节,大小-保留,读取);
保持-=读取;
}
}
}捕获(IOE异常){
投掷e;
}最后{
fis.close();
}
返回字节;
}
注意:它假设文件大小小于MAX_INT字节,如果需要,您可以为此添加处理 目前最简单的解决方案是使用Apache common io: 唯一的缺点是在
build.gradle
应用程序中添加此依赖项:
implementation 'commons-io:commons-io:2.5'
+1562方法计数您也可以这样做:
byte[] getBytes (File file)
{
FileInputStream input = null;
if (file.exists()) try
{
input = new FileInputStream (file);
int len = (int) file.length();
byte[] data = new byte[len];
int count, total = 0;
while ((count = input.read (data, total, len - total)) > 0) total += count;
return data;
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
if (input != null) try
{
input.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
return null;
}
由于接受的
BufferedInputStream#read
不能保证读取所有内容,而不是自己跟踪缓冲区大小,因此我使用了以下方法:
byte bytes[] = new byte[(int) file.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
DataInputStream dis = new DataInputStream(bis);
dis.readFully(bytes);
阻塞直到完全读取完成,并且不需要额外的导入。一个简单的InputStream就可以了
byte[] fileToBytes(File file){
byte[] bytes = new byte[0];
try(FileInputStream inputStream = new FileInputStream(file)) {
bytes = new byte[inputStream.available()];
//noinspection ResultOfMethodCallIgnored
inputStream.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
下面是以块形式读取整个文件的工作解决方案,以及使用scanner类读取大型文件的有效解决方案
try {
FileInputStream fiStream = new FileInputStream(inputFile_name);
Scanner sc = null;
try {
sc = new Scanner(fiStream);
while (sc.hasNextLine()) {
String line = sc.nextLine();
byte[] buf = line.getBytes();
}
} finally {
if (fiStream != null) {
fiStream.close();
}
if (sc != null) {
sc.close();
}
}
}catch (Exception e){
Log.e(TAG, "Exception: " + e.toString());
}
如果要从上下文中使用
openFileInput
方法,可以使用以下代码
这将创建一个BufferArrayOutputStream
,并在从文件读取每个字节时将其追加
/**
*
*使用指定的上下文为文件创建InputStream
*并返回从文件中读取的字节。
*
*
*@param context要使用的上下文。
*@param file要从中读取的文件。
*@返回从文件读取的字节数组,如果找不到文件,则返回null。
*/
公共静态字节[]读取(上下文,字符串文件)引发IOException{
字节[]ret=null;
if(上下文!=null){
试一试{
InputStream InputStream=context.openFileInput(文件);
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
int nextByte=inputStream.read();
而(下一字节!=-1){
outputStream.write(下一字节);
nextByte=inputStream.read();
}
ret=outputStream.toByteArray();
}捕获(忽略FileNotFoundException){}
}
返回ret;
}
请注意,buf.read()
可能无法读取您请求的字节数。请参见此处的javadoc:,int,int)不要忘了在清单中。如果您要一次性读取整个文件,则无需将FileInputStream包装在BufferedInputStream中-实际上这样做会使用更多内存并降低速度,因为数据将被不必要地复制。这个答案实际上是错误的,因为第一条注释指出,尽管它的声誉很高,尽管它被接受。不幸的是,这是stackoverflow的黑暗面。@JamesKPolk关于Siavash的回答呢?是吗?谢谢。将“jsonFile”替换为“f”。使用相同的名称调用缓冲区大小和文件大小:“size”,这会让人非常困惑。这样,您的缓冲区大小将与文件大小相同,这意味着没有缓冲区,您的循环将永远不会执行。@FlorianB希望循环永远不会执行。在最佳情况下,第一次调用fis.read(字节,0,大小)时将读取整个文件代码>。。。循环就在那里,以防文件太大,系统无法读取整个文件,在这种情况下,我们进入循环并在对fis.read()的连续调用中读取其余文件。file.read()不能保证在一次调用中可以读取请求它的所有字节,返回值是实际读取的字节数。Dis确实帮了我很多忙为什么BufferedInputStream#read
不能保证读取所有内容?我阅读了文档,没有发现任何关于这个“问题”的信息。更简单、更直接。谢谢
try {
FileInputStream fiStream = new FileInputStream(inputFile_name);
Scanner sc = null;
try {
sc = new Scanner(fiStream);
while (sc.hasNextLine()) {
String line = sc.nextLine();
byte[] buf = line.getBytes();
}
} finally {
if (fiStream != null) {
fiStream.close();
}
if (sc != null) {
sc.close();
}
}
}catch (Exception e){
Log.e(TAG, "Exception: " + e.toString());
}