자바 프로 그래 밍 사상 자바 I/O 시스템 장절 읽 기 노트

25669 단어 자바직장nio레저
오늘 마침 애플 릿 을 쓰 려 면 io 작업 이 필요 합 니 다.갑자기 자바 에 nio 가 사용 하지 않 았 던 것 이 생각 나 서 자 료 를 찾 아 연 구 했 습 니 다.그리고 나중에 찾 아 볼 수 있 도록 필 기 를 했 습 니 다.
-------------------------------------------------------------------------------------------------------------------------------------------
프로 그래 밍 언어의 I/O 라 이브 러 리 에 서 는 스 트림 개념 을 자주 사용 하지만 실제 I/O 장치 에서 데 이 터 를 처리 하 는 디 테 일 을 차단 합 니 다.자바 에 서 는 단일 클래스 를 사용 하여 스 트림 대상 을 만 드 는 것 이 아니 라 여러 대상 을 겹 쳐 서 원 하 는 기능 을 제공 합 니 다(장식 기 모드 를 사용 합 니 다).InputStream 과 OutputStream 은 입력 과 출력 에 쓰 인 다.자바 1.1 에서 Reader 와 Writer 는 어댑터 를 이용 하여 국제 화 를 실현 했다.오래된 I/O 흐름 계승 결 과 는 8 개의 바이트 흐름 만 지원 하기 때문에 16 개의 유 니 코드 문 자 를 잘 처리 할 수 없다.
파일 작업 의 클래스:FileInputReader,FileOutputReader,RandomAccessFile.그 중에서 RandomAccessFile 은 스스로 독립 된 유형 으로 읽 고 쓸 수 있 지만 모두 자신의 내부 에서 이 루어 진 것 으로 입 출력 흐름 의 차원 구 조 를 계승 하지 않 았 다.JDK 1.4 에서 대부분의 기능 은 nio 메모리 맵 파일 로 대체 되 었 습 니 다.
기본 파일 출력:FileWriter 대상 은 파일 에 데 이 터 를 기록 할 수 있 습 니 다.실제로 저 희 는 Buffered Writer 로 포장 하여 버퍼 출력 을 사용 합 니 다.포맷 체 제 를 제공 하기 위해 PrintWriter 로 장식 합 니 다.예 를 들 어 new PrintWriter(new Buffered Writer(file))는 J2SE 5 에서 보조 구조 기 를 사용 하여 new PrintWriter(file)로 간략하게 쓸 수 있다.
파이프 흐름:Piped InputStream,Piped OutputStream,Piped Reader 및 Piped Writer,그들의 가 치 는 다 중 스 레 드 에서 만 나타 날 수 있 습 니 다.파이프 흐름 은 작업 간 의 통신 에 사용 되 기 때 문 입 니 다.
-------------------------------------------------------------------------------------------------------------------------------------------
new I/O:속 도 를 높이 기 위해 새로운 버 전의 JDK 에서 오래된 I/O 도 nio 를 사용 하여 재 구현 하여 성능 을 향상 시 키 는 것 이 목적 입 니 다.속도 의 향상 은 사용 하 는 구조 가 운영 체제 의 실행 I/O 방식 인 채널 과 버퍼 에 더욱 가깝다.
getChannel()방법 을 사용 하면 FileChannel 이 생 성 됩 니 다.채널 은 상당히 기본 적 인 것 입 니 다.읽 기와 쓰기 에 사용 되 는 ByteBuffer 를 전송 할 수 있 고 파일 의 일부 영역 을 잠 그 고 독점 적 인 접근 에 사용 할 수 있 습 니 다(뒤에 언급 되 어 있 습 니 다).

  
  
  
  
  1. import java.nio.*;  
  2. import java.nio.channels.*;  
  3. import java.io.*;  
  4.  
  5. public class GetChannel {  
  6.   private static final int BSIZE = 1024;  
  7.   public static void main(String[] args) throws Exception {  
  8.     // Write a file:  
  9.     FileChannel fc =  
  10.       new FileOutputStream("data.txt").getChannel();  
  11.     fc.write(ByteBuffer.wrap("Some text ".getBytes()));  
  12.     fc.close();  
  13.     // Add to the end of the file:  
  14.     fc = new RandomAccessFile("data.txt""rw").getChannel();  
  15.     fc.position(fc.size()); // Move to the end  
  16.     fc.write(ByteBuffer.wrap("Some more".getBytes()));  
  17.     fc.close();  
  18.     // Read the file:  
  19.     fc = new FileInputStream("data.txt").getChannel();  
  20.     ByteBuffer buff = ByteBuffer.allocate(BSIZE);  
  21.     fc.read(buff);  
  22.     buff.flip();  
  23.     while(buff.hasRemaining())  
  24.       System.out.print((char)buff.get());  
  25.   }  
  26. }  
  27.  

