英文:
Seeking on an InputStream in Android - Java
问题
我有一个文件传输应用程序,它通过套接字连接从Android发送大文件(几GB大小)到Windows。我正在使用内容解析器获取存储在手机上的文件的输入流实例,但我希望能够在输入流上前后跳转,以使文件传输在数据报通道上更加高效。有没有办法做到这一点?
int ack, len;
Context context = getApplicationContext();
ContentResolver cr = context.getContentResolver();
InputStream is = cr.openInputStream(fileUri);
while ((len = is.read(bufr, 0, BUFFER_SIZE)) > 0) {
ack = sendDatagramPacket(bufr, 0, len);
}
英文:
I have a file transfer app that sends large files (few GBs in size) from Android to Windows over a socket connection. I am using content resolver to get input stream instance to the file stored in the phone, but I want to be able to seek back and forth on the input stream to make file transfer more efficient over Datagram channel. Is there a way to do that?
int ack, len;
Context context = getApplicationContext();
ContentResolver cr = context.getContentResolver();
InputStream is = cr.openInputStream(fileUri);
while ((len = is.read(bufr, 0, BUFFER_SIZE)) > 0) {
ack = sendDatagramPacket(bufr, 0, len);
}
答案1
得分: 0
这里有一个值得尝试的方法,对我有效。思路是通过获取AssetFileDescriptor将InputStream强制转换为FileInputStream,然后获取一个允许你前后移动的FileChannel实例。
long position = 0, bytesRead = 0, currentRead = 0;
Context context = getApplicationContext();
ContentResolver cr = context.getContentResolver();
InputStream is = cr.openInputStream(fileUri);
AssetFileDescriptor assetFileDescriptor = null;
FileInputStream fis = null;
FileChannel fc = null;
try {
assetFileDescriptor = getContentResolver().openAssetFileDescriptor(fileUri[0], "r");
is = cr.openInputStream(fileUri[0]);
Utility.sendFileInfo(is, out, fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fis = new FileInputStream(assetFileDescriptor.getFileDescriptor());
fc = fis.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(Utility.BUFFER_SIZE);
while (position < filesize) {
try {
fc.position(position);
currentRead = fc.read(buffer);
// 使用填充的缓冲区发送数据
SendDatagramPacket(buffer, 0, currentRead);
bytesRead += currentRead;
position = bytesRead;
buffer = ByteBuffer.allocate(Utility.BUFFER_SIZE);
} catch (IOException e) {
e.printStackTrace();
}
}
英文:
Here's one approach worth trying that worked for me. The idea is to cast InputStream to FileInputStream by getting AssetFileDescriptor, and then getting an instance of FileChannel that lets you seek back and forth.
long position = 0, bytesRead = 0, currentRead = 0;
Context context = getApplicationContext();
ContentResolver cr = context.getContentResolver();
InputStream is = cr.openInputStream(fileUri);
AssetFileDescriptor assetFileDescriptor = null;
FileInputStream fis = null;
FileChannel fc = null;
try {
assetFileDescriptor = getContentResolver().openAssetFileDescriptor(fileUri[0], "r");
is = cr.openInputStream(fileUri[0]);
Utility.sendFileInfo(is, out, fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fis = new FileInputStream(assetFileDescriptor.getFileDescriptor());;
fc = fis.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(Utility.BUFFER_SIZE);
while(position < filesize){
try {
fc.position(position);
currentRead = fc.read(buffer);
//Use the populated buffer to send data out
SendDatagramPacket(buffer, 0, currentRead)
bytesRead += currentRead;
position = bytesRead;
buffer = ByteBuffer.allocate(Utility.BUFFER_SIZE);
} catch (IOException e) {
e.printStackTrace();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论