Как определить, что диск заполнен во время операции записи с Java nio?

Я хотел бы написать файл, который приходит из сети, поэтому я не знаю размер файла, который приходит. Иногда диск на файловом сервере может быть заполнен, и я хотел бы вернуть сообщение моему клиенту уведомляя их об этой ошибке. Я не смог найти никакой документации о том, как можно отследить этот тип ошибки ввода-вывода. FileChannel потоковые байты из памяти на диск, так что это может быть не тривиально, чтобы обнаружить это. Сохранение происходит асинхронно? Можно ли обнаружить заполненный диск?

// Create a new file to write to
RandomAccessFile mFile = new RandomAccessFile(this.mFilePath, "rw");
FileChannel mFileChannel = this.mFile.getChannel();

// wrappedBuffer has my file in it
ByteBuffer wrappedBuffer = ByteBuffer.wrap(fileBuffer);
while(wrappedBuffer.hasRemaining()) {
    bytesWritten += this.mFileChannel.write(wrappedBuffer, this.mBytesProcessed);
}

Я понял в File класс, мы можем сделать что-то вроде этого:

// if there is less than 1 mb left on disk
new File(this.mFilePath, "r").getUsableSpace() < 1024; 

Но если есть способ бросить, кроме как если this.mFileChannel.write() не удается, потому что диск заполнен?

1 ответ

Решение

Даже если не рекомендуется анализировать сообщение об ошибке, вы можете сделать что-то вроде этого:

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Pattern;

public class SmallDisk {

    final static String SMALL_DISK_PATH = "/Volumes/smallDisk";

    final static Pattern NO_SPACE_LEFT = Pattern.compile(": No space left on device$");

    public static void main(String[] args) throws NoSpaceException {
        Path p = Paths.get(SMALL_DISK_PATH);
        FileStore fs = null;
        try {
            fs = Files.getFileStore(p);
            System.out.println(fs.getUsableSpace());
            Path newFile = Paths.get(SMALL_DISK_PATH + "/newFile");
            Files.createFile(newFile);

        } catch (FileSystemException e) {
            //We catch the "No space left on device" from the FileSystemException and propagate it
            if(NO_SPACE_LEFT.matcher(e.getMessage()).find()){
                throw new NoSpaceException("Not enough space");
            }
            //Propagate exception or deal with it here
        } catch (IOException e) {
            //Propagate exception or deal with it here
        }

    }

    public static class NoSpaceException extends IOException{

        public NoSpaceException(String message) {
            super(message);
        }
    }
}

Другой способ, но он не гарантирует, что у вас не будет исключения, - это использовать FileStore, чтобы проверить, достаточно ли места перед записью (недостаточно, если вы работаете с общей папкой или многопоточным программным обеспечением).

Другие вопросы по тегам