바이트 를 ByteBuffer 에 저장 하 는 방법 은 두 가지 가 있 습 니 다.하 나 는 put 방법 으로 하나 이상 의 바이트 나 기본 데이터 형식 을 직접 채 우 는 것 입 니 다.다른 하 나 는 이미 존재 하 는 바이트 배열 을 warp 방법 으로 ByteBuffer 에 포장 하 는 것 이다.읽 기 전용 접근 에 대해 서 는 정적 인 allocate 방법 으로 ByteBuffer 를 할당 해 야 합 니 다.nio 의 목 표 는 대량의 데 이 터 를 빠르게 이동 하 는 것 입 니 다.따라서 ByteBuffer 의 크기 는 매우 중요 합 니 다.실제 실행 되 는 프로그램 에서 테스트 를 통 해 최 적 치 를 찾 아야 합 니 다.더 높 은 속 도 를 내 려 면 allocateDirect()가 아 닌 allocate()를 사용 하여 운영 체제 와 더욱 높 은 결합 성 을 가 진'직접'버퍼 를 만 드 는 것 이 방법 이지 만 효 과 는 실제 테스트 가 필요 합 니 다.

  
  
  
  
  1. import java.nio.*;  
  2. import java.nio.channels.*;  
  3. import java.io.*;  
  4.  
  5. public class ChannelCopy {  
  6.   private static final int BSIZE = 1024;  
  7.   public static void main(String[] args) throws Exception {  
  8.     if(args.length != 2) {  
  9.       System.out.println("arguments: sourcefile destfile");  
  10.       System.exit(1);  
  11.     }  
  12.     FileChannel in = new FileInputStream(args[0]).getChannel();  
  13.     FileChannel out = new FileOutputStream(args[1]).getChannel();  
  14.     // , 2    
  15.     // in = transferTo(0, in.size(), out);   out = transferFrom(in, 0, in.size());  
  16.     ByteBuffer buffer = ByteBuffer.allocate(BSIZE);  
  17.     while(in.read(buffer) != -1) {  
  18.       buffer.flip(); // Prepare for writing  
  19.       out.write(buffer);  
  20.       buffer.clear();  // Prepare for reading  
  21.     }  
  22.   }  
  23. }  

Buffer Writer 를 char 형 으로 바 꾸 는 것 은 매우 불편 합 니 다.우 리 는 CharBuffer 의 toString()방법 을 이용 하여 String 형 으로 바 꾸 는 것 이 훨씬 편리 합 니 다.

  
  
  
  
  1. import java.nio.*;  
  2. import java.nio.channels.*;  
  3. import java.nio.charset.*;  
  4. import java.io.*;  
  5.  
  6. public class BufferToText {  
  7.   private static final int BSIZE = 1024;  
  8.   public static void main(String[] args) throws Exception {  
  9.     FileChannel fc =  
  10.       new FileOutputStream("data2.txt").getChannel();  
  11.     fc.write(ByteBuffer.wrap("Some text".getBytes()));  
  12.     fc.close();  
  13.     fc = new FileInputStream("data2.txt").getChannel();  
  14.     ByteBuffer buff = ByteBuffer.allocate(BSIZE);  
  15.     fc.read(buff);  
  16.     buff.flip();  
  17.     // Doesn't work:  
  18.     System.out.println(buff.asCharBuffer());  
  19.     // Decode using this system's default Charset:  
  20.     buff.rewind();  
  21.     String encoding = System.getProperty("file.encoding");  
  22.     System.out.println("Decoded using " + encoding + ": " 
  23.       + Charset.forName(encoding).decode(buff));  
  24.     // Or, we could encode with something that will print:  
  25.     fc = new FileOutputStream("data2.txt").getChannel();  
  26.     fc.write(ByteBuffer.wrap(  
  27.       "Some text".getBytes("UTF-16BE")));  
  28.     fc.close();  
  29.     // Now try reading again:  
  30.     fc = new FileInputStream("data2.txt").getChannel();  
  31.     buff.clear();  
  32.     fc.read(buff);  
  33.     buff.flip();  
  34.     System.out.println(buff.asCharBuffer());  
  35.     // Use a CharBuffer to write through:  
  36.     fc = new FileOutputStream("data2.txt").getChannel();  
  37.     buff = ByteBuffer.allocate(24); // More than needed  
  38.     buff.asCharBuffer().put("Some text");  
  39.     fc.write(buff);  
  40.     fc.close();  
  41.     // Read and display:  
  42.     fc = new FileInputStream("data2.txt").getChannel();  
  43.     buff.clear();  
  44.     fc.read(buff);  
  45.     buff.flip();  
  46.     System.out.println(buff.asCharBuffer());  
  47.   }  
  48. }  
  49.  

