안드로이드 다운로드 바이너리 파일 문제
인터넷에서 내 앱의 바이너리 파일 (비디오)을 다운로드하는 데 문제가 있습니다. Quicktime에서 직접 다운로드하면 제대로 작동하지만 내 앱을 통해 어떻게 든 엉망이됩니다 (텍스트 편집기에서 정확히 동일하게 보이지만). 예를 들면 다음과 같습니다.
URL u = new URL("http://www.path.to/a.mp4?video");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(root,"Video.mp4"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer);
}
f.close();
이것이 유일한 문제인지는 모르겠지만 거기에 고전적인 Java 결함이 있습니다. read ()가 항상 요청한 것보다 적은 바이트를 반환 할 수 있다는 사실에 의존하지 않습니다 . 따라서 읽기는 1024 바이트 미만일 수 있지만 쓰기는 항상 이전 루프 반복의 바이트를 포함하여 정확히 1024 바이트를 기록합니다.
다음으로 수정 :
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
}
지연 시간이 더 긴 네트워킹이나 Android에서 3G의 더 작은 패킷 크기가 그 효과를 악화시킬까요?
new DefaultHttpClient().execute(new HttpGet("http://www.path.to/a.mp4?video"))
.getEntity().writeTo(
new FileOutputStream(new File(root,"Video.mp4")));
한 가지 문제는 버퍼를 읽는 것입니다. 입력 스트림의 모든 읽기가 1024의 정확한 배수가 아니면 잘못된 데이터를 복사합니다. 사용하다:
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 ) {
f.write(buffer,0, len1);
}
public class download extends Activity {
private static String fileName = "file.3gp";
private static final String MY_URL = "Your download url goes here";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
URL url = new URL(MY_URL);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory()
+ "/download/";
Log.d("Abhan", "PATH: " + PATH);
File file = new File(PATH);
if(!file.exists()) {
file.mkdirs();
}
File outputFile = new File(file, fileName);
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.flush();
fos.close();
is.close();
} catch (IOException e) {
Log.e("Abhan", "Error: " + e);
}
Log.i("Abhan", "Check Your File.");
}
}
이 스레드에 대한 이전 피드백을 기반으로 코드를 수정했습니다. 이클립스와 여러 개의 큰 파일을 사용하여 테스트했습니다. 잘 작동합니다. 이것을 복사하여 환경에 붙여넣고 http 경로와 파일을 다운로드 할 위치를 변경하기 만하면됩니다.
try {
//this is the file you want to download from the remote server
String path ="http://localhost:8080/somefile.zip";
//this is the name of the local file you will create
String targetFileName
boolean eof = false;
URL u = new URL(path);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("c:\\junk\\"+targetFileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
}
f.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
행운을 빕니다 알리레자 아가 모하마디
아파치의 복사 방법 ( Apache Commons IO )을 사용하십시오-Java 사용의 장점!
IOUtils.copy(is, os);
finally 블록에서 스트림을 닫는 것을 잊지 마십시오.
try{
...
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
참고 URL : https://stackoverflow.com/questions/576513/android-download-binary-file-problems
'programing tip' 카테고리의 다른 글
Angular + Material-데이터 소스를 새로 고치는 방법 (매트 테이블) (0) | 2020.10.29 |
---|---|
ASP.NET MVC Ajax.ActionLink with Image (0) | 2020.10.29 |
Tomcat 기본 URL 리디렉션 (0) | 2020.10.29 |
Java에서 모든 날짜 구문 분석 (0) | 2020.10.29 |
로드되지 않는 VSTO 추가 기능의 문제를 해결하는 방법은 무엇입니까? (0) | 2020.10.29 |