RandomAccessFileMode.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.io;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.file.OpenOption;
- import java.nio.file.Path;
- import java.nio.file.StandardOpenOption;
- import java.util.Objects;
- import org.apache.commons.io.function.IOConsumer;
- import org.apache.commons.io.function.IOFunction;
- /**
- * Enumerates access modes for {@link RandomAccessFile} with factory methods.
- *
- * @see RandomAccessFile#RandomAccessFile(File, String)
- * @see RandomAccessFile#RandomAccessFile(String, String)
- * @see Enum
- * @since 2.12.0
- */
- public enum RandomAccessFileMode {
- /**
- * Defines mode {@value #R} to open a {@link RandomAccessFile} for reading only.
- *
- * @see RandomAccessFile#RandomAccessFile(File, String)
- * @see RandomAccessFile#RandomAccessFile(String, String)
- */
- READ_ONLY(RandomAccessFileMode.R, 1), // NOPMD bug https://github.com/pmd/pmd/issues/5263
- /**
- * Defines mode {@value #RW} to open a {@link RandomAccessFile} for reading and writing.
- *
- * @see RandomAccessFile#RandomAccessFile(File, String)
- * @see RandomAccessFile#RandomAccessFile(String, String)
- */
- READ_WRITE(RandomAccessFileMode.RW, 2), // NOPMD bug https://github.com/pmd/pmd/issues/5263
- /**
- * Defines mode {@value #RWS} to open a {@link RandomAccessFile} for reading and writing, as with {@value #RW}, and also require that every update to the
- * file's content or metadata be written synchronously to the underlying storage device.
- *
- * @see RandomAccessFile#RandomAccessFile(File, String)
- * @see RandomAccessFile#RandomAccessFile(String, String)
- * @see StandardOpenOption#SYNC
- */
- READ_WRITE_SYNC_ALL(RandomAccessFileMode.RWS, 4), // NOPMD bug https://github.com/pmd/pmd/issues/5263
- /**
- * Defines mode {@value #RWD} to open a {@link RandomAccessFile} for reading and writing, as with {@value #RW}, and also require that every update to the
- * file's content be written synchronously to the underlying storage device.
- *
- * @see RandomAccessFile#RandomAccessFile(File, String)
- * @see RandomAccessFile#RandomAccessFile(String, String)
- * @see StandardOpenOption#DSYNC
- */
- READ_WRITE_SYNC_CONTENT(RandomAccessFileMode.RWD, 3); // NOPMD bug https://github.com/pmd/pmd/issues/5263
- private static final String R = "r";
- private static final String RW = "rw";
- private static final String RWD = "rwd";
- private static final String RWS = "rws";
- /**
- * Gets the enum value that best fits the given {@link OpenOption}s.
- * <p>
- * The input must be a legal and working combination for NIO.
- * </p>
- *
- * @param openOption options like {@link StandardOpenOption}.
- * @return best fit, by default {@link #READ_ONLY}.
- * @see StandardOpenOption
- * @since 2.18.0
- */
- public static RandomAccessFileMode valueOf(final OpenOption... openOption) {
- RandomAccessFileMode bestFit = READ_ONLY;
- for (final OpenOption option : openOption) {
- if (option instanceof StandardOpenOption) {
- switch ((StandardOpenOption) option) {
- case WRITE:
- if (!bestFit.implies(READ_WRITE)) {
- bestFit = READ_WRITE;
- }
- break;
- case DSYNC:
- if (!bestFit.implies(READ_WRITE_SYNC_CONTENT)) {
- bestFit = READ_WRITE_SYNC_CONTENT;
- }
- break;
- case SYNC:
- if (!bestFit.implies(READ_WRITE_SYNC_ALL)) {
- bestFit = READ_WRITE_SYNC_ALL;
- }
- break;
- default:
- // explicit case skip (spotbugs)
- continue;
- }
- }
- }
- return bestFit;
- }
- /**
- * Gets the {@link RandomAccessFileMode} value for the given mode, one of {@value #R}, {@value #RW}, {@value #RWD}, or {@value #RWS}.
- *
- * @param mode one of {@value #R}, {@value #RW}, {@value #RWD}, or {@value #RWS}.
- * @return A RandomAccessFileMode.
- * @throws IllegalArgumentException Thrown when mode is not one of {@value #R}, {@value #RW}, {@value #RWD}, or {@value #RWS}.
- * @since 2.18.0
- */
- public static RandomAccessFileMode valueOfMode(final String mode) {
- switch (mode) {
- case R:
- return READ_ONLY;
- case RW:
- return READ_WRITE;
- case RWD:
- return READ_WRITE_SYNC_CONTENT;
- case RWS:
- return READ_WRITE_SYNC_ALL;
- }
- throw new IllegalArgumentException(mode);
- }
- private final int level;
- private final String mode;
- RandomAccessFileMode(final String mode, final int level) {
- this.mode = mode;
- this.level = level;
- }
- /**
- * Performs an operation on the {@link RandomAccessFile} specified at the given {@link Path}.
- * <p>
- * This method allocates and releases the {@link RandomAccessFile} given to the consumer.
- * </p>
- *
- * @param file the file specifying the {@link RandomAccessFile} to open.
- * @param consumer the function to apply.
- * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}.
- * @throws IOException Thrown by the given function.
- * @since 2.18.0
- */
- public void accept(final Path file, final IOConsumer<RandomAccessFile> consumer) throws IOException {
- try (RandomAccessFile raf = create(file)) {
- consumer.accept(raf);
- }
- }
- /**
- * Applies the given function for a {@link RandomAccessFile} specified at the given {@link Path}.
- * <p>
- * This method allocates and releases the {@link RandomAccessFile} given to the function.
- * </p>
- *
- * @param <T> the return type of the function.
- * @param file the file specifying the {@link RandomAccessFile} to open.
- * @param function the function to apply.
- * @return the function's result value.
- * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}.
- * @throws IOException Thrown by the given function.
- * @since 2.18.0
- */
- public <T> T apply(final Path file, final IOFunction<RandomAccessFile, T> function) throws IOException {
- try (RandomAccessFile raf = create(file)) {
- return function.apply(raf);
- }
- }
- /**
- * Constructs a random access file to read from, and optionally to write to, the file specified by the {@link File} argument.
- * <p>
- * Prefer {@link #create(Path)} over this.
- * </p>
- *
- * @param file the file object
- * @return a random access file
- * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}.
- */
- public RandomAccessFile create(final File file) throws FileNotFoundException {
- return new IORandomAccessFile(file, mode);
- }
- /**
- * Constructs a random access file to read from, and optionally to write to, the file specified by the {@link File} argument.
- *
- * @param file the file object
- * @return a random access file
- * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}.
- */
- public RandomAccessFile create(final Path file) throws FileNotFoundException {
- return create(Objects.requireNonNull(file.toFile(), "file"));
- }
- /**
- * Constructs a random access file to read from, and optionally to write to, the file specified by the {@link File} argument.
- * <p>
- * Prefer {@link #create(Path)} over this.
- * </p>
- *
- * @param name the file object
- * @return a random access file
- * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}.
- */
- public RandomAccessFile create(final String name) throws FileNotFoundException {
- return new IORandomAccessFile(name, mode);
- }
- /**
- * A level for relative comparison of access mode rights, the larger, the more access.
- * <p>
- * The relative order from lowest to highest access rights is:
- * </p>
- * <ol>
- * <li>{@link #READ_ONLY}</li>
- * <li>{@link #READ_WRITE}</li>
- * <li>{@link #READ_WRITE_SYNC_CONTENT}</li>
- * <li>{@link #READ_WRITE_SYNC_ALL}</li>
- * </ol>
- * <p>
- * This is unrelated to {@link #ordinal()}.
- * </p>
- *
- * @return A level for relative comparison.
- */
- private int getLevel() {
- return level;
- }
- /**
- * Gets the access mode, one of {@value #R}, {@value #RW}, {@value #RWD}, or {@value #RWS}.
- *
- * @return one of {@value #R}, {@value #RW}, {@value #RWD}, or {@value #RWS}.
- * @since 2.18.0
- */
- public String getMode() {
- return mode;
- }
- /**
- * Tests whether this mode implies the given {@code other} mode.
- * <p>
- * For example:
- * </p>
- * <ol>
- * <li>{@link RandomAccessFileMode#READ_WRITE_SYNC_ALL} implies {{@link RandomAccessFileMode#READ_WRITE_SYNC_CONTENT}}.</li>
- * <li>{@link RandomAccessFileMode#READ_WRITE_SYNC_CONTENT} implies {{@link RandomAccessFileMode#READ_WRITE}}.</li>
- * <li>{@link RandomAccessFileMode#READ_WRITE} implies {{@link RandomAccessFileMode#READ_ONLY}}.</li>
- * </ol>
- *
- * @param other the non-null mode to test against.
- * @return whether this mode implies the given {@code other} mode.
- * @since 2.18.0
- */
- public boolean implies(final RandomAccessFileMode other) {
- // Note: The method name "implies" is inspired by java.security.Permission.implies(Permission)
- return getLevel() >= other.getLevel();
- }
- /**
- * Constructs a random access file to read from, and optionally to write to, the file specified by the {@link File} argument.
- *
- * @param name the file object
- * @return a random access file
- * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}.
- * @since 2.18.0
- */
- public IORandomAccessFile io(final String name) throws FileNotFoundException {
- return new IORandomAccessFile(name, mode);
- }
- }