-------------------------------------------------------------------------------------------------------------------------------------------
메모리 맵 파일:메모리 에 넣 을 수 없 는 파일 을 만 들 고 수정 할 수 있 습 니 다.

  
  
  
  
  1. import java.nio.*;  
  2. import java.nio.channels.*;  
  3. import java.io.*;  
  4. import static net.mindview.util.Print.*;  
  5.  
  6. public class LargeMappedFiles {  
  7.   static int length = 0x8FFFFFF// 128 MB  
  8.   public static void main(String[] args) throws Exception {  
  9.     MappedByteBuffer out =  
  10.       new RandomAccessFile("test.dat""rw").getChannel()  
  11.       .map(FileChannel.MapMode.READ_WRITE, 0, length);  
  12.     for(int i = 0; i < length; i++)  
  13.       out.put((byte)'x');  
  14.     print("Finished writing");  
  15.     for(int i = length/2; i < length/2 + 6; i++)  
  16.       printnb((char)out.get(i));  
  17.   }  
  18. }  
  19.  

파일 잠 금 추가:FileChannel 에 tryLock()과 lock()을 호출 하면 전체 파일 의 FileLock 을 얻 을 수 있 습 니 다.try Lock()을 시작 하 는 것 은 비 차단 식 입 니 다.자 물 쇠 를 가 져 오 려 고 노력 하지만 얻 지 못 하면 직접 놓 는 방법 을 되 돌려 줍 니 다.lock()은 자 물 쇠 를 얻 을 때 까지 스 레 드 를 막 거나 lock()의 스 레 드 가 중단 되 거나 lock()의 채널 을 호출 하여 닫 아야 합 니 다.

  
  
  
  
  1. import java.nio.channels.*;  
  2. import java.util.concurrent.*;  
  3. import java.io.*;  
  4.  
  5. public class FileLocking {  
  6.   public static void main(String[] args) throws Exception {  
  7.     FileOutputStream fos= new FileOutputStream("file.txt");  
  8.     FileLock fl = fos.getChannel().tryLock();  
  9.     if(fl != null) {  
  10.       System.out.println("Locked File");  
  11.       TimeUnit.MILLISECONDS.sleep(100);  
  12.       fl.release();  
  13.       System.out.println("Released Lock");  
  14.     }  
  15.     fos.close();  
  16.   }  
  17. }  
  18.  

맵 파일 의 부분 잠 금 추가:

  
  
  
  
  1. import java.nio.*;  
  2. import java.nio.channels.*;  
  3. import java.io.*;  
  4.  
  5. public class LockingMappedFiles {  
  6.   static final int LENGTH = 0x8FFFFFF// 128 MB  
  7.   static FileChannel fc;  
  8.   public static void main(String[] args) throws Exception {  
  9.     fc =  
  10.       new RandomAccessFile("test.dat""rw").getChannel();  
  11.     MappedByteBuffer out =  
  12.       fc.map(FileChannel.MapMode.READ_WRITE, 0, LENGTH);  
  13.     for(int i = 0; i < LENGTH; i++)  
  14.       out.put((byte)'x');  
  15.     new LockAndModify(out, 00 + LENGTH/3);  
  16.     new LockAndModify(out, LENGTH/2, LENGTH/2 + LENGTH/4);  
  17.   }  
  18.   private static class LockAndModify extends Thread {  
  19.     private ByteBuffer buff;  
  20.     private int start, end;  
  21.     LockAndModify(ByteBuffer mbb, int start, int end) {  
  22.       this.start = start;  
  23.       this.end = end;  
  24.       mbb.limit(end);  
  25.       mbb.position(start);  
  26.       buff = mbb.slice();  
  27.       start();  
  28.     }  
  29.     public void run() {  
  30.       try {  
  31.         // Exclusive lock with no overlap:  
  32.         FileLock fl = fc.lock(start, end, false);  
  33.         System.out.println("Locked: "+ start +" to "+ end);  
  34.         // Perform modification:  
  35.         while(buff.position() < buff.limit() - 1)  
  36.           buff.put((byte)(buff.get() + 1));  
  37.         fl.release();  
  38.         System.out.println("Released: "+start+" to "+ end);  
  39.       } catch(IOException e) {  
  40.         throw new RuntimeException(e);  
  41.       }  
  42.     }  
  43.   }  
  44. }  

좋은 웹페이지 즐겨찾기