File.createNewFile () буксирующий IOException Никакой такой файл или каталог

Вот другой подход - инкапсуляция; таким образом, Ваш код мог быть столь же простым как:

    Forker p = new Forker();
    foreach (var obj in collection)
    {
        var tmp = obj;
        p.Fork(delegate { DoSomeWork(tmp); });
    }
    p.Join();

, Где Forker класс дан ниже (я скучал на поезде;-p)... снова, это избегает объектов ОС, но оборачивает вещи вполне аккуратно (IMO):

using System;
using System.Threading;

/// <summary>Event arguments representing the completion of a parallel action.</summary>
public class ParallelEventArgs : EventArgs
{
    private readonly object state;
    private readonly Exception exception;
    internal ParallelEventArgs(object state, Exception exception)
    {
        this.state = state;
        this.exception = exception;
    }

    /// <summary>The opaque state object that identifies the action (null otherwise).</summary>
    public object State { get { return state; } }

    /// <summary>The exception thrown by the parallel action, or null if it completed without exception.</summary>
    public Exception Exception { get { return exception; } }
}

/// <summary>Provides a caller-friendly wrapper around parallel actions.</summary>
public sealed class Forker
{
    int running;
    private readonly object joinLock = new object(), eventLock = new object();

    /// <summary>Raised when all operations have completed.</summary>
    public event EventHandler AllComplete
    {
        add { lock (eventLock) { allComplete += value; } }
        remove { lock (eventLock) { allComplete -= value; } }
    }
    private EventHandler allComplete;
    /// <summary>Raised when each operation completes.</summary>
    public event EventHandler<ParallelEventArgs> ItemComplete
    {
        add { lock (eventLock) { itemComplete += value; } }
        remove { lock (eventLock) { itemComplete -= value; } }
    }
    private EventHandler<ParallelEventArgs> itemComplete;

    private void OnItemComplete(object state, Exception exception)
    {
        EventHandler<ParallelEventArgs> itemHandler = itemComplete; // don't need to lock
        if (itemHandler != null) itemHandler(this, new ParallelEventArgs(state, exception));
        if (Interlocked.Decrement(ref running) == 0)
        {
            EventHandler allHandler = allComplete; // don't need to lock
            if (allHandler != null) allHandler(this, EventArgs.Empty);
            lock (joinLock)
            {
                Monitor.PulseAll(joinLock);
            }
        }
    }

    /// <summary>Adds a callback to invoke when each operation completes.</summary>
    /// <returns>Current instance (for fluent API).</returns>
    public Forker OnItemComplete(EventHandler<ParallelEventArgs> handler)
    {
        if (handler == null) throw new ArgumentNullException("handler");
        ItemComplete += handler;
        return this;
    }

    /// <summary>Adds a callback to invoke when all operations are complete.</summary>
    /// <returns>Current instance (for fluent API).</returns>
    public Forker OnAllComplete(EventHandler handler)
    {
        if (handler == null) throw new ArgumentNullException("handler");
        AllComplete += handler;
        return this;
    }

    /// <summary>Waits for all operations to complete.</summary>
    public void Join()
    {
        Join(-1);
    }

    /// <summary>Waits (with timeout) for all operations to complete.</summary>
    /// <returns>Whether all operations had completed before the timeout.</returns>
    public bool Join(int millisecondsTimeout)
    {
        lock (joinLock)
        {
            if (CountRunning() == 0) return true;
            Thread.SpinWait(1); // try our luck...
            return (CountRunning() == 0) ||
                Monitor.Wait(joinLock, millisecondsTimeout);
        }
    }

    /// <summary>Indicates the number of incomplete operations.</summary>
    /// <returns>The number of incomplete operations.</returns>
    public int CountRunning()
    {
        return Interlocked.CompareExchange(ref running, 0, 0);
    }

    /// <summary>Enqueues an operation.</summary>
    /// <param name="action">The operation to perform.</param>
    /// <returns>The current instance (for fluent API).</returns>
    public Forker Fork(ThreadStart action) { return Fork(action, null); }

    /// <summary>Enqueues an operation.</summary>
    /// <param name="action">The operation to perform.</param>
    /// <param name="state">An opaque object, allowing the caller to identify operations.</param>
    /// <returns>The current instance (for fluent API).</returns>
    public Forker Fork(ThreadStart action, object state)
    {
        if (action == null) throw new ArgumentNullException("action");
        Interlocked.Increment(ref running);
        ThreadPool.QueueUserWorkItem(delegate
        {
            Exception exception = null;
            try { action(); }
            catch (Exception ex) { exception = ex;}
            OnItemComplete(state, exception);
        });
        return this;
    }
}
32
задан A Jackson 6 October 2009 в 11:36
поделиться

