티스토리 뷰

android.net.Uri & java.net.URI

android.net.Urijava.net.URI의 차이가 뭐냐? 스펠링은 똑같고 대/소문자만 틀리다.. ㅠㅜ

두개의 차이는 두개의 android reference를 읽어보면 알수 있다.

 Android.net.Uri
Uri는 변할수 없는 URI reference이다. URI reference는 URI와 fragment(#뒤에 정의된 URI component)는 포함하고 있다. URI reference의 build와 parse는 RFC 2396에 정의되어 있다.

성능적인 관점에서, 이클래스는 validation을 거의 안한다. 그래서 invalid input에 대한 행동이 정의 안되어 있다. 이클래스는 invalid input에 대해 용서를 잘해준다. invalid input이 들어오면 exception을 발생안시키고 쓰레기 값을 return한다. 

Reference를 읽어보면 Uri는 변경할수 없는(immutable) URI  reference란다. 그러고 보니 Uri는 Uri.parse()로 한번 만들면   변경을 할수가 없다. 메소드들도 다 get메소드만 제공한다. 그리고 invalid input이 들어와도 Exception을 발생안시킨다. 

그리고 URI는 변경가능하다(mutable).

 

아래와 같이 테스트를 해보았다. space가 들어가 path로 Uri, URI를 만들어 봤다. reference의 설명데로 Uri는 Exception을 발생시키지 않고 잘 만든다. 그런데 URI는 space를 Illegal character로 인식한다.

 
 Uri uri = Uri.parse("file:///storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg");
 Log.v(TAG, "Uri =  " + uri.toString());
 V/Main    (11878): Uri =  file:///storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg

 URI uri = new URI("file:///storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg"); (실패)
 W/System.err(13739): java.net.URISyntaxException: Illegal character in path at index 44: file:///storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg

 URI uri = new URI("file:///storage/emulated/0/Pictures/Selected%20a%20effected%20photo/IMG_0003.jpg"); (성공) space를 %20으로 변경

그러면 Exception을 발생시키지 않고 만들어진 Uri는 잘못된 놈일까? 아무데도 쓸모없는 놈일까?


         
 Uri uri = Uri.parse("file:///storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg");
 try {
     InputStream ip = getContentResolver().openInputStream(uri);
     Log.v(TAG, "size = " + ip.available());
     ip.close();
 } catch (FileNotFoundException e2) {
     e2.printStackTrace();
 } catch (IOException e) {
     e.printStackTrace();
  }
 V/Main    (14183): size = 57557

아무데도 쓸모없는 놈은 아니다. space가 들어간 경로로 Uri를 만들어서 InputStream을 만들어서 파일사이즈를 출력해 보니.. 정상이다. 내 판단으로는 Uri와 URI중에 어느것이 좋다고 판단하기 힘들것 같다. Uri는 경로에 space가 있어도 인식을 하고, URI는 space가 있으면 인식을 못한다? 정도이다. Uri의 경로에 %20이 있어도 인식을 잘한다. 즉 URLEncode되있든 안되있든 잘 인식한다는 것이다.

 network관련 메소드중에 Uri만 arg로 받는 녀석이 있고, URI만 받아들이는 녀석이 있다. Uri를 만들어서 쭉 Uri로만 쓸거면 문제가 안된다. Uri로 처음 만들어서 URI로 변경하려다 문제가 생기는 것이다.

  그리고 특이점은 Uri는 android.net계열이고, URI는 java.net계열이다. 즉 URI는 java.net 패키지에서 많이 쓰고, Uri는 android.net 패키지에서 많이 쓴다는 것이다.


그리고 여기서 조심해야 할것은 Uri.fromFile()의 결과물은 URLEncode된 즉 space가  %20으로 바뀐 경로라는 것이다. 원래 Uri는 URLEncode를 하지않으나 Uri.fromFile()에서는 URLEncode를 해준다. 결과적으로 URLEncode해주는게 좋을것 같다.

File file = new File("/storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg");
Log.v(TAG, "file = " + file.getAbsolutePath());
V/Main    (16196): file = /storage/emulated/0/Pictures/Selected a effected photo/IMG_0003.jpg
Uri uri = Uri.fromFile(file);
Log.v(TAG, "Uri.fromFile() " + uri.toString());
V/Main    (16421): Uri =  file:///storage/emulated/0/Pictures/Selected%20a%20effected%20photo/IMG_0003.jpg

 

java.net.URL & java.net.URI

URL과 URI의 차이는 뭘까? 먼저 같은점은 URI처럼 URL도 URLEncode된 경로만 인식 한다는 것이다.


URL url;
try {
     url = new URL("file:///storage/emulated/0/Pictures/Selected%20a%20effected%20photo/IMG_0003.jpg");
     URI uri = url.toURI();
     } catch (MalformedURLException e) {
        e.printStackTrace();
     } catch (URISyntaxException e) {
        e.printStackTrace();
     }

크게 보면 URL은 URI에 포함되어 있다. 즉 모든 URL은 URI에 포함이 되지만 URI는 URL이 아닐수도 있다. URI reference를 보면 URI는 상대주소/절대주소 다 가능하다고 한다. 즉 아래처럼 URL는 Location이므로 scheme, host를 다적어서 정확한 위치를 적어야 하지만 URI는 ID(Indentification)이므로 상대주소로 가리킬수 있다.

  • URL : http://example.com/some/page.html
  • URI : /some/page.html

특히 어떤 경우에 URL을 쓰고 어떤경우는 URI를 써야하는지 정의하기가 힘들다. 우리가 일반 적으로 아는것처럼 URL은 Web페이지의 주소, URI는 resource의 위치로 쓰는게 어떨까 한다. 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함