7 ответов

обычно это что-то, что вы изменили недавно, сначала ваш пример кода: если файл не существует и не создается новый файл - вы пытаетесь что-то закодировать - что это?

Тогда просмотрите список каталогов, чтобы узнать, существует ли он на самом деле, и выполните println / toString () для объекта файла и getMessage () для исключения, а также трассировку стека печати. ​​

Затем снова начните с нуля и С самого начала учитывайте каждый шаг, который вы используете, чтобы добраться сюда. Вероятно, вы застряли где-то там, осмысляя код (потому что он работал) - вы просто прослеживаете каждый шаг в деталях, и вы его найдете.

7
ответ дан 27 November 2019 в 19:42
поделиться

попытайтесь убедиться, что родительский каталог существует с:

file.getParentFile().mkdirs()
106
ответ дан 27 November 2019 в 19:42
поделиться

Согласно [java docs] ( http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#createNewFile () ) createNewFile автоматически создаст для вас новый файл.

Атомарно создает новый пустой файл, названный этим абстрактным путем, тогда и только тогда, когда файл с таким именем еще не существует.

Учитывая, что createNewFile является атомарным и не перезаписывает существующий файл, вы можете переписать свой код как

try {
    if(!file.createNewFile()) {
        System.out.println("File already exists");
    } 
} catch (IOException ex) {
    System.out.println(ex);
}

. Это может упростить обнаружение любых потенциальных проблем с потоками, условий гонки и т.д.

3
ответ дан 27 November 2019 в 19:42
поделиться

Я думаю, что исключение, которое вы получаете, вероятно, является результатом проверки файлов атомарным методом file.createNewFile () . Метод не может проверить, существует ли файл, потому что некоторые из родительских каталогов не существуют или у вас нет разрешений для доступа к ним. Я бы предложил следующее:

if (file.getParentFile() != null && !file.getParentFile().mkDirs()) {
    // handle permission problems here
}
// either no parent directories there or we have created missing directories
if (file.createNewFile() || file.isFile()) {
    // ready to write your content
} else {
    // handle directory here
}

Если принять во внимание параллелизм, все эти проверки бесполезны, потому что в любом случае какой-то другой поток может создавать, удалять или делать что-нибудь еще с вашим файлом. В этом случае вы должны использовать блокировку файлов, чего я бы не предлагал делать;)

3
ответ дан 27 November 2019 в 19:42
поделиться

Вы определенно получаете это исключение «Система не может найти указанный путь»

Просто напечатайте «file.getAbsoluteFile ()», это даст вам знать, какой файл вы хотите создать.

Это исключение возникает, если каталог, в котором вы создаете файл, не существует .

2
ответ дан 27 November 2019 в 19:42
поделиться

Хм. Похоже, что самый простой способ получить то, что я хочу на стороне Java приложения, - использовать Servlet.getServletConfig (). getInitParameter (parameterName) например, getInitParameter ("myApp.connectionString");

Но я не знаю, где это установить. В документации Tomcat рассказывается о различных перестановках context.xml, но я хочу убедиться, что этот параметр влияет только на мой сервлет, а не на другие. Я также не хочу размещать его в моем файле .war, чтобы я мог сохранить этот параметр независимо от приложений (например, если я устанавливаю обновление).


Обновление: Я понял это, ключ / параметры значения, доступные для ServletContext.getInitParameter () , перейдите сюда (или можете перейти сюда) в $ {CATALINA_HOME} /conf/server.xml:

<Server port=... >
    ...
  <Service name="Catalina" ...>
    <Engine name="Catalina" ...>
      ...
      <Host name="localhost" ...>
        <Context path="/myWarFile">
          <Parameter name="foo" value="123" />
          <Parameter name="bar" value="456" />
           ...
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

Это устанавливает два параметра, "

15
ответ дан 27 November 2019 в 19:42
поделиться

Это может быть проблема многопоточности (совместная проверка и создание не атомарны: ! File.exists () &&! File.createNewFile () ) или "файл" уже является каталогом .

Попробуйте ( file.isFile () ):

if (file.exists() && !file.isFile()){
   //handle directory is there
}else if(!file.createNewFile()) {
   //as before
}
0
ответ дан 27 November 2019 в 19